一、生成代理对象
spring 对象初始化过程(遗记了能够看这里:对象初始化惯例流程),属性赋值后对对象做代理加强——这是 AOP 得以实现的根底。
源码入口如下:
Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 属性赋值办法
populateBean(beanName, mbd, instanceWrapper);
// ## 此处做代理加强
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
咱们看下办法实现:
initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 对象初始化前置处理器
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 执行初始办法
this.invokeInitMethods(beanName, wrappedBean, mbd);
// ## 对象初始化后置处理器
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
跟踪 后置处理器
的执行链路:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// ## 1. 获取 Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// ## 2. 创立 AOP 代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
}
别离察看这两步的实现。
1. 获取 Advisor
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
// 咱们察看“注解实现”org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
List<Advisor> buildAspectJAdvisors() {Class<?> beanType = this.beanFactory.getType(beanName);
// ### A. 什么样的对象是 Advisor?if (this.advisorFactory.isAspect(beanType)) {
// ### B.Advisor 对象如何创立
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
}
}
从这部分源码又衍生出几个问题。
A. 什么样的对象是 Advisor
答:被 @Aspect 对象润饰的对象是 Advisor
org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect
org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#hasAspectAnnotation
private boolean hasAspectAnnotation(Class<?> clazz) {
// 源码是这么写的
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
再思考一下,应用过程中被 @Aspect 注解润饰的对象 是什么?
答案 是“一个切面申明”,比方上面的例子。
#### 这是一个切面申明的例子,非 spring 源码 ####
@Aspect
@Component
public class TransactionAop {@Pointcut("execution(* com.jiuxian..service.*.*(..))")
public void pointcut() {}
@Before("pointcut()")
public void beginTransaction() {System.out.println("before beginTransaction");
}
@After("pointcut()")
public void commit() {System.out.println("after commit");
}
}
于是大胆推断——Advisor 是不是一个切面对象的封装?
接下来,通过 Advisor 的创立过程来验证这个推断是否正确。
B.Advisor 对象如何创立
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory){
// ** 代码 1:获取了某种办法 **
for (Method method : getAdvisorMethods(aspectClass)) {
// ** 代码 2:依据 ` 代码 1` 的办法构建 Advisor **
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
}
}
代码 1:获取的某种办法是什么?
ReflectionUtils.doWithMethods(aspectClass, method -> {
// 获取非 @Poincut 注解润饰的所有办法(即 @Before、@After 注解润饰的办法)if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {methods.add(method);
}
});
代码 2:依据 代码 1
的办法构建的 Advisor 到底是什么?
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor
Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// == 获取切面信息
AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {return null;}
// == 返回 Advisor 的实现
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
Advisor 由 InstantiationModelAwarePointcutAdvisorImpl 实现 ,联合代码 1 来看,Advisor 实质是对一个切面办法(@Before、@After 等润饰的办法)的封装
之前的推断有些许偏差……
最初咱们看一下 InstantiationModelAwarePointcutAdvisorImpl
是怎么获取 Advice 的
C.Advisor 获取 Advice
org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#getAdvice
org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice
// == 每个注解都对应着一种具体的 Advice 实现
switch (aspectJAnnotation.getAnnotationType()) {
case AtAround:
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
}
2. 创立 AOP 代理对象
后面纵深过大,简略总结一下:
咱们用大段篇幅解释了 wrapIfNecessary 办法的“代码 1”局部——这个 specificInterceptors 数组,其实就是切面中的切面办法(各种 @Before、@After 注解润饰的办法)的封装。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// ## 1. 获取 Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// ## 2. 创立 AOP 代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
}
接下来,进入“代码 2”局部,看看 AOP 代理是如何创立的!
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {//== A. 先创立 AopProxy 对象,实质就是 new JdkDynamicAopProxy(config)
return new JdkDynamicAopProxy(config)
//== B. 再调用 JdkDynamicAopProxy 的 getProxy()办法
.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {// ## 第三个参数 InvocationHandler 传入的是 this,所以被代理对象理论执行的是本类的 invoke()办法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
代理执行逻辑,下一章再剖析。
二、AOP 执行
目前咱们曾经晓得,spring 对象初始化后会对申明 AOP 切面的对象作动静代理。
这样在对象办法执行时,会执行相应的代理办法。
而代理对象又蕴含全副的切面办法封装和切面申明,剩下的只是把它们关联起来。
本章对这部分逻辑加以分析。
// ## 1. 构建责任链(全副的 advice)List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// ## 2. 责任链调度
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method,
args, targetClass, chain);
retVal = invocation.proceed();
1. 构建责任链
org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
if (advisor instanceof PointcutAdvisor) {PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
if (config.isPreFiltered()
|| pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 获取办法匹配器 @Pointcut 的 expression
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
// 依据 expression 表达式匹配指标办法(以后执行的办法)match = mm.matches(method, actualClass);
if (match) {
// 匹配上了,返回办法的全副拦截器(advice 的封装)MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
2. 责任链调度
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
// 构造函数中赋值 chain,办法拦截器 -> advice
protected final List<?> interceptorsAndDynamicMethodMatchers;
// chain 的索引
private int currentInterceptorIndex = -1;
-------- ## 以上为属性 ## --------------
// ### 这是一个递归办法
public Object proceed() throws Throwable {
// == 1. 曾经是 chain 中的最初一个拦截器,则执行原办法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return this.invokeJoinpoint();
}
// == 2. 否则,执行过滤器办法
else {
// 索引自增,获取链中的以后拦截器
Object interceptorOrInterceptionAdvice
= this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// ## 拦截器执行(不同的拦截器有不同的实现)return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
最初察看两种不同的拦截器实现吧。
-
before 拦截器
// == before 拦截器(告诉)org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke { // 先执行拦截器 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 再执行办法(递归调用,代码去执行 ReflectiveMethodInvocation#proceed)return mi.proceed();}
-
after 拦截器
// == after 拦截器(告诉)org.springframework.aop.aspectj.AspectJAfterAdvice#invoke { Object var2; try { // 先执行办法(递归调用,代码去执行 ReflectiveMethodInvocation#proceed)var2 = mi.proceed();} finally { // 再执行拦截器实现 this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); } return var2; }
附录
P6-P7 常识合辑