Spring(定义切面类—注解方式定义通知)

时间:2021-04-09 20:29:52
 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:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
 9 <!-- 扫描器 -->
10 <context:component-scan base-package="com.hanqi"></context:component-scan>
11 <!-- 启用AspectJ切面注解 -->    
12 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
13 </beans>
 1 package com.hanqi;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class Test {
 7 
 8     public static void main(String[] args)
 9     {
10         
11         ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
12         //使用接口方式得到实例
13         JiSQ jsp=(JiSQ)ac.getBean("myJiSQ");
14         System.out.println("1+2="+jsp.jia(1,2));
15         System.out.println("20/2="+jsp.chu(20, 2));
16     }
17 }
 1 package com.hanqi;
 2 
 3 import java.util.Arrays;
 4 import org.aspectj.lang.JoinPoint;
 5 import org.aspectj.lang.ProceedingJoinPoint;
 6 import org.aspectj.lang.annotation.After;
 7 import org.aspectj.lang.annotation.AfterReturning;
 8 import org.aspectj.lang.annotation.AfterThrowing;
 9 import org.aspectj.lang.annotation.Around;
10 import org.aspectj.lang.annotation.Aspect;
11 import org.aspectj.lang.annotation.Before;
12 import org.aspectj.lang.annotation.Pointcut;
13 import org.springframework.stereotype.Component;
14 
15 @Aspect//定义切面类的注解
16 @Component//被容器管理的Bean注解
17 
18 public class LogAspect
19 {
20     //@Pointcut注解定义公共切点表达式,指定通知在哪些地方上起到作用
21     @Pointcut("execution(* com.hanqi.JiSQ.*(..))")//第一个*代表任意修饰符任意返回类型,第二个*代表任意方法,..代表任意参数
22     public void pointCut()
23     {
24         
25     }
26     
27     //前置通知实现前置日志,在方法执行之前执行
28     //@Before注解定义通知类型和切点表达式,传入公共的切点表达式
29     @Before("pointCut()")
30     public void beforeLog(JoinPoint jp)//传入JoinPoint类的参数,来接收传进来的参数
31     {
32         String methodName=jp.getSignature().getName();//获取方法名
33         
34         System.out.println("这是前置日志通知:方法名="+methodName+"参数="+Arrays.asList(jp.getArgs()));//把获取的参数值列表转成集合的方式进行输出
35     }
36     
37     
38     //后置通知,在方法执行之后执行,不论是否发生异常
39     @After("pointCut()")
40     public void afterLog()
41     {
42         System.out.println("这是后置通知");
43     }
44     
45     //返回通知,在方法返回结果之后执行
46     @AfterReturning(pointcut="pointCut()",returning="rtn")//pointcut="定义切点",可使用公共的切入点 returning="定义返回值"
47     public void afterReturningLog(JoinPoint jp,Object rtn)//传入接收来的切点信息和返回值的数据
48     {
49         System.out.println("这是返回通知,方法名="+jp.getSignature().getName()+"参数列表="+Arrays.asList(jp.getArgs())+"返回值="+rtn);
50     }
51     
52     //异常通知,方法抛出异常之后执行
53     @AfterThrowing(pointcut="execution(* com.hanqi.JiSQ.*(..))",throwing="thr")
54     public void afterThrowingLog(JoinPoint jp,Exception thr)
55     {
56         System.out.println("这是异常通知"+thr.getMessage());
57     }
58     
59     
60     
61     //环绕通知
62     @Around("execution(* com.hanqi.JiSQ.*(..))")
63     
64         public Object aroundLog(ProceedingJoinPoint pjp)//传入ProceedingJoinPoint类型的参数,接收来自切点的信息
65         {
66             Object rtn=null;
67             String mname=pjp.getSignature().getName();//获取方法名
68             Object[] args=pjp.getArgs();//获取参数值列表
69             //前置通知
70             System.out.println("这是环绕通知的前置通知"+"方法名="+mname+"参数列表="+Arrays.asList(args));
71             try
72             {
73                 //执行目标方法
74                 rtn=pjp.proceed();
75                 //返回通知
76                 System.out.println("这是环绕通知的返回通知"+"方法名="+mname+"参数列表="+Arrays.asList(args)+"返回值="+rtn);
77                 
78             }
79             catch(Throwable e)
80             {
81                 //异常通知
82                 System.out.println("这是环绕通知的异常通知通知"+"方法名="+mname+"参数列表="+Arrays.asList(args)+"异常信息="+e.getMessage());
83                 
84             }
85             finally
86             {
87                 //后置通知
88                 System.out.println("这是环绕通知的后置通知"+"方法名="+mname+"参数列表="+Arrays.asList(args));
89                 
90             }
91             return rtn;
92         }
93 }
1 package com.hanqi;
2 //计算器接口
3 public interface JiSQ 
4 {
5     //加法
6     int jia(int m,int n);
7     //除法
8     int chu(int m,int n);
9 }
 1 package com.hanqi;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 @Component
 6 public class MyJiSQ implements JiSQ
 7 {
 8     @Override
 9     public int jia(int m, int n)
10     {
11         //前置日志
12         //System.out.println("jia方法的前置日志:m="+m+",n="+n);
13         int rtn=m+n;
14         //后置日志
15         //System.out.println("jia方法的后置日志:m+n="+rtn);
16         return rtn;    
17     }
18 
19     @Override
20     public int chu(int m, int n)
21     {
22         //前置日志
23         //System.out.println("chu方法的前置日志:m="+m+",n="+n);
24         int rtn=m/n;
25         //后置日志
26         //System.out.println("chu方法的后置日志:m/n="+rtn);
27         return rtn;
28     }
29 }