AspectJ
@AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并运用的风格类似纯java注解的普通java类
Spring可以使用AspectJ来做切入点解析
AOP的运行仍旧是纯Spring AOP,对AspectJ的编辑器或者植入无依赖性
注解方式:
@Configuration
@EnableAspectJAutoProxy
public class AppConfig{
}
配置文件方式:<aop:aspectj-autoproxy/>
@AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并运用
用@Aspect注解的类可以有方法和字段,他们也可能包含切入点(pointcut),通知(Advice)和引入(introduction)声明
@Aspect注解是不能通过类路径自动检测发现的,所以要配合使用@Component注解或者在xml配置bean
eg:
xml配置bean
<bean id="myAspect" class="org.xyz.NotVeryUsefulAspect">
</bean>
@Aspect
public class NotVeryUsefulAspect{
}
@Component注解
@Aspect
@Component
public class NotVeryUsefulAspect{
}
pointcut(切入点)
一个切入点通过一个普通的方法定义来提供,并且切入点表达式使用@Pointcut注解,方法返回类型必须为void
定义一个名为‘anyOldTransfer’,这个切入点将匹配任何名为“transfer”的方法的执行
@Pointcut("execution(* transfer(..))")
private void anyOldTransfer(){
}
组合pointcut
切入点表达式可以通过&&、||和!进行组合,也可以通过名字引用切入点表达式
通过组合,可以建立更加复杂的切入点表达式
@Pointcut("execution(punlic * (..))")
private void anyPublicOperation(){
}
@Pointcut("within(com.xyz.someapp.trading..)")
private void inTrading(){
}
@Pointcut("anyPublicOperation() && inTrading() ")
private void tradingOperation(){
}
一个好多切入点应该要:
1.选择特定类型的连接点:execution,get,set,call,handler
2.确定连接点范围:within,withincode
3.匹配上下文:this,target,@annotation
Before advice
@Component
@Aspect
public class MoocAspect{
@Before(execution(* com.imooc.aop.aspectj.biz.* Biz.* (..))")
public void before(){
}
}
PS:
com.imooc.aop.aspectj.biz.* Biz.* (..))
是在执行com.imooc.aop.aspectj包下以Biz结尾的类所有方法是匹配Advice
After returning advice
@Aspect
public class AfterReturningExample{
@AfterReturning("com.xyz.SystemArchitecture.dataAccessOperation()")
public void daAccessCheck(){
}
}
有时需要在通知体内得到返回的实际值,可以使用@AfterReturning绑定返回值形式
@Aspect
public class AfterReturningExample{
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void daAccessCheck(Object retVal){
}
}
PS:
public void daAccessCheck(Object retVal)
Object为返回值,根据实际返回值类型填写
After throwing advice
@Aspect
public class AfterReturningExample{
@AfterThrowing("com.xyz.SystemArchitecture.dataAccessOperation()")
public void doRecoveryActions(){
}
}
有时需要在通知体内得到返回的实际值,可以使用@AfterReturning绑定返回值形势
@Aspect
public class AfterThrowingExample{
@AfterThrowing(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing="ex")
public void doRecoveryActions(DataAccessException ex){
}
}
After (finally) advice
最终通知必须准备处理正常和异常两种异常返回情况,它通常用于释放资源
@Aspect
public class AfterFinallyExample{
@After("com.xyz.SystemArchitecture.dataAccessOperation()")
public void doRecoveryLock(){
}
}
Around advice
环绕通知使用@Around注释声明,通知方法的第一个参数必须是ProceedingJoinPoint类型
在通知内部调用ProceedingJoinPoint的proceedings()方法会导致执行真正的方法,传入一个Object[]对象,数组中的值将被作为参数传递给方法
@Aspect
public class AroundExample{
@Around("com.xyz.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
Object retVal = pjp.proceed();
return retVal;
}
}
给advice传递参数
方法一:
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account){
//...
}
方法二:
@Poincyt("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
private void accountDataAccessOperation(Account account){
}
@Before("accountDataAccessOperation(account)")
public void validateAccount(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的参数以及泛型
public interface Sample<T>{
void sampleGenericMethod(T param);
void sampleGenericCollectionMethod(Collection<T> param);
}
@Before("execution(* ..Sample+.sampleGenericMethod(* )) && args (param)")
public void beforeSampleMethod(MyType param){
//..
}
@Before("execution(* ..Sample+.sampleGenericCollectionMethod(* )) && args (param)")
public void beforeSampleMethod(Collection<MyType> param){
//....
}
内容来源于网络,如有侵权,请联系作者删除!