Spring AOP(二)
advice通知类型:
- Before 连接点执行之前,但是无法阻止连接点的正常执行,除非该段执行抛出异常
- After 连接点正常执行之后,执行过程中正常执行返回退出,非异常退出
- After throwing 执行抛出异常的时候
- After (finally) 无论连接点是正常退出还是异常退出,都会执行
- Around advice: 围绕连接点执行,例如方法调用。这是最有用的切面方式。
- around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。
Before:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
After:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
After Throwing:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
@Aspect
public class AfterThrowingExample {
@AfterThrowing("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doRecoveryActions() {
// ...
}
}
After (Finally) Advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
@Aspect
public class AfterFinallyExample {
@After("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doReleaseLock() {
// ...
}
}
Around advice
p:环绕通知可以作方法的处理和改变参数(ProceedingJoinPoint.getArgs()获取参数)
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.CommonPointcuts.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
ProceedingJoinPoint pjp解析:正在增强的连接点。
Proceedingjoinpoint 和JoinPoint的区别:Proceedingjoinpoint 继承了JoinPoint,proceed()这个是aop代理链执行的方法。并扩充实现了proceed()方法,用于继续执行连接点。JoinPoint仅能获取相关参数,无法执行连接点,通过这个对象能获得连接点得信息,所在的类,所在的目标对象,所在的代理对象,参数,方法签名,方法返回类型。
JoinPoint的方法
1.java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;
2.Signature getSignature() :获取连接点的方法签名对象;
3.java.lang.Object getTarget() :获取连接点所在的目标对象;
4.java.lang.Object getThis() :获取代理对象本身;
proceed()有重载,有个带参数的方法,可以修改目标方法的的参数
Introductions
可以将某些实现某个接口,并实现接口的方法。
Aspect Instantiation Models切面实例化模型
“模式定义的方面唯一支持的实例化模型是单例模型。其他实例化模型可能会在未来的版本中得到支持”。程序中每一个切面都是一个单独的实例,AspectJ把这种模式称作单例实例化模型。通过perthis 和 pertarget 这两个语义去开启这个支持。perthis 是每一个符合条件的代理对象声明一个切面实例,pertarget就是每一个符合条件的目标对象声明一个切面实例。需要加上@Scope(“prototype”),否则报错Bean with name ‘demo2Aspect’ is a singleton, but aspect instantiation model is not singleton(用一个singleton的模式构建多个实例)
创作不易,转载请注明出处!