本文介绍配置切面后,动态代理创建器自动创建动态代理的过程。有些名称先统一,可先看看前一篇:
原始bean: 需要被动态代理的对象,一般是我们用户编写的java类;
代理bean: spring为原始bean创建的代理对象,可在执行原始bean的方法时,添加额外的逻辑;
Advice: 通知,代理bean为原始bean添加的额外执行逻辑。一个Advice处理一种逻辑,比如事务注解和缓存注解会有两个Advice;
Advisor: 顾问,是对Advice(通知)的封装,通常内部会持有一个Advice对象;
代理方式 | 实现方式 |
---|---|
接口代理 | jdk动态代理 |
目标类代理 | cglib动态代理 |
代理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)) |
类体系分成两部分:
代理配置类,提供了代理相关的配置属性。其中proxyTargetClass表示是否启用目标类代理,而不使用接口代理。目标类代理的实现方式是使用cglib代理;
代理创建器通用功能基类,提供一些工具方法;
//**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"));
}
智能实例化处理器,管理bean的生命周期;
自动代理创建器抽象类,创建代理对象的主要逻辑。获取原始bean的所有AdvicesAndAdvisors(通知和顾问),封装成ProxyFactory,然后创建动态代理bean代替原始bean。其中获取原始bean所有AdvicesAndAdvisors的方法getAdvicesAndAdvisorsForBean委托子类实现;
//**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)
@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;
}
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));
}
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);
}
}
自动代理创建器第二个抽象类,它的它的子类实现了getAdvicesAndAdvisorsForBean方法,负责检索原始bean的顾问和通知,并提供了一些方法扩展该功能;
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;
}
}
//**扩展的调用逻辑
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;
}
默认的自动代理创建器。重写了isEligibleAdvisorBean(String),支持使用指定前缀过滤标准顾问,通常用于一个Advisor类有多个实例的场景。实际上很少会使用;
//**只支持使用这3个自动代理创建器
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
基础设施自动代理创建器。重写了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);
}
AspectJ自动代理创建器。重写了extendAdvisors(List)和sortAdvisors(List),对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;
}
AspectJ注解自动代理创建器,重写了findCandidateAdvisors(),查找AspectJ配置,支持@Aspect注解切面。支持配置全局正则过滤@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;
}
//**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);
}
//**根据通知的类型,创建对应的通知对象
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);
}
`