首页 > 代码库 > Spring-AOP-学习笔记(2)-AspectJ
Spring-AOP-学习笔记(2)-AspectJ
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 }
Spring-AOP-学习笔记(2)-AspectJ
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。