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 }