概念
- 面向切面编程
- 横向扩展
- 动态代理
相关术语
动态代理
spring在运行期,生成动态代理对象,不需要特殊的编译器
Spring AOP的底层就是通过JDK动态代理或者CGLIb动态代理 技术为目标Bean执行横向织入
- 目标对象实现了接口,spring使用JDK的java.lang.reflect.Proxy类代理
- 若目标对象没有实现任何接口,spring使用CGLib库生成目标对象的子类
AOP通知类型
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 引介通知
AOP切面类型
- Advisor:代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截
- PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类哪些方法
AspectJ
实现spring AOP的一个框架
通知类型
@Before 前置通知,相当于BeforeAdvice
@AfterReturning 后置通知,相当于AfterReturningAdvice
@Around 环绕通知,相当于MethodInterceptor
@AfterThrowing异常抛出通知,相当于ThrowAdvice
@After 最终final通知,不管是否异常,该通知都会执行
切入点表达式
注意:
代码在 spring-aop中
java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAdvice {
/**
* 可以获取到方法的返回值
* 给update方法进行后置增强
*/
@AfterReturning(value = "execution(* cn.ting.aop.aspectj.*.update(..))",returning="result")
public void after(String result){
System.out.println("后置通知"+result);
}
/**
*
* 给insert方法进行前置增强
*/
@Before(value = "execution(* cn.ting.aop.aspectj.*.insert(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知"+joinPoint.getTarget());
}
/**
* 环绕通知
* @param joinPoint
*/
@Around(value = "execution(* cn.ting.aop.aspectj.*.find(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("前置通知");
Object proceed = joinPoint.proceed();
System.out.println("后置通知");
return proceed;
}
}