`

征服Spring AOP—— @AspectJ

阅读更多
接N年前写的一篇Spring AOP相关的内容征服Spring AOP—— Schema,沿用原有例子,将Schema方式转换为@AspectJ方式实现。
注解方式的确更加简洁,由配置优先转为契约优先,还是需要点过程,至少是理解上和心理上!



相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ



先看Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
>
	<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
	<aop:aspectj-autoproxy proxy-target-class="true" />
	<bean
		id="hello"
		class="org.zlex.aop.SayHello" />
	<bean class="org.zlex.aop.AspectJAdvice" />
</beans>


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

先来看BeforeAdvice,实现方法如下:
	/**
	 * @param joinPoint
	 */
	@Before("execution(* org.zlex.aop.Hello.sayHelloBefore(..))")
	public void beforeAdvice(JoinPoint joinPoint) {
		System.out.println("Before: " + joinPoint.getSignature().getName());
	}

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

AfterAdvice和AroundAdvice与之类似,代码如下:
	/**
	 * After
	 * 
	 * @param joinPoint
	 */
	@After(value = "execution(* org.zlex.aop.Hello.sayHelloAfter(..))")
	public void afterAdvice(JoinPoint joinPoint) {
		System.out.println("After: " + joinPoint.getSignature().getName());
	}

	/**
	 * Around
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Throwable
	 */
	@Around(value = "execution(* org.zlex.aop.Hello.sayHelloAround(..))")
	public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("Around: " + joinPoint.getSignature().getName());
		System.out.println("Before");
		Object obj = joinPoint.proceed();
		System.out.println("End");
		return obj;
	}

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

AfterReturningAdvice可以获取目标方法的返回值,代码如下:
	/**
	 * AfterReturning
	 * 
	 * @param joinPoint
	 */
	@AfterReturning(value = "execution(* org.zlex.aop.Hello.sayHelloAfterReturning(..))", returning = "retVal")
	public void afterReturningAdvice(JoinPoint joinPoint, String retVal) {
		System.out.println("AfterReturning: "
				+ joinPoint.getSignature().getName());
		System.out.println("Return Value: " + retVal);
	}

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

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


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

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

这里就不再废话了,代码相见附件



相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ

分享到:
评论
2 楼 慕何而来 2012-05-29  
snowolf 写道
为啥上传的附件看不到了呢?!很诡异!

有的啊
1 楼 snowolf 2012-04-10  
为啥上传的附件看不到了呢?!很诡异!

相关推荐

Global site tag (gtag.js) - Google Analytics