目录
目标
AOP
简介
相关概念
join point
aspect
advice
pointcut
introduction
target object
AOP proxy
主要类
DefaultAopProxyFactory
CglibAopProxy
DefaultAdvisorChainFactory
ReflectiveMethodInvocation
使用AspectJ
开启Spring支持
@aspect声明类作为面
@pointcut声明方法为pointcut
声明方法为advice
如何确定advice的执行顺序
事务
介绍springcore中的IOC、AOP、事务,阐述通过源码了解的原理。
AOP是对OOP的补充,从切面的角度考虑编程结构。OOP的单元是class,AOP的单元是aspect,aspect切面便于针对关注点进行模块化。 文档链接:https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/core.html#aop
程序执行中的一个关注点,如方法的执行或异常的控制。SpringAOP,指的是方法的执行。
对关注点的模块化,模块中包括关注点描述和对应的行为。例如事务管理。
SpringAOP,通过xml配置或@Aspect来实现。
在确切的点,由aspect执行的具体行为。advice的类型包括around before after。许多AOP框架,包括SpringAOP,将advice视为interceptor拦截器,并且对join point维持一个拦截器链。
type
before advice 在join point之前执行的advice,无法控制执行流程进入joinpoint @Before("pointcut()") public void doBefore(JoinPoint joinPoint) throws Exception { // do something }after returning advice 在join point正常返回之后执行的advice @AfterReturning(pointcut = "pointcut()") public void doAfterReturning(JoinPoint joinPoint) { // do something }
after throwing advice 在join point抛出异常后执行的adviceafter finally advice 忽略join point的返回方式(不管正常返回还是抛出异常),在join point退出后执行advicearound advice 在join point之前和之后都可以执行的advice,威力最大的advice。它负责决定执行流程是否进入join point,是否通过返回自定义数据或抛出自定义异常的方式截断joinpoint的执行 @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // do something // 可以直接返回,中断调用 return joinPoint.proceed(); }
type选择建议:选择最适合需求的advice,这样让代码简洁,而且避免错误。
一个描述,用于匹配感兴趣的join point。advice必须与pointcut描述关联,并且在由pointcut匹配到的joinpoint处执行,例如具体名称的方法执行。
允许在类型的代表之上,引入额外的方法或域。SpringAOP允许在advisedobject上引入任何接口。
被一个或多个aspect advised的对象。因为SpringAOP使用了运行时代理,所以target指的是被代理的对象。
为了实现aspect的约定,由AOP框架创建的对象。SpringAOP,指的是JDK动态代理或CGLIB代理。
SpringAOP只能将method作为joinpoint;如果需要异常和field作为joinpoint,需要选择AspectJ。
默认aop代理工厂,创建Cglib代理或jdk动态代理
class DefaultAopProxyFactory implements AopProxyFactory AopProxy createAopProxy(AdvisedSupport config){}当AdvisedSupport中optimize=true或proxyTargetClass=true或没有设置proxy interfaces,创建CglibProxy,否则Jdk动态代理
生成代理类实例的方法;定义了一些拦截器类(如动态AOP拦截器)
class CglibAopProxy implements AopProxyCglibAopProxy.DynamicAdvisedInterceptor 动态AOP拦截器
获取方法级别关注点的所有切面行为生成CglibMethodInvocation并执行processCglibAopProxy.CglibMethodInvocation extends ReflectiveMethodInvocation
org.springframework.aop.framework.DefaultAdvisorChainFactory
getInterceptorsAndDynamicInterceptionAdvice,获取关注点的所有切面行为
Object proceed(),依次执行切面行为,最后执行关注点
org.aspectj.lang.JoinPoint
用于自定义advice方法的参数,代表当前关注点信息
org.aspectj.lang.ProceedingJoinPoint
用于自定义around advice方法的参数,代表当前关注点信息
spring中joinpoint proceedingJoinPoint的实现类,真实持有当前关注点信息。
需要org.aspectJ的jar
现在已经不使用xml文件了。
spring xml添加 <aop:aspectj-autoproxy/> 可能还需要 xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
3中类型
kind,如execution(规定接口与方法)scope,如within(规定包)context,如this,target(规定proxy traget 参数等类型)最佳实践
scope+kind必须明确pointcut,可进行参数传递
依据aspect的order决定,order越大则优先执行。 多个aspect时,则按照order决定顺序。一个aspect中的多个advice,无法判断顺序,建议分拆到多个aspect中。
详见后续章节