Spring Core-AOP

it2022-05-05  169

目录

目标

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

简介

AOP是对OOP的补充,从切面的角度考虑编程结构。OOP的单元是class,AOP的单元是aspect,aspect切面便于针对关注点进行模块化。 文档链接:https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/core.html#aop

相关概念

join point

程序执行中的一个关注点,如方法的执行或异常的控制。SpringAOP,指的是方法的执行。

aspect

对关注点的模块化,模块中包括关注点描述和对应的行为。例如事务管理。

SpringAOP,通过xml配置或@Aspect来实现。

advice

在确切的点,由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,这样让代码简洁,而且避免错误。

pointcut

一个描述,用于匹配感兴趣的join point。advice必须与pointcut描述关联,并且在由pointcut匹配到的joinpoint处执行,例如具体名称的方法执行。

introduction

允许在类型的代表之上,引入额外的方法或域。SpringAOP允许在advisedobject上引入任何接口。

target object

被一个或多个aspect advised的对象。因为SpringAOP使用了运行时代理,所以target指的是被代理的对象。

AOP proxy

为了实现aspect的约定,由AOP框架创建的对象。SpringAOP,指的是JDK动态代理或CGLIB代理。

SpringAOP只能将method作为joinpoint;如果需要异常和field作为joinpoint,需要选择AspectJ。

 

主要类

DefaultAopProxyFactory

默认aop代理工厂,创建Cglib代理或jdk动态代理

class DefaultAopProxyFactory implements AopProxyFactory AopProxy createAopProxy(AdvisedSupport config){}

当AdvisedSupport中optimize=true或proxyTargetClass=true或没有设置proxy interfaces,创建CglibProxy,否则Jdk动态代理

CglibAopProxy

生成代理类实例的方法;定义了一些拦截器类(如动态AOP拦截器)

class CglibAopProxy implements AopProxy

CglibAopProxy.DynamicAdvisedInterceptor 动态AOP拦截器

获取方法级别关注点的所有切面行为生成CglibMethodInvocation并执行process

CglibAopProxy.CglibMethodInvocation extends ReflectiveMethodInvocation

DefaultAdvisorChainFactory

org.springframework.aop.framework.DefaultAdvisorChainFactory

getInterceptorsAndDynamicInterceptionAdvice,获取关注点的所有切面行为

ReflectiveMethodInvocation

class ReflectiveMethodInvocation implements ProxyMethodInvocation

Object proceed(),依次执行切面行为,最后执行关注点

JoinPoint

org.aspectj.lang.JoinPoint

用于自定义advice方法的参数,代表当前关注点信息

ProceedingJoinPoint

org.aspectj.lang.ProceedingJoinPoint

用于自定义around advice方法的参数,代表当前关注点信息

MethodInvocationProceedingJoinPoint

spring中joinpoint proceedingJoinPoint的实现类,真实持有当前关注点信息。

 

使用AspectJ

开启Spring支持

需要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"

@aspect声明类作为面

@pointcut声明方法为pointcut

3中类型

kind,如execution(规定接口与方法)scope,如within(规定包)context,如this,target(规定proxy traget 参数等类型)

最佳实践

scope+kind

声明方法为advice

@Before@AfterReturning@AfterThrowing@After@Around

必须明确pointcut,可进行参数传递

如何确定advice的执行顺序

依据aspect的order决定,order越大则优先执行。 多个aspect时,则按照order决定顺序。一个aspect中的多个advice,无法判断顺序,建议分拆到多个aspect中。

 

事务

详见后续章节

 

 


最新回复(0)