1.概述
本文介绍配置切面后,动态代理创建器自动创建动态代理的过程。有些名称先统一,可先看看前一篇:
原始bean: 需要被动态代理的对象,一般是我们用户编写的java类;
代理bean: spring为原始bean创建的代理对象,可在执行原始bean的方法时,添加额外的逻辑;
Advice: 通知,代理bean为原始bean添加的额外执行逻辑。一个Advice处理一种逻辑,比如事务注解和缓存注解会有两个Advice;
Advisor: 顾问,是对Advice(通知)的封装,通常内部会持有一个Advice对象;
代理方式 | 实现方式 |
接口代理 | jdk动态代理 |
目标类代理 | cglib动态代理 |
2.结论(重点)
代理bean的创建过程:
A.入口是SmartInstantiationAwareBeanPostProcessor的生命周期管理方法(如实例化前置处理器postProcessBeforeInstantiation),创建每个bean时都会调用此方法,在这些方法中可以对bean进行修改。而创建代理就是判断bean是否需要使用代理bean,如果需要就创建代理bean代替原始bean;
B.判断原始bean是否能封装为TargetSource,不能则不创建代理bean;
C.获取原始bean配置的顾问和通知(AdvicesAndAdvisors);
根据获取方式的不同可以分成两类: 普通的Advisor和AspectJ切面;
a.普通的Advisor: 本身就是Advisor的实例 ,可直接使用beanFactory.getBean(Class requiredType)获取;
b.AspectJ注解切面: 本身只是只是标注了@Aspect的普通类,并不是Advisor的子类。需要根据bean方法上的切面注解(如@Around)封装为Advisor;
找到所有的Advisor后,然后根据Advisor提供的过滤方法判断是否能适用于原始bean;
D.根据原始bean,TargetSource和顾问和通知列表,创建代理bean;
根据原始bean的的配置和代理的限制,选择为bean创建jdk代理还是cglib代理。springboot默认proxyTargetClass=true,所以默认为cglib代理;
使用jdk动态代理的场景 | 使用cglib动态代理的场景 |
proxyTargetClass=false & 原始bean存在有效的接口 | proxyTargetClass=true |
proxyTargetClass=true & Interface(targetClass.isInterface()) | proxyTargetClass=false & 原始bean强制使用cglib代理 |
proxyTargetClass=true & Proxy(Proxy.isProxyClass(targetClass)) | proxyTargetClass=false & 原始bean没有有效的接口 |
proxyTargetClass=true & Lambda(ClassUtils.isLambdaClass(targetClass)) |
3.原理
核心类图
类体系分成两部分:
- AbstractAutoProxyCreator及其父类/父接口主要负责处理生成代理相关的配置的逻辑;
- AbstractAdvisorAutoProxyCreator及其子类主要负责检索原始bean的顾问和通知;
«Interface»
AopInfrastructureBean
//**基础设施标记接口
ProxyConfig
//**代理配置
- boolean proxyTargetClass//**是否启用cglib代理
- boolean optimize //**是否优化,true:使用cglib代理
< boolean opaque
< boolean exposeProxy //**是否暴露代理
- boolean frozen //**是否冻结
+//**复制代理配置()
+void copyFrom(ProxyConfig config)
ProxyProcessorSupport
//**代理创建器通用功能基类
//**主要用于classLoader管理和计算原始类的接口
- boolean classLoaderConfigured //**是否设置了classLoader
- ClassLoader<?> proxyClassLoader//**classLoader
+//**两个都是设置classLoader,setProxyClassLoader优先度更高()
+void setBeanClassLoader(ClassLoader)
+void setProxyClassLoader(ClassLoader)
#计算原始类是否包合理的接口。否则设置proxyTargetClass=true()
#void evaluateProxyInterfaces(Class<?>, ProxyFactory)
«Interface»
SmartInstantiationAwareBeanPostProcessor
//**智能实例化处理器
+//**预测bean的class类型()
+Class~?~ predictBeanType(Class<?>, String)
+//**确定bean的class类型()
+Class~?~ determineBeanType(Class<?>, String)
+//**获取提前暴露的bean引用()
+Object getEarlyBeanReference(Object, String)
+//**实例化前置处理器()
+Object postProcessBeforeInstantiation(Class<?>, String)
+//**初始化后置处理器()
+Object postProcessAfterInitialization(Object, String)
«Abstract»
AbstractAutoProxyCreator
//**创建代理对象的主要逻辑
//**子类只需要实现getAdvicesAndAdvisorsForBean获取原始bean需要绑定的通知和顾问
- TargetSourceCreator[] customTargetSourceCreators //**TargetSource创建器
- String[] interceptorNames //**拦截器bean名称数组
- AdvisorAdapterRegistry advisorAdapterRegistry //**advisor适配器注册,SPI接口
- Map<Object, Boolean> advisedBeans //**key:bean名称,vlue:是否使用代理
- Map<Object, Class> proxyTypes //**key:bean名称,vlue:代理bean的class对象
- Map<Object, Object> earlyProxyReferences //**key:bean名称,vlue:原始bean
- Set<String> targetSourcedBeans //**能获取targetSource的bean名称
- boolean applyCommonInterceptorsFirst //**是否首先应用公共Interceptor
# Object[] DO_NOT_PROXY //**常量,标记getAdvicesAndAdvisorsForBean方法没有代理时的返回值
+//**springbean的生命周期管理的5个方法,创建bean动态代理的入口()
+//**1.预测bean的class类型()
+Class~?~ predictBeanType(Class<?>, String)
+//**2.确定bean的class类型.创建代理的class对象()
+Class~?~ determineBeanType(Class<?>, String)
+//**3.获取提前暴露的bean引用,没有则创建代理对象()
+Object getEarlyBeanReference(Object, String)
+//**4.实例化前置处理器.创建代理对象()
+Object postProcessBeforeInstantiation(Class<?>, String)
+//**5.初始化后置处理器,上一步没有创建代理对象,则在这里创建代理对象()
+Object postProcessAfterInitialization(Object, String)
#//**创建代理对象()
#Object createProxy(Class<?>, String, Object[], TargetSource)
#//**获取bean配置的通知和顾问,需要子类实现()
#Object[] getAdvicesAndAdvisorsForBean(Class<?>, String, TargetSource)
#//**开放的钩子,允许用户对ProxyFactory进行自定义操作。暂无实现()
#void customizeProxyFactory(ProxyFactory)
#//**如果需要则创建代理,否则使用原始bean()
#Object wrapIfNecessary(Object, String, Object)
#//**是否应该跳过,不创建代理对象()
#boolean shouldSkip(Class<?>, String)
#//**是否强制使用cglib代理()
#boolean shouldProxyTargetClass(Class<?>, String)
#//**根据拦截器构建顾问()
#Advisor[] buildAdvisors(String, Object[])
-//**创建代理bean的class对象()
-Class~?~ createProxyClass(Class<?>, String?, Object[]?, TargetSource)
#//**根据拦截器解析顾问()
-Advisor[] resolveInterceptorNames()
-//**构建代理对象,创建代理对的主要逻辑()
-Object buildProxy(Class<?>, String?, Object[]?, TargetSource, boolean)
«Abstract»
AbstractAdvisorAutoProxyCreator
//**主要功能是获取标准的顾问Advisor,并找出可应用于指定bean的顾问
//**子类可实现extendAdvisors添加除了非标准顾问其它的准顾
- BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper //**检索标准Advisor的助手
#//**实现了此方法,委托findEligibleAdvisors找出可应用于指定bean的顾问()
#Object[] getAdvicesAndAdvisorsForBean(Class<?>, String, TargetSource)
#//**找出可应用于指定bean的顾问,主要逻辑在此()
#List~Advisor~ findEligibleAdvisors(Class<?>, String)
#//**获取所有标准的顾问Advisor()
#List~Advisor~ findCandidateAdvisors()
#//**从上面所有标准顾问Advisor中,找出可应用于指定bean的顾问()
#List~Advisor~ findAdvisorsThatCanApply(List<Advisor>, Class<?>, String)
#//**可过滤指定的标准顾问()
#boolean isEligibleAdvisorBean(String)
#//**可对指定bean的顾问列表排序()
#sortAdvisors(List<Advisor>)
#//**可扩展添加其它的顾问()
#extendAdvisors(List<Advisor>)
DefaultAdvisorAutoProxyCreator
//**默认的自动代理创建器
//**使用指定前缀过滤标准顾问
//**通常用于一个Advisor类有多个实例的场景
- boolean usePrefix //**是否使用前缀
- String advisorBeanNamePrefix //**前缀
#//**过滤bean名称不包含指定前缀的标准顾问()
#boolean isEligibleAdvisorBean(String)
InfrastructureAdvisorAutoProxyCreator
//**基础设施自动代理创建器
//**查找基础设施标准顾问
#//**过滤非ROLE_INFRASTRUCTURE的标准顾问()
#boolean isEligibleAdvisorBean(String)
AspectJAwareAdvisorAutoProxyCreator
//**AspectJ自动代理创建器
//**增加对AspectJ切面的支持
#//**添加DefaultPointcutAdvisor()
#void extendAdvisors(List<Advisor>)
#//**跳过AspectJPointcutAdvisor()
#boolean shouldSkip(Class<?>, String)
#**使用新的排序规则排序()
#List~Advisor~ sortAdvisors(List<Advisor>)
AnnotationAwareAspectJAutoProxyCreator
//**注解@AspectJ自动代理创建器
//**增加对@Aspect切面的支持
- List<Pattern> includePatterns
+//**支持配置全局正则过滤@AspectJ切面()
+void setIncludePatterns(List<String>)
#boolean isEligibleAspectBean(String)
#//**添加所有配置@AspectJ的顾问()
#List~Advisor~ findCandidateAdvisors()
核心类说明
A.ProxyConfig
代理配置类,提供了代理相关的配置属性。其中proxyTargetClass表示是否启用目标类代理,而不使用接口代理。目标类代理的实现方式是使用cglib代理;
B.ProxyProcessorSupport
代理创建器通用功能基类,提供一些工具方法;
- 1.用于classLoader管理;
- 2.计算原始类是否存在有效的接口(计算规则如下)。如果不存在有效的接口则设置proxyTargetClass=true;
//**1.接口的方法数量 > 1
ifc.getMethods().length > 0
//**2.非如下回调接口
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
//**3.非如下外部语言接口
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}
C.SmartInstantiationAwareBeanPostProcessor
智能实例化处理器,管理bean的生命周期;
D.AbstractAutoProxyCreator
自动代理创建器抽象类,创建代理对象的主要逻辑。获取原始bean的所有AdvicesAndAdvisors(通知和顾问),封装成ProxyFactory,然后创建动态代理bean代替原始bean。其中获取原始bean所有AdvicesAndAdvisors的方法getAdvicesAndAdvisorsForBean委托子类实现;
- 实现了SmartInstantiationAwareBeanPostProcessor的5个生命周期管理接口。用于在bean生命周期的各个阶段返回的是代理bean,而不是返回原始bean。SmartInstantiationAwareBeanPostProcessor以前介绍过,这里就不展开了;
//**springbean的生命周期管理的5个方法,创建bean动态代理的入口()
//**1.预测bean的class类型()
public Class<?> predictBeanType(Class<?>, String)
//**2.确定bean的class类型.创建代理的class对象()
public Class<?> determineBeanType(Class<?>, String)
//**3.获取提前暴露的bean引用,没有则创建代理对象()
public Object getEarlyBeanReference(Object, String)
//**4.实例化前置处理器.创建代理对象()
public Object postProcessBeforeInstantiation(Class<?>, String)
//**5.初始化后置处理器,上一步没有创建代理对象,则在这里创建代理对象()
public Object postProcessAfterInitialization(Object, String)
- 5个方法创建代理bean的的逻辑都差不多,我们重点看下postProcessBeforeInstantiation(实例化前置处理器):
核心逻辑就是查找原始bean是否需要代理,如果需要则获取所的AdvicesAndAdvisors(通知和顾问),并创建并返回代理对象,不需要则返回null;
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {\
//**获取缓存的key
Object cacheKey = getCacheKey(beanClass, beanName);
//**如果beanName为空 || 原始bean不能封装为TargetSource
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//**如果是重复处理的bean,不处理,直接返回空(advisedBeans缓存了已经处理过的bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//**如果是基础设置类 || 应该跳过,则不使用代理并返回空。并缓存在advisedBeans中
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
//**尝试把原始beab封装为TargetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
//**如果能封装为TargetSource
if (targetSource != null) {
//**缓存到targetSourcedBeans中
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//**获取原始bean的AdvicesAndAdvisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//**创建代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
//**缓存在proxyTypes中
this.proxyTypes.put(cacheKey, proxy.getClass());
//**返回代理对象
return proxy;
}
//**返回空
return null;
}
- 在看下创建代理的核心代码:
核心逻辑就是根据原始bean的class对象&名称&通知和顾问&TargetSource创建ProxyFactory对象。然后调用ProxyFactory的getProxy方法获取代理对象;
private Object buildProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource, boolean classOnly) {
//**如果beanFactory是ConfigurableListableBeanFactory,把原始类信息写到BeanDefinition的originalTargetClass属性中
if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
AutoProxyUtils.exposeTargetClass(clbf, beanName, beanClass);
}
//**创建ProxyFactory,并初始化基础配置
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//**虽然proxyTargetClass=true,但是原始bean是Proxy || 是Lambda,则仍然会使用jdk动态代理,需要配置接口
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
} else {
//**proxyTargetClass=false,但原始bean强制了使用目标类代理,则仍然需要设置proxyTargetClass=true
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {//**proxyTargetClass=false,如果原始bean存在有效的接口,则使用jdk动态代理,否则仍然使用目标类代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//**对通知和顾问进行处理和转换
//**1.添加常用的通知和顾问,并排序
//**2.如果是通知(advice),封装成顾问(Advisor),前面一直都是AdvicesAndAdvisors(通知和顾问),到这里时必须全部是Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
//**设置TargetSource
proxyFactory.setTargetSource(targetSource);
//**开放的钩子,允许用户对ProxyFactory进行自定义操作。暂无实现
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader smartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = smartClassLoader.getOriginalClassLoader();
}
//**调用ProxyFactory的getProxy方法获取代理对象
return (classOnly ? proxyFactory.getProxyClass(classLoader) : proxyFactory.getProxy(classLoader));
}
- 创建代理是ProxyFactory(AdvisedSupport的子类)实现的,我们会有专门的篇章介绍AdvisedSupport。这里先简单看一下创建代理的核心代码:
核心逻辑就是根据原始bean的的配置和代理的限制,选择为bean创建jdk接口代理还是cglib目标类代理;
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//**如果原始bean 需要优化 || proxyTargetClass=true || 没有有效的接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//**原则上满足上述条件是需要使用目标类代理的,但是原始bean是接口 || 是Proxy || 是Lambda,则仍然使用jdk动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//**使用目标类代理(cglib代理)
return new ObjenesisCglibAopProxy(config);
}
else {//**使用jdk动态代理
return new JdkDynamicAopProxy(config);
}
}
E.AbstractAdvisorAutoProxyCreator
自动代理创建器第二个抽象类,它的它的子类实现了getAdvicesAndAdvisorsForBean方法,负责检索原始bean的顾问和通知,并提供了一些方法扩展该功能;
- 实现的功能: 提供了查找标准顾问和通知的功能;
每个需使用代理实现的功能都会注册一个Advisor,比如声明式事物如下:
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//**注册名为org.springframework.transaction.config.internalTransactionAdvisor的Advisor
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
}
- 提供的扩展:
- 过滤isEligibleAdvisorBean(String)
- 排序sortAdvisors(List)
- 自定义extendAdvisors(List)
//**扩展的调用逻辑
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//**查找所有类型为Advisor的bean,会调用isEligibleAdvisorBean过滤
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//**从上面所有标准顾问Advisor中,找出可应用于原始定bean的顾问
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//**添加自定义的Advisor
extendAdvisors(eligibleAdvisors);
//**排序,执行时会按照此顺序执行
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
F.DefaultAdvisorAutoProxyCreator
默认的自动代理创建器。重写了isEligibleAdvisorBean(String),支持使用指定前缀过滤标准顾问,通常用于一个Advisor类有多个实例的场景。实际上很少会使用;
//**只支持使用这3个自动代理创建器
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
G.InfrastructureAdvisorAutoProxyCreator
基础设施自动代理创建器。重写了isEligibleAdvisorBean(String),会过滤掉BeanDefinition中role!=ROLE_INFRASTRUCTURE的Advisor。通常Spring自带的标准功能会注册InfrastructureAdvisorAutoProxyCreator,如@EnableTransactionManagement和@EnableCaching等;
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
H.AspectJAwareAdvisorAutoProxyCreator
AspectJ自动代理创建器。重写了extendAdvisors(List)和sortAdvisors(List),对AspectJ切面进行支持;
- 重写sortAdvisors(List),支持对AspectJ调用排序;
- 如果A和B在不同的切面中定义,那么优先级是由切面的order值决定;
- 如果A和B在同一个切面中定义:
- 如果A或B是后置通知(after advice),那么后声明的通知具有高优先级;
- 如果A和B都不是后置通知,那么先声明的通知具有高优先级;
- 重写extendAdvisors(List),添加ExposeInvocationInterceptor到首位,以暴露AspectJ调用上下文;
//**如果包含AspectJ相关的Advice/Advisor,则自动添加DefaultPointcutAdvisor,并且添加到首位
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) { is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}
I.AnnotationAwareAspectJAutoProxyCreator
AspectJ注解自动代理创建器,重写了findCandidateAdvisors(),查找AspectJ配置,支持@Aspect注解切面。支持配置全局正则过滤@AspectJ切面;
- 查找AspectJ配置bean的核心代码:
核心逻辑就是查找所有的bean,然后判断是否匹配全局正则,是否为AspectJ相关的bean,符合条件则封装为Advisor对象,添加到Advisor列表;
如何区分AspectJ相关的bean: AnnotationUtils.findAnnotation(clazz, Aspect.class) != null && !compiledByAjc(clazz);包含@Aspect注解,并且不是ajc编译器编译(compiledByAjc是一个编译时生成的标志,当类被AspectJ 编译器织入切面时,会在类文件的元数据中添加这个标志。这个标志的存在表明该类已经被AspectJ处理,切面代码已经被织入到类中。);
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//**查找所有的bean
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {//**全局正则过滤
continue;
}
//**获取bean的class对象
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
//**如果bean的类型为AspectJ类型(AnnotationUtils.findAnnotation(clazz, Aspect.class) != null)
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//**把标注@Aspect的bean封装成Advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
//**缓存起来,如果bean的作用域为单例,则直接缓存Advisor对象,否则缓存创建Advisor的工厂(后续用缓存的工厂创建实例)
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
...
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
- 根据AspectJ配置创建Advisor的核心代码:
先查找AspectJ配置的方法,然后获取Pointcut,最后创建Advisor实例(InstantiationModelAwarePointcutAdvisorImpl);
//**1.查找AspectJ方法的逻辑,查找标注@Aspect注解的bean中不包修@Pointcut的方法
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
.and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
//**2.获取Pointcut的逻辑,查找上一步结果的方法中的如下注解
Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//**3.创建Advisor实例的逻辑,根据上面两步获取方法和Pointcut创建Advisor
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//**创建了Advisor的子类InstantiationModelAwarePointcutAdvisorImpl
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
- 创建Advice的核心代码:
Advice才是真正添加的额外逻辑,Advisor只是对Advice的封装。最终切面的方法会转换为Advice,看下转换的核心逻辑;
//**根据通知的类型,创建对应的通知对象
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut -> {
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
}
//**创建环绕通知
case AtAround -> springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
//**创建前置通知
case AtBefore -> springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
//**创建后置通知
case AtAfter -> springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
case AtAfterReturning -> {
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
}
case AtAfterThrowing -> {
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
}
default -> throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
`