目录
二、AbstractAutoProxyCreator#postProcessBeforeInstantiation源码解析
一、简介
AnnotationAwareAspectJAutoProxyCreator 实现了几个重要的扩展接口:
- 1)、实现了 BeanPostProcessor 接口:实现了 postProcessAfterInitialization()方法;
- 2)、实现了 InstantiationAwareBeanPostProcessor 接口:实现了 postProcessBeforeInstantiation()、postProcessAfterInstantiation()方法;
- 3)、实现了 SmartInstantiationAwareBeanPostProcessor 接口:实现了 predictBeanType() 方法;getEarlyBeanReference()方法;
- 4)、实现了 BeanFactoryAware 接口,实现了 setBeanFactory()方法;
本篇文章主要分析AnnotationAwareAspectJAutoProxyCreator 通过间接实现InstantiationAwareBeanPostProcessor接口,在内部主要做了哪些事情?
二、AbstractAutoProxyCreator#postProcessBeforeInstantiation源码解析
AnnotationAwareAspectJAutoProxyCreator类最上面的父类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,而SmartInstantiationAwareBeanPostProcessor接口继承自InstantiationAwareBeanPostProcessor,在IOC源码中,我们介绍过,InstantiationAwareBeanPostProcessor内部提供了两个方法:
- postProcessBeforeInstantiation():在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走;
- postProcessAfterInstantiation():在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null;
InstantiationAwareBeanPostProcessor是在AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()中执行的,在doCreateBean()实例化bean之前就调用了。
所以,我们需要关注:
AnnotationAwareAspectJAutoProxyCreator
==> AspectJAwareAdvisorAutoProxyCreator
==> AbstractAdvisorAutoProxyCreator
==> AbstractAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator各个间接父类中,postProcessBeforeInstantiation()、postProcessAfterInstantiation()方法的实现过程。
查看上面四个类的源码,发现只有根父类--- AbstractAutoProxyCreator实现了postProcessBeforeInstantiation()、postProcessAfterInstantiation()方法,我们查看具体的实现过程:
- (一)、postProcessBeforeInstantiation()方法
// AbstractAutoProxyCreator#postProcessBeforeInstantiation
// postProcessBeforeInstantiation()方法在bean实例化之前调用
// 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 组装缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 如果advisedBeans缓存中已经存在,即当前正在创建的Bean已经被解析过,则直接返回null
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 注意:AnnotationAwareAspectJAutoProxyCreator重写了isInfrastructureClass()方法.
// 1.isInfrastructureClass():判断当前正在创建的Bean是否是基础的Bean(Advice、PointCut、Advisor、AopInfrastructureBean)
// 2.shouldSkip():判断是不是应该跳过
// 满足两个条件其中之一,都将跳过,直接返回null
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
// 获取用户自定义TargetSource(目标源)
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 获取目标对象的拦截器链
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 创建AOP代理
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
AbstractAutoProxyCreator#postProcessBeforeInstantiation()处理流程大体如下:
- 根据beanClass和beanName获取缓存Key,通常就是beanName,如果是FactoryBean的话,则是"&"+beanNmae;
- 判断当前正在创建的Bean是否已经被解析过,如果已解析,则直接返回null;
- 判断当前正在创建的Bean是否是基础的Bean、是否需要跳过等;
- 用户自定义TargetSource(目标源)的处理;
AbstractAutoProxyCreator#postProcessBeforeInstantiation()中核心就是下面两个方法:
- isInfrastructureClass(beanClass)方法
此方法主要判断当前正在创建的Bean是否是基础的Bean,即当前bean是否是Advice、PointCut、Advisor、AopInfrastructureBean。
注意AnnotationAwareAspectJAutoProxyCreator类重写了isInfrastructureClass()方法,真正执行的是下面的代码。
// AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass
protected boolean isInfrastructureClass(Class<?> beanClass) {
// isInfrastructureClass():判断当前正在创建的Bean是否是基础的Bean(Advice、PointCut、Advisor、AopInfrastructureBean)
// 或者是否是切面(@Aspect)
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
// AbstractAutoProxyCreator.isInfrastructureClass
// 判断当前bean是否是基础类,如Advice、Pointcut、Advisor、AopInfrastructureBean
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
// 判断是否切面类
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
// 判断是否使用@Aspect注解
private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
可以看到,AnnotationAwareAspectJAutoProxyCreator的isInfrastructureClass()方法除了判断当前正在创建的Bean是否是基础的Bean之外,还判断了当前bean是否是切面。
- shouldSkip(beanClass, beanName)方法
判断是否需要跳过。
// AbstractAutoProxyCreator.shouldSkip
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
注意,AbstractAutoProxyCreator的子类----AspectJAwareAdvisorAutoProxyCreator重写了shouldSkip()方法,而AnnotationAwareAspectJAutoProxyCreator又继承自AspectJAwareAdvisorAutoProxyCreator类。
下面我们看下AspectJAwareAdvisorAutoProxyCreator#shouldSkip()方法的源码:
// AspectJAwareAdvisorAutoProxyCreator.shouldSkip
// 判断是否需要跳过
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 1.获取所有候选的Advisor增强器(即切面里面的通知方法),每个封装的通知方法的增强器的类型为InstantiationModelAwarePointcutAdvisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2.循环所有的增强器(通知方法),判断是否是AspectJPointcutAdvisor类型的,如果是的话,则需要跳过。(实际上就是跳过切面类)
for (Advisor advisor : candidateAdvisors) {
// 判断每个增强器是否是AspectJPointcutAdvisor类型的, 如果是的话则跳过(跳过切面类)
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
// 3.调用父类(AbstractAutoProxyCreator)的shouldSkip()方法
return super.shouldSkip(beanClass, beanName);
}
shouldSkip()方法的处理流程大体如下:
- 获取所有候选的Advisor增强器(即切面里面的通知方法),每个封装的通知方法的增强器的类型为InstantiationModelAwarePointcutAdvisor;
- 循环所有的增强器(通知方法),判断是否是AspectJPointcutAdvisor类型的,如果是的话,则需要跳过。(实际上就是跳过切面类);
- 调用父类(AbstractAutoProxyCreator)的shouldSkip()方法;
下面我们看一下Spring是如何获取所有候选的Advisor增强器的(即切面里面的通知方法),具体在findCandidateAdvisors()方法,源码如下:
// AbstractAdvisorAutoProxyCreator.findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 获取所有候选的Advisor增强器集合
return this.advisorRetrievalHelper.findAdvisorBeans();
}
AnnotationAwareAspectJAutoProxyCreator类重写了此方法:
// AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 1.调用父类AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()方法找到所有候选的增强器(通知方法)
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 2.为bean工厂中的所有的AspectJ切面构建Advisor增强器
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()处理过程大体如下:
- 调用父类AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()方法找到所有候选的增强器(通知方法);
- 为bean工厂中的所有的AspectJ切面构建Advisors增强器;
首先来看下如何找到所有候选的增强器(通知方法)的,具体源码在BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans():
// BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans
// 获取所有符合条件的Advisor增强器,会忽略FactoryBeans以及正在创建中的bean
public List<Advisor> findAdvisorBeans() {
// 1.保存增强器对应的beanName集合,并将cachedAdvisorBeanNames缓存的值赋值给它
String[] advisorNames = this.cachedAdvisorBeanNames;
// 2.如果cachedAdvisorBeanNames缓存为空,则从bean工厂中获取class类型为Advisor的所有bean名称
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 3.存入缓存中
this.cachedAdvisorBeanNames = advisorNames;
}
// 如果advisorNames是空的,直接返回空集合
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
// 4.循环遍历前面确定好的增强器对应的beanName集合,确定切面与当前beanName是否符合
for (String name : advisorNames) {
// isEligibleBean(): 确定切面与当前beanName是否符合,默认都是true
if (isEligibleBean(name)) {
// 5.如果当前bean正在创建中的话,什么都不处理
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
} else {
try {
// 6.根据beanName从工厂中获取对应的bean对象,并添加到advisors集合中
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
// 7.返回advisors增强器集合
return advisors;
}
findAdvisorBeans()方法的整体流程如下:
- 获取到cachedAdvisorBeanNames缓存;
- 如果cachedAdvisorBeanNames缓存为空,则从bean工厂中获取class类型为Advisor的所有bean名称;
- 将上一步获取的bean名称存入缓存中;循环
- 遍历前面确定好的增强器对应的beanName集合,确定切面与当前beanName是否符合;
- 如果当前bean正在创建中的话,什么都不处理;
- 如果当前bean不是正在创建,则根据beanName从工厂中获取对应的bean对象,并添加到advisors集合中;
- 返回advisors增强器集合;
当所有候选的增强器找到之后,就需要为bean工厂中的所有的AspectJ切面构建Advisor增强器,具体是在this.aspectJAdvisorsBuilder.buildAspectJAdvisors()完成的。
// BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
// 1.获取aspectBeanNames缓存,如果为空,则会触发切面的解析工作
List<String> aspectNames = this.aspectBeanNames;
// 解析切面,注意实例化第一个单实例bean的时候就会触发解析切面
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
// 用于保存所有解析出来的Advisor增强器
List<Advisor> advisors = new ArrayList<>();
// 用于保存切面名称
aspectNames = new ArrayList<>();
// 2.获取工厂中所有的beanNames(bean名称集合)
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 3.循环所有的beanNames(bean名称集合),找到增强器
for (String beanName : beanNames) {
// 跳过不符合条件的beanName
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 获取beanName对应的bean的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 4.如果存在@Aspect注解的话,则进行解析
if (this.advisorFactory.isAspect(beanType)) {
// 如果是切面类的话,则将beanName加入到aspectNames中
aspectNames.add(beanName);
// 根据beanType、beanName创建切面元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 如果获取per-clause的类型是SINGLETON
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 创建MetadataAwareAspectInstanceFactory,主要用来创建切面对象实例
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 5.获取标记了@AspectJ相关注解的增强方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 6.如果当前bean是单例的,则将对应的增强方法加入advisorsCache缓存中
this.advisorsCache.put(beanName, classAdvisors);
} else {
// 7.如果当前bean不是单例的,则将对应的工厂factory加入到aspectFactoryCache缓存中,后面可以通过factory来解析增强方法
this.aspectFactoryCache.put(beanName, factory);
}
// 将解析的增强器添加到advisors集合中
advisors.addAll(classAdvisors);
} else {
// 如果per-clause的类型不是SINGLETON
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
// 将对应的工厂factory加入到aspectFactoryCache缓存中,后面可以通过factory来解析增强方法
this.aspectFactoryCache.put(beanName, factory);
// 获取标记@AspectJ注解的增强方法
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
// 将解析出来的切面beanName放到缓存aspectBeanNames
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// 如果经过上述的解析后,缓存aspectNames还是空列表的话,则直接返回一个空列表出去
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
// 存放所有的增强器的集合
List<Advisor> advisors = new ArrayList<>();
// 8.循环遍历所有解析到的切面名称
for (String aspectName : aspectNames) {
// 9.根据切面名称从缓存advisorsCache中查找对应的增强器
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
// 10.如果缓存中已经存在解析好的Advisor,则直接添加到advisors中
advisors.addAll(cachedAdvisors);
} else {
// 11.缓存中没有,则根据切面beanName从缓存aspectFactoryCache中查找对应的工厂,然后解析出增强器,并添加到advisors中
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
// 返回增强器集合
return advisors;
}
buildAspectJAdvisors()方法的处理流程:
- 获取aspectBeanNames缓存,如果为空,则会触发切面的解析工作;
- 获取工厂中所有的beanNames(bean名称集合);
- 循环所有的beanNames(bean名称集合),找到增强器;
- 如果存在@Aspect注解的话,则进行解析;
- 获取标记了@AspectJ相关注解的增强方法;
- 如果当前bean是单例的,则将对应的增强方法加入advisorsCache缓存中;
- 如果当前bean不是单例的,则将对应的工厂factory加入到aspectFactoryCache缓存中,后面可以通过factory来解析增强方法;
- 循环遍历所有解析到的切面名称,根据切面名称从缓存advisorsCache中查找对应的增强器;
- 如果缓存中已经存在解析好的Advisor,则直接添加到advisors中;
- 缓存中没有,则根据切面beanName从缓存aspectFactoryCache中查找对应的工厂,然后解析出增强器,并添加到advisors中;
上述流程中,比较复杂的方法是this.advisorFactory.getAdvisors(factory):真正的去获取Advisor增强器。
// org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取到当前处理的切面类类型
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 获取到当前处理的切面类名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 对切面类进行一些校验
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator so that it will only instantiate once.
// 包装MetadataAwareAspectInstanceFactory, 保证只会实例化一次
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
// 存放增强器的集合
List<Advisor> advisors = new ArrayList<>();
// 获取切面类中的所有通知方法,也就是被@Around、@After等注解修饰的方法,但是会跳过@Pointcut修饰的通知方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 循环解析切面中的通知方法,将通知方法包装成Advisor增强器
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
// 如果增强器不为空,则添加到advisors集合中
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
// 如果增强器advisors不为空,而且配置了增强延迟初始化,那么需要在首位加入同步实例化增强器(用以保证增强使用之前的实例化)
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
// 添加到集合中第一个位置
advisors.add(0, instantiationAdvisor);
}
// 获取DeclareParents注解
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
getAdvisors()方法核心逻辑有两个:
- 获取切面类中的所有通知方法,并按照规则排序---getAdvisorMethods(aspectClass)方法
也就是被@Around、@After等注解修饰的方法,但是会跳过@Pointcut修饰的通知方法,源码如下:
// org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisorMethods
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
// 1.获取到当前切面类aspectClass的所有通知方法
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// 2.排除掉@Pointcut注解修饰的方法
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
// 3.对通知方法进行排序
if (methods.size() > 1) {
methods.sort(METHOD_COMPARATOR);
}
// 4.返回通知方法
return methods;
}
- 将通知方法包装成Advisor增强器---getAdvisor()方法
// 将通知方法包装成Advisor增强器
// org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// 对切面类进行一些校验
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获取切点信息,封装成AspectJExpressionPointcut
AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 实例化切面通知对象
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
getAdvisor()核心就是实例化了一个InstantiationModelAwarePointcutAdvisorImpl切面通知对象,我们查看其构造方法:
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 切点表达式
this.declaredPointcut = declaredPointcut;
// 切面的class对象
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
// 切面方法的名称
this.methodName = aspectJAdviceMethod.getName();
// 切面方法的参数类型
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
// 切面方法对象
this.aspectJAdviceMethod = aspectJAdviceMethod;
// aspectj的通知工厂
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
// aspect的实例工厂
this.aspectInstanceFactory = aspectInstanceFactory;
// 切面的顺序
this.declarationOrder = declarationOrder;
// 切面的名称
this.aspectName = aspectName;
// 判断当前的切面对象是否需要延时加载
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
// 非延迟加载
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 实例化Advice通知对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
在InstantiationModelAwarePointcutAdvisorImpl的构造方法中,首先是初始化了一些属性值,然后判断当前的切面对象是否需要延时加载,分别做不同的操作。
如果切面对象是非延迟加载的情况,则会执行实例化Advice通知对象:instantiateAdvice(this.declaredPointcut)。
// org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.instantiateAdvice
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
继续跟踪到this.aspectJAdvisorFactory.getAdvice()方法:
// org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvice
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 获取切面类类型
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 校验切面类
validate(candidateAspectClass);
// 获取切面方法上的注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
// 判断解析出来的注解信息是否为null
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
// 再次校验切面类是否使用了@AspectJ注解
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
// 根据方法使用的aspectJ注解创建对应的增强器
switch (aspectJAnnotation.getAnnotationType()) {
// 如果是PointCut注解,那么就抛出异常
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
// 如果是@Around环绕通知,则构建AspectJAroundAdvice通知
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
// 如果是@Before前置通知,则构建AspectJMethodBeforeAdvice通知
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
// 如果是@After后置通知,则构建AspectJAfterAdvice通知
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
// 如果是@AfterReturning返回通知,则构建AspectJAfterReturningAdvice通知
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
// 如果是@AfterThrowing异常通知,则构建AspectJAfterThrowingAdvice通知
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// 配置通知对象的相关属性,如设置切面名称、参数等
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
到这里,postProcessBeforeInstantiation()方法整个流程执行完成,已经获取到我们的Advisor增强器。
- (二)、postProcessAfterInstantiation()方法:直接返回true
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
三、总结
最后,通过一张图总结一下AnnotationAwareAspectJAutoProxyCreator实现InstantiationAwareBeanPostProcessor接口底层做的一些工作: