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

时间:2021-07-14 16:32:47
 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     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
 7 
 8 
 9 <bean id="myJiSQ" class="com.hanqi.xml.MyJiSQ"></bean>
10 <!-- 把切面类放入容器 -->
11 <bean id="logAspect" class="com.hanqi.xml.LogAspect"></bean>
12 
13 <!-- aop配置 -->
14 <aop:config>
15 <!-- 定义公共的节点表达式 -->
16 <aop:pointcut expression="execution(* com.hanqi.xml.JiSQ.*(..))" id="pc"/>
17     <!-- 定义切面类-->
18     <aop:aspect ref="logAspect" >
19         <!-- 定义通知 -->
20         <aop:before method="beforeLog" pointcut-ref="pc"/>
21         
22         <!-- 后置通知 -->
23         <aop:after method="afterLog" pointcut-ref="pc"/>
24         
25         <!-- 返回通知 -->
26         <aop:after-returning method="afterReturningLog" pointcut-ref="pc" returning="rtn"/>
27         
28         <!-- 异常通知 -->
29         <aop:after-throwing method="afterThrowingLog" pointcut-ref="pc" throwing="thr"/>
30         
31         <!-- 环绕通知 -->
32         <aop:around method="aroundLog" pointcut-ref="pc"/>
33     </aop:aspect>
34 </aop:config>
35 </beans>
 1 package com.hanqi.xml;
 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.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.xml;
 2 
 3 import java.util.Arrays;
 4 import org.aspectj.lang.JoinPoint;
 5 import org.aspectj.lang.ProceedingJoinPoint;
 6 
 7 public class LogAspect
 8 {
 9 
10     
11     //前置通知实现前置日志,在方法执行之前执行
12     public void beforeLog(JoinPoint jp)//传入JoinPoint类的参数,来接收传进来的参数
13     {
14         String methodName=jp.getSignature().getName();//获取方法名
15         
16         System.out.println("这是前置日志通知:方法名="+methodName+"参数="+Arrays.asList(jp.getArgs()));//把获取的参数值列表转成集合的方式进行输出
17     }
18     
19     
20     //后置通知,在方法执行之后执行,不论是否发生异常
21     public void afterLog()
22     {
23         System.out.println("这是后置通知");
24     }
25     
26     
27     //返回通知,在方法返回结果之后执行
28     public void afterReturningLog(JoinPoint jp,Object rtn)//传入接收来的切点信息和返回值的数据
29     {
30         System.out.println("这是返回通知,方法名="+jp.getSignature().getName()+"参数列表="+Arrays.asList(jp.getArgs())+"返回值="+rtn);
31     }
32     
33     
34     //异常通知,方法抛出异常之后执行
35     public void afterThrowingLog(JoinPoint jp,Exception thr)
36     {
37         System.out.println("这是异常通知"+thr.getMessage());
38     }
39     
40     
41     
42     //环绕通知
43         public Object aroundLog(ProceedingJoinPoint pjp)//传入ProceedingJoinPoint类型的参数,接收来自切点的信息
44         {
45             Object rtn=null;
46             String mname=pjp.getSignature().getName();//获取方法名
47             Object[] args=pjp.getArgs();//获取参数值列表
48             System.out.println("这是环绕通知的前置通知"+"方法名="+mname+"参数列表="+Arrays.asList(args));
49             try
50             {
51                 //执行目标方法
52                 rtn=pjp.proceed();
53                 //返回通知
54                 System.out.println("这是环绕通知的返回通知"+"方法名="+mname+"参数列表="+Arrays.asList(args)+"返回值="+rtn);
55                 
56             }
57             catch(Throwable e)
58             {
59                 //异常通知
60                 System.out.println("这是环绕通知的异常通知通知"+"方法名="+mname+"参数列表="+Arrays.asList(args)+"异常信息="+e.getMessage());
61                 
62             }
63             finally
64             {
65                 //后置通知
66                 System.out.println("这是环绕通知的后置通知"+"方法名="+mname+"参数列表="+Arrays.asList(args));
67                 
68             }
69             return rtn;
70         }
71 }
1 package com.hanqi.xml;
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.xml;
 2 
 3 public class MyJiSQ implements JiSQ
 4 {
 5 
 6     @Override
 7     public int jia(int m, int n)
 8     {
 9         //前置日志
10         //System.out.println("jia方法的前置日志:m="+m+",n="+n);
11         int rtn=m+n;
12         //后置日志
13         //System.out.println("jia方法的后置日志:m+n="+rtn);
14         return rtn;
15     }
16 
17     @Override
18     public int chu(int m, int n)
19     {
20         //前置日志
21         //System.out.println("chu方法的前置日志:m="+m+",n="+n);
22         int rtn=m/n;
23         //后置日志
24         //System.out.println("chu方法的后置日志:m/n="+rtn);
25         return rtn;
26     }
27 }