Spring AOP 之注解

Spring AOP  将Schema方式转换为@AspectJ方式实现。 
注解方式的确更加简洁,由配置优先转为契约优先,还是需要点过程,至少是理解上和心理上! 21232604_w77L.gif  



先看Spring配置文件: 
Xml代码    收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  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.xsd"  
  8. >  
  9.     <!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->  
  10.     <aop:aspectj-autoproxy proxy-target-class="true" />  
  11.     <bean  
  12.         id="hello"  
  13.         class="org.zlex.aop.SayHello" />  
  14.     <bean class="org.zlex.aop.AspectJAdvice" />  
  15. </beans>  


<aop:aspectj-autoproxy /> 打开自动代理, proxy-target-class 默认"false"使用JDK代理,更改为"ture"使用CGLib动态代理。 
org.zlex.aop.AspectJAdvice 是在上一篇Advice类的AspectJ注解实现。 
逐步解析。。。 
@Aspect 标注AspectJ的实现类: 
Java代码    收藏代码
  1. @Aspect   
  2. public class AspectJAdvice {  
  3. // ...  
  4. }  

先来看BeforeAdvice,实现方法如下: 
Java代码    收藏代码
  1. /** 
  2.  * @param joinPoint 
  3.  */  
  4. @Before("execution(* org.zlex.aop.Hello.sayHelloBefore(..))")  
  5. public void beforeAdvice(JoinPoint joinPoint) {  
  6.     System.out.println("Before: " + joinPoint.getSignature().getName());  
  7. }  

@Before("execution(* org.zlex.aop.Hello.sayHelloBefore(..))") 也可以写成 @Before(value="execution(* org.zlex.aop.Hello.sayHelloBefore(..))") 。 
当执行 org.zlex.aop.Hello.sayHelloBefore(..) 方法时,将触发beforeAdvice方法。 

AfterAdvice和AroundAdvice与之类似,代码如下: 
Java代码    收藏代码
  1. /** 
  2.  * After 
  3.  *  
  4.  * @param joinPoint 
  5.  */  
  6. @After (value = "execution(* org.zlex.aop.Hello.sayHelloAfter(..))")  
  7. public void afterAdvice(JoinPoint joinPoint) {  
  8.     System.out.println("After: " + joinPoint.getSignature().getName());  
  9. }  
  10.   
  11. /** 
  12.  * Around 
  13.  *  
  14.  * @param joinPoint 
  15.  * @return  
  16.  * @throws Throwable 
  17.  */  
  18. @Around(value = "execution(* org.zlex.aop.Hello.sayHelloAround(..))")  
  19. public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {  
  20.     System.out.println("Around: " + joinPoint.getSignature().getName());  
  21.     System.out.println("Before");  
  22.     Object obj = joinPoint.proceed();  
  23.     System.out.println("End");  
  24.     return obj;  
  25. }  

只是这里的AroundAdvice在实现方法时,需要 ProceedingJoinPoint 作为参数,用于执行环绕方法,并将执行结果返回。 

AfterReturningAdvice可以获取目标方法的返回值,代码如下: 
Java代码    收藏代码
  1. /** 
  2.  * AfterReturning 
  3.  *  
  4.  * @param joinPoint 
  5.  */  
  6. @AfterReturning(value = "execution(* org.zlex.aop.Hello.sayHelloAfterReturning(..))", returning = "retVal")  
  7. public void afterReturningAdvice(JoinPoint joinPoint, String retVal) {  
  8.     System.out.println("AfterReturning: "  
  9.             + joinPoint.getSignature().getName());  
  10.     System.out.println("Return Value: " + retVal);  
  11. }  

@AfterReturning(value = "execution(* org.zlex.aop.Hello.sayHelloAfterReturning(..))", returning = "retVal") 中,有一个注解参数 returning 用于标识返回值参数,与方法中的参数名称保持一致即可。 

AfterThrowingAdvice与AfterReturningAdvice类似,可以获得目标对象抛出的异常,代码如下: 
Java代码    收藏代码
  1. /** 
  2.  * AfterThrowing 
  3.  *  
  4.  * @param joinPoint 
  5.  */  
  6. @AfterThrowing(value = "execution(* org.zlex.aop.Hello.sayHelloAfterThrowing(..))", throwing = "e")  
  7. public void afterThrowingAdvice(JoinPoint joinPoint, Exception e) {  
  8.     System.out.println("AfterThrowing: "  
  9.             + joinPoint.getSignature().getName());  
  10.     System.out.println("Exception Message: " + e.getMessage());  
  11. }  


这里需要着重说明的是Introduction的注解实现方式,代码如下: 
Java代码    收藏代码
  1. @DeclareParents(value = "org.zlex.aop.SayHello", defaultImpl = org.zlex.aop.IntroductionOk.class)  
  2. public Ok ok;  

这里的Ok接口,用来扩展原有SayHello。 这个成员变量(ok)必须标示为public,即public Ok ok; 。 
@DeclareParents 参数中, defaultImpl 指向 Ok 接口的实现类, value 标识目标类。比起Schema的繁杂配置,可谓是一步到位!

转载于:https://my.oschina.net/minglli/blog/97581

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值