一、生成代理对象
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 buildAspectJAdvisors() {
Class> beanType = this.beanFactory.getType(beanName);
// ### A.什么样的对象是Advisor?
if (this.advisorFactory.isAspect(beanType)) {
// ### B.Advisor对象如何创建
List 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 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
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; }