3.springboot创建代理

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);
}
`
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值