注解的方式实现动态代理基于SpringAOP

1.配置spring容器

导入jar包  

    com.springsource.net.sf.cglib-2.2.0.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.2.2.RELEASE.jar
    spring-beans-4.2.2.RELEASE.jar
    spring-context-4.2.2.RELEASE.jar
    spring-core-4.2.2.RELEASE.jar
    spring-expression-4.2.2.RELEASE.jar

配置xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:p="http://www.springframework.org/schema/p"
 5     xmlns:aop="http://www.springframework.org/schema/aop"
 6     xmlns:context="http://www.springframework.org/schema/context"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/context
10         http://www.springframework.org/schema/context/spring-context.xsd
11         http://www.springframework.org/schema/aop
12         http://www.springframework.org/schema/aop/spring-aop.xsd">
13     
14     <!-- 包扫描 -->
15     <context:component-scan base-package="com.eduask.liusheng.aop.after"/>
16     
17     <!-- 开启切面 -->
18     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
19 </beans>
applicationContext-aop-annotation.xml

2.ArithmeticCaluda.java

 1 public interface ArithmeticCaluda {
 2 
 3     /**
 4      * 加
 5      * @param a
 6      * @param b
 7      * @return 8      */
 9     double add(double a, double b);
10 
11     /**
12      * 减
13      * @param a
14      * @param b
15      * @return16      */
17     double sub(double a, double b);
18 
19     /**
20      * 乘
21      * @param a
22      * @param b
23      * @return24      */
25     double mul(double a, double b);
26 
27     /**
28      * 除
29      * @param a
30      * @param b
31      * @return32      */
33     double div(double a, double b);
34 
35 }
ArithmeticCaluda.java

3.ArithmeticCaludaImp.java

import org.springframework.stereotype.Component;

@Component
public class ArithmeticCaludaImp implements ArithmeticCaluda {
    /**
     * 加
     * @param a
     * @param b
     * @return*/
    public double add(double a,double b){
        double result=a+b;
        return result;
    }
    /**
     * 减
     * @param a
     * @param b
     * @return*/
    public double sub(double a,double b){
        double result=a-b;
        return result;
    }
    /**
     * 乘
     * @param a
     * @param b
     * @return*/
    public double mul(double a,double b){
        double result=a*b;
        return result;
    }
    /**
     * 除
     * @param a
     * @param b
     * @return*/
    public double div(double a,double b){
        double result=a/b;
//        int i=10/0;
        return result;
    }
}
ArithmeticCaludaImp.java

4.Log.java

 1 import java.util.Arrays;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.annotation.After;
 5 import org.aspectj.lang.annotation.AfterReturning;
 6 import org.aspectj.lang.annotation.AfterThrowing;
 7 import org.aspectj.lang.annotation.Aspect;
 8 import org.aspectj.lang.annotation.Before;
 9 import org.springframework.core.annotation.Order;
10 import org.springframework.stereotype.Component;
11 
12 @Component 
13 @Aspect
14 @Order(0)
15 public class Log {
16     
17     @Before("execution(* com.eduask.liusheng.aop.after.*.*(..))")
18     public void before(JoinPoint jp){
19         System.out.println("the method "+jp.getSignature().getName()+"() begin with "+Arrays.asList(jp.getArgs()));
20     }
21     
22     @After("execution(* com.eduask.liusheng.aop.after.*.*(..))")
23     public void after(JoinPoint jp){
24         System.out.println("the method after ");
25     }
26     
27     @AfterReturning(value="execution(* com.eduask.liusheng.aop.after.*.*(..))",returning="result")
28     public void afterReturning(JoinPoint jp,Object result){
29         System.out.println("the method "+jp.getSignature().getName()+"() end with ["+result+"]");
30     }
31     
32     @AfterThrowing(value="execution(* com.eduask.liusheng.aop.after.*.*(..))",throwing="e")
33     public void afterThrowing(Exception e){
34         System.out.println("afterThrowing"+e.getMessage());
35     }
36 }
Log.java

5.CopyOfLog.java

 1 import java.util.Arrays;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.annotation.After;
 5 import org.aspectj.lang.annotation.AfterReturning;
 6 import org.aspectj.lang.annotation.AfterThrowing;
 7 import org.aspectj.lang.annotation.Aspect;
 8 import org.aspectj.lang.annotation.Before;
 9 import org.aspectj.lang.annotation.Pointcut;
10 import org.springframework.core.annotation.Order;
11 import org.springframework.stereotype.Component;
12 
13 @Component 
14 @Aspect
15 @Order(1)
16 public class CopyOfLog {
17     @Pointcut("execution(* com.eduask.liusheng.aop.after.*.*(..))")
18     public void log(){}
19     
20     @Before("log()")
21     public void before(JoinPoint jp){
22         System.out.println("CopyOfLog the method "+jp.getSignature().getName()+"() begin with "+Arrays.asList(jp.getArgs()));
23     }
24     
25     @After("log()")
26     public void after(JoinPoint jp){
27         System.out.println("CopyOfLog the method "+jp.getSignature().getName()+"() end ");
28     }
29     
30     @AfterReturning(value="log()",returning="re")
31     public void afterReturning(JoinPoint jp,Object re){
32         System.out.println("CopyOfLog the method "+jp.getSignature().getName()+"() end with ["+re+"]");
33     }
34     
35     @AfterThrowing(value="execution(* com.eduask.liusheng.aop.after.*.*(..))",throwing="e")
36     public void afterThrowing(Exception e){
37         System.out.println("afterThrowing"+e.getMessage());
38     }
39 }
CopyOfLog.java

6.Test.java

 1 import org.springframework.context.ApplicationContext;
 2 import org.springframework.context.support.ClassPathXmlApplicationContext;
 3 
 4 import com.eduask.liusheng.aop.after.ArithmeticCaluda;
 5 /**
 6  * aop之注解实现动态代理,使用Aspect之分步控制连接点
 7  * @author Administrator
 8  *
 9  */
10 public class Test {
11     public static void main(String[] args) {
12         ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext-aop-annotation.xml");
13         ArithmeticCaluda arithmeticCaluda=(ArithmeticCaluda) app.getBean("arithmeticCaludaImp");
14         arithmeticCaluda.div(10, 2);
15     }
16 }
Test,java

注解说明:

@Component :spring组件,spring初始化的时候,spring会把所有添加@Component注解的类作为使用自动扫描注入配置路径下的备选对象,同时在初始化spring@Autowired

@Aspect :声明一个切面
@Order(1) :当有多个切面时,配置优先级,数值越小优先级越高,

@Pointcut("execution(* com.eduask.liusheng.aop.after.*.*(..))") : @Pointcut声明连接点,execution中第一个*表示所有返回类型,第二个*表示所有类,第三个*表示所有方法,(..)表示所有参数类型

@Before("log()") :连接点方法之前执行该方法

@After("log()")  :连接点方法之后执行该方法,方法return之前

@AfterReturning(value="log()",returning="re")  :连接点方法之后执行该方法,方法return之后,re用来接收返回值

@AfterThrowing(value="execution(* com.eduask.liusheng.aop.after.*.*(..))",throwing="e") :连接点方法出现异常时执行

测试结果:

正常运行时

the method div() begin with [10.0, 2.0]
CopyOfLog the method div() begin with [10.0, 2.0]
CopyOfLog the method div() end
CopyOfLog the method div() end with [5.0]
the method after
the method div() end with [5.0]

异常运行时

the method div() begin with [10.0, 2.0]
CopyOfLog the method div() begin with [10.0, 2.0]
CopyOfLog the method div() end
afterThrowing/ by zero
the method after
afterThrowing/ by zero

7.@Around环绕通知,功能整合一步到位

AroundLog.java

 1 import java.util.Arrays;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.Around;
 5 import org.aspectj.lang.annotation.Aspect;
 6 import org.springframework.stereotype.Component;
 7 
 8 @Component 
 9 @Aspect
10 public class AroundLog {
11     
12     @Around("execution(* com.eduask.liusheng.aop.around.*.*(..))")
13     public Object logArround(ProceedingJoinPoint jp) throws Throwable{
14         Object result=null;
15         System.out.println("Arround the method "+jp.getSignature().getName()+"() begin with "+Arrays.asList(jp.getArgs()));
16         try {
17             result=jp.proceed();
18             System.out.println("Arround the method "+jp.getSignature().getName()+"() end ");
19         } catch (Throwable e) {
20             System.out.println("Arround the method "+e.getMessage());
21             throw e;
22         }
23         System.out.println("Arround the method "+jp.getSignature().getName()+"() end with ["+result+"]");
24         return result;
25     }    
26 }
AroundLog.java
原文地址:https://www.cnblogs.com/qq634571685/p/7168845.html