首页 > 代码库 > Spring4学习笔记-AOP

Spring4学习笔记-AOP

1.加入jar包

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

commons-logging-1.1.3.jar

spring-aop-4.1.0.RELEASE.jar

spring-aspects-4.1.0.RELEASE.jar

spring-beans-4.1.0.RELEASE.jar

spring-context-4.1.0.RELEASE.jar

spring-core-4.1.0.RELEASE.jar

spring-expression-4.1.0.RELEASE.jar

2.在配置文件中加入AOP的命名空间

3.基于注解的方式

 

①在配置文件中加入如下配置

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

②把横切关注点的代码抽象到切面的类中

    切面首先是一个IOC中的bean,即加入@Component注解

    切面还需要加入@Aspect注解

③在类中声明各种通知

    @Before 前置通知,在方法执行之前执行

    @After 后置通知,在方法执行之后执行

    @AfterRunning 返回通知,在方法返回结果之后执行

    @AfterThrowing 异常通知,在方法抛出异常之后执行

    @Around 环绕通知,围绕着方法执行

③在方法中声明一个类型为JoinPoint的参数就可以访问链接细节

 

ArithmeticCalculator接口

package com.spring.aop.impl; public interface ArithmeticCalculator {    public int add(int i, int j);     public int sub(int i, int j);     public int mul(int i, int j);     public int div(int i, int j);}

  接口实现类 ArithmeticCalculatorImpl.java

package com.spring.aop.impl; import org.springframework.stereotype.Component; @Componentpublic class ArithmeticCalculatorImpl implements ArithmeticCalculator{     @Override    public int add(int i, int j) {        int result = i + j;        return result;    }     @Override    public int sub(int i, int j) {        int result = i - j;        return result;    }     @Override    public int mul(int i, int j) {        int result = i * j;        return result;    }     @Override    public int div(int i, int j) {        int result = i / j;        return result;    } }

  切面类 LoggingAspect.java

package com.spring.aop.impl; import java.util.ArrayList;import java.util.Arrays;import java.util.List; import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component; //把这个类声明为一个切面:需要把该类放入到IOC容器中。再声明为一个切面.@Aspect@Componentpublic class LoggingAspect {     /**    *前置通知,在目标方法开始之前执行。    *@Before("execution(public int com.spring.aop.impl.ArithmeticCalculator.add(int, int))")这样写可以指定特定的方法。     * @param joinpoint     */    @Before("execution(public int com.spring.aop.impl.ArithmeticCalculator.*(int, int))")    public void beforeMethod(JoinPoint joinpoint) {        String methodName = joinpoint.getSignature().getName();        List<Object>args = Arrays.asList(joinpoint.getArgs());        System.out.println("前置通知:The method "+ methodName +" begins with " + args);    }     /**    *后置通知,在目标方法执行之后开始执行,无论目标方法是否抛出异常。    *在后置通知中不能访问目标方法执行的结果。     * @param joinpoint     */    @After("execution(public int com.spring.aop.impl.ArithmeticCalculator.*(int, int))")    public void afterMethod(JoinPoint joinpoint) {        String methodName = joinpoint.getSignature().getName();        //List<Object>args = Arrays.asList(joinpoint.getArgs());  后置通知方法中可以获取到参数        System.out.println("后置通知:The method "+ methodName +" ends ");    }         /**    *返回通知,在方法正常结束之后执行。    *可以访问到方法的返回值。     * @param joinpoint     * @param result 目标方法的返回值     */    @AfterReturning(value="http://www.mamicode.com/execution(public int com.spring.aop.impl.ArithmeticCalculator.*(..))", returning="result")    public void afterReturnning(JoinPoint joinpoint, Object result) {        String methodName = joinpoint.getSignature().getName();        System.out.println("返回通知:The method "+ methodName +" ends with " + result);    }         /**    *异常通知。目标方法出现异常的时候执行,可以访问到异常对象,可以指定在出现特定异常时才执行。    *假如把参数写成NullPointerException则只在出现空指针异常的时候执行。     * @param joinpoint     * @param e     */    @AfterThrowing(value="http://www.mamicode.com/execution(public int com.spring.aop.impl.ArithmeticCalculator.*(..))", throwing="e")    public void afterThrowing(JoinPoint joinpoint, Exception e) {        String methodName = joinpoint.getSignature().getName();        System.out.println("返回通知:The method "+ methodName +" occurs exception " + e);    }         /**     * 环绕通知类似于动态代理的全过程,ProceedingJoinPoint类型的参数可以决定是否执行目标方法。     * @param point 环绕通知需要携带ProceedingJoinPoint类型的参数。     * @return 目标方法的返回值。必须有返回值。     */     /*不常用    @Around("execution(public int com.spring.aop.impl.ArithmeticCalculator.*(..))")    public Object aroundMethod(ProceedingJoinPoint point) {        Object result = null;        String methodName = point.getSignature().getName();        try {            //前置通知            System.out.println("The method "+ methodName +" begins with " + Arrays.asList(point.getArgs()));            //执行目标方法            result = point.proceed();            //翻译通知            System.out.println("The method "+ methodName +" ends with " + result);        } catch (Throwable e) {            //异常通知            System.out.println("The method "+ methodName +" occurs exception " + e);            throw new RuntimeException(e);        }        //后置通知        System.out.println("The method "+ methodName +" ends");        return result;    }    */}

  applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">    <!-- 配置自动扫描包 -->    <context:component-scan base-package="com.spring.aop.impl"></context:component-scan>    <!-- 使AspectJ注解起作用:自动为匹配的类生产代理对象 -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>

  Main.java

package com.spring.aop.impl; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {public static void main(String[] args) {    //创建spring IOC容器    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");    //从IOC容器中获取bean实例    ArithmeticCalculator arithmeticCalculator = applicationContext.getBean(ArithmeticCalculator.class);    int result = arithmeticCalculator.add(4, 6);    System.out.println(result);    result = arithmeticCalculator.sub(4, 6);    System.out.println(result);    System.out.println(result);    result = arithmeticCalculator.mul(4, 6);    System.out.println(result);    System.out.println(result);    result = arithmeticCalculator.div(4, 0);    System.out.println(result);}}

  

源码

http://yunpan.cn/cgsy2s5Qf8KAY  提取码 e202

Spring4学习笔记-AOP