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 }