AOP的五种通知类型 业务类 UserService 1 2 3 4 5 6 public class UserService { public String createUser () { System.out.println(this + ":正在调用UserService.createUser()" ); return "success" ; } }
切面类 SampleAspect 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class SampleAspect { public void doBefore (JoinPoint jp) { String clzName = jp.getTarget().getClass().getName(); String method = jp.getSignature().getName(); Object args = jp.getArgs(); System.out.println("【前置通知】" + clzName + "." + method ); } public void doAfter (JoinPoint jp) { String clzName = jp.getTarget().getClass().getName(); String method = jp.getSignature().getName(); System.out.println("【后置通知】" + clzName + "." + method ); } public void doAfterReturning (JoinPoint jp , Object ret) { System.out.println("【返回后通知】" + ret); } public void doAfterThrowing (JoinPoint jp , Throwable t) { System.out.println("【异常通知】" + t.getMessage()); } public Object doAround (ProceedingJoinPoint pjp) throws Throwable { String clzName = pjp.getTarget().getClass().getName(); String method = pjp.getSignature().getName(); Object args = pjp.getArgs(); System.out.println("【前置通知】" + clzName + "." + method ); Object ret = null ; try { ret = pjp.proceed(); System.out.println("【返回后通知】" + ret); } catch (Throwable t) { System.out.println("【异常通知】" + t.getMessage()); throw t; }finally { System.out.println("【后置通知】" + clzName + "." + method + "()" ); } return ret; } }
配置文件 applicationContext.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <bean name ="sampleAspect" class ="SampleAspect" > </bean > <bean name ="userService" class ="UserService" > </bean > <aop:config > <aop:aspect ref ="sampleAspect" > <aop:pointcut id ="samplePC" expression ="execution(* *Service.create*(..))" /> <aop:before pointcut-ref ="samplePC" method ="doBefore" /> <aop:after pointcut-ref ="samplePC" method ="doAfter" /> <aop:after-returning method ="doAfterReturning" pointcut-ref ="samplePC" returning ="ret" /> <aop:after-throwing method ="doAfterThrowing" pointcut-ref ="samplePC" throwing ="t" /> <aop:around method ="doAround" pointcut-ref ="samplePC" /> </aop:aspect > </aop:config >
<aop:config> ... </aop:config>
:通知Spring这是AOP的配置内容<aop:aspect ref="xxx"> ... </aop:aspect>
:通知Spring切面类是哪个Bean<aop:pointcut ... />
:定义切点,规定切面适用的范围1、前置通知 Before 1 2 【前置通知】UserService . createUser UserService@dd8ba08:正在调用UserService . createUser()
2、返回通知 After returning 1 2 UserService@dd8ba08:正在调用UserService . createUser() 【返回后通知】success
3、异常通知 After throwing 异常通知和返回通知是互斥的 在UserService.createUser()方法中添加:
1 2 3 if (1 == 1 ) { throw new RuntimeException("内部错误" ); }
1 2 3 4 UserService@dd8ba08:正在调用UserService . createUser() 【异常通知】内部错误 Exception in thread "main" java.lang.RuntimeException: 内部错误 at UserService . createUser(UserService.java :16)
4、后置通知 After 在返回后通知/异常通知前 1 2 UserService@dd8ba08:正在调用UserService . createUser() 【后置通知】UserService . createUser
5、环绕通知 Around(常用) 可以一次性完成以上四种通知的功能 1 2 3 4 【前置通知】UserService . createUser UserService@384 ad17b:正在调用UserService . createUser() 【返回后通知】success 【后置通知】UserService . createUser()
或
1 2 3 4 5 6 【前置通知】UserService . createUser UserService@384 ad17b:正在调用UserService . createUser() 【异常通知】内部错误 【后置通知】UserService . createUser() Exception in thread "main" java.lang.RuntimeException: 内部错误 at UserService . createUser(UserService.java :16)