标签:pre ref his span 配置 this 还需 aspect aop
1.启用@AspectJ,需要下载aspectjweaver.jar
<!-- 默认启用动态代理 -->
<aop:aspectj-autoproxy/>
<!-- 启用CGliB -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
2.声明一个切面(Aspect)
/** 注解的方式声明 **/ package org.xyz; import org.aspectj.lang.annotation.Aspect; @Aspect @Component public class MyAspect{ }
添加@Component注解是为了让Spring自动搜索到并进行管理,当然还需要告诉Spring搜索路径:
<context:component-scan base-package="org.xyz"/>
<!-- XML方式声明,不需要@Aspect和@Component注解 --> <bean id="masp" class="org.xyz.MyAspect"> <!-- 配置切面属性 --> </bean> <aop:config> <aop:aspect id="myAspect" ref="masp"> ... ... </aop:aspect> </aop:config>
3.声明一个切点(Pointcut)
Spring AOP只支持在方法上定义连接点,所以只需考虑如何让切点匹配到目标方法,声明一个切点需要2步:一个包含名称的签名及参数(方法返回值必须为void);一个切点表达式。切点表达式使用@Pointcut注解表示。
@Pointcut("execution(* com.xyz.myapp.service..(..))") public void anyOldTransfer(){ } /** * anyOldTransfer即为切点签名 * execution为切点表达式,这里表示任意返回值,service包下(包括子包)任意形参的接口实现类方法 */
<!-- XML方式配置 --> <aop:config> <aop:aspect id="myAspect" ref="masp"> <aop:pointcut id="anyOldTransfer" expression="execution(* com.xyz.myapp.service..(..))"/> </aop:aspect> </aop:config>
4.声明一个通知(Advice)
@Aspect public class AspectExample(){ @Before("execution(* com.xyz.myapp.dao..(..)") public void beforeTest(){ } @After("execution(* com.xyz.myapp.dao..(..)") public void afterTest(){ } @AfterReturning("execution(* com.xyz.myapp.dao..(..)") public void afterReturnTest(){ } /** 将返回值传递给切点 */ @AfterReturning("execution(* com.xyz.myapp.dao..(..)",returning="retVal") public void afterReturningTest(Object retVal){ } @AfterThrowing("execution(* com.xyz.myapp.dao..(..)") public void afterThrowingTest(){ } /** 捕捉指定异常 */ @AfterThrowing("execution(* com.xyz.myapp.dao..(..)",throwing="ex") public void afterThrowingTest(DataAccessException ex){ } @Around("execution(* com.xyz.myapp.dao..(..)") public Object aroundTest(ProceedingJoinPoint pjp) throws Throwable{ //前处理 Object retVal = pjp.proceed(); //后处理 return retVal; } }
访问当前JoinPoint
任何Advice类型方法都可以声明第一个形参为org.aspectj.lang.JoinPoint(Around的为ProceedingJoinPoint,JoinPoint的子类)
JoinPoint接口提供了:getArgs()获取方法形参,getThis()获取代理对象,getTarget()获取目标对象
将调用方法参数传递到advice
后置的上面已经给出实例,下面看看前置的
@Before("execution(* com.xyz.myapp.dao..(..) && args(account,..)") public void beforeTest(Account account){ }
自定义注解使用
//定义注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Auditable { AuditCode value(); } //获取注解 @Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)") public void audit(Auditable auditable) { AuditCode code = auditable.value(); // ... }
Advice参数和泛型
Spring AOP还可以处理带泛型的类和方法参数
public interface Sample<T> { void sampleGenericMethod(T param); void sampleGenericCollectionMethod(Collection<T> param); } @Before("execution(* ..Sample+.sampleGenericMethod(*)) && args(param)") public void beforeSampleMethod(MyType param) { // Advice implementation } /** 对于集合的泛型形参要用?代替,真正类型由调用者自行转换 */ @Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) && args(param)") public void beforeSampleMethod(Collection<?> param) { // Advice implementation }
标签:pre ref his span 配置 this 还需 aspect aop
原文地址:http://www.cnblogs.com/manliu/p/5986498.html