⑤invokeBeanFactoryPostProcessors()
先说明:invokeBeanFactoryPostProcessors()是在refresh()方法中的第⑤步,他的作用是注册bean的定义信息,但还没进行创建实例。我们下面介绍了注解@EnableAspectJAutoProxy就是在这个阶段注册一个bean定义,但实例化要推迟到第⑥步registerBeanPostProcessor()完成
@EnableAspectJAutoProxy
@EnableAspectJAutoProxy
的作用是给spring容器中注册一个bean:这个bean名为internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator.class “注册装配模式的切面自动代理创建器”另外可以注意,是在
invokeBeanFactoryPostProcessors()
阶段进来调用注册的
@EnableAspectJAutoProxy标准在配置类上,在EnableAspectJAutoProxy接口类上有@Import(AspectJAutoProxyRegistrar.class)
,该@Import给容器中导入了AspectJAutoProxyRegistrar这个bean,而这个bean作用是手动注册bean定义到ac容器中。
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({
AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
// 用于强制使用cglib动态代理,即使实现了接口。
// 如果希望强制使用CGLIB代理(例如希望代理目标对象的所有方法,而不只是实现自接口的方法)// 但需要保证有CGLIB包
boolean proxyTargetClass() default false;
// 事务中会用到 // 是否暴露代理对象,暴露出来的代理对象和线程绑定,用的是threadLocal // 设置为true之后还得用(AopContext.currentProxy()).被调方法() 替换原来的 被调方法()
// 比如切入点表达式是save方法,saveAll方法没在切入点表达式里,saveAll调用了save方法,此时调用saveAll方法并不执行save的AOP方法//走save的时候该轮到增强的事情已经过去了//AopContext.currentProxy()获取代理对象
boolean exposeProxy() default false;
}
exposeProxy解释:
public interface UserService{ public void a(); public void a(); } public class UserServiceImpl implements UserService{ @Transactional(propagation = Propagation.REQUIRED) public void a(){ this.b(); } @Transactional(propagation = Propagation.REQUIRED_NEW) public void b(){ System.out.println("b has been called"); } } 代码参照《Spring源码解析》p173页。 Q1:b中的事务会不会生效? A1:不会,a的事务会生效,b中不会有事务,因为a中调用b属于内部调用,没有通过代理,所以不会有事务产生。 Q2:如果想要b中有事务存在,要如何做? A2:<aop:aspectj-autoproxy expose-proxy=“true”> ,设置expose-proxy属性为true,将代理暴露出来,使用AopContext.currentProxy()获取当前代理,将this.b()改为((UserService)AopContext.currentProxy()).b()
Import(AspectJAutoProxyRegistrar)
而注解驱动里的知识告诉我们@Import与实现ImportBeanDefinitionRegistrar接口的类注册bean的用法,这时@Import就会调用这个类的
registerBeanDefinitions()
方法,(可以在这个方法上打断点)
class AspectJAutoProxyRegistrar
implements ImportBeanDefinitionRegistrar {
// 实现该接口的话会自动调用registerBeanDefinitions()方法
@Override
public void registerBeanDefinitions(//注册bean定义,而不是注册bean实例
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
//bean定义注册器
// 去注册bean // 如有必要就注册AspectJ注解自动代理创建器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 拿到注解@EnableAspectJAutoProxy注解的属性信息,proxyTargetClass、exposeProxy
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, //当前类的元数据
EnableAspectJAutoProxy.class);// 哪个注解
// 如果拿到了注解信息
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
...;
}
//==========多次重载跳到===============================
public abstract class AopConfigUtils {
// 注册类
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, //AnnotationAwareAspectJAutoProxyCreator.class
BeanDefinitionRegistry registry, //注册器
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 如果bean定义存在了
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// else 如果该bean定义不存在
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);//AnnotationAwareAspectJAutoProxyCreator.class
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册bean定义
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
比如现在我们有个逻辑(有红蓝色颜料就能造出彩虹),该方法可以通过
registry.containsBeanDefinition("com.atguigu.bean.MyRed");
判断容器中是否有了对应的红bean(的定义信息),同理还判断有没有蓝bean定义,如红蓝bean定义信息都有,就创建一个彩虹BeanDefinition定义信息,:new RootBeanDefinition(RainBow.class);
,然后注册bean定义信息到容器中:registry.registerBeanDefinition("rainBow", beanDefinition);
从而创建bean的时候工厂容器就知道要创建哪些bean了。
也就是说:@Import(AspectJAutoProxyRegistrar)的作用的注册一个bean定义信息:这个bean名为internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator.class
AnnotationAwareAspectJAutoProxyCreator
“org.springframework.aop.config.internalAutoProxyCreator”
上面说了:AspectJAutoProxyRegistrar的作用的注册一个bean:internalAutoProxyCreator
。而internalAutoProxyCreator是bean name,对应的值是类AnnotationAwareAspectJAutoProxyCreator
(注解装配方式的切面自动代理创建器)。他是一个后置处理器。AnnotationAwareAspectJAutoProxyCreator的继承关系如下:
类继承关系
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
}
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
}
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
}
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
}
总结关系如下:
---AnnotationAwareAspectJAutoProxyCreator
------AnnotationAwareAspectJAutoProxyCreator
--------->AspectJAwareAdvisorAutoProxyCreator
------------>AbstractAdvisorAutoProxyCreator
--------------->AbstractAutoProxyCreator
------------------>BeanFactoryAware //(这个接口可以把bean工厂拿到)
------------------>SmartInstantiationAwareBeanPostProcessor //(注意这个)
---------------------->InstantiationAwareBeanPostProcessor
-------------------------->BeanPostProcessor
每个类的作用:
==父类-->子类
=====AbstractAutoProxyCreator======
public void setBeanFactory(BeanFactory beanFactory) {
}
public boolean postProcessBeforeInstantiation();
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
}
=====AbstractAdvisorAutoProxyCreator========;
public void setBeanFactory(BeanFactory beanFactory);{
initBeanFactory((ConfigurableListableBeanFactory)beanFactory);}//子类重写了setBeanFactory方法//refresh(){registerBeanPostProcessor(){这里调用了set方法}}
========AspectJAwareAdvisorAutoProxyCreator===========;
========AnnotationAwareAspectJAutoProxyCreator====;
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}//前面的setBeanFactory调用了该方法,这里重写了
如果想了解xml方式的AspectJAwareAdvisorAutoProxyCreator是如何注入到容器的,可以参考https://blog.csdn.net/qq_26323323/article/details/81012855
第⑤部分更多的内容我们放后面点拓展部分再讲
AnnotationAwareAspectJAutoProxyCreator注册时机
这里说下流程,具体步骤可以看后文的附录的⑤
main方法
invokeBeanFactoryPostPostProcessors() 注册bean工厂的后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
遍历所有所有bean工厂后置处理器,依次实例化工厂后置处理器,然后依次调用他们里面重写了的registerBeanDefinitions方法
refresh();
invokeBeanFactoryPostProcessors(beanFactory);
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
postProcessor.postProcessBeanDefinitionRegistry(registry);//
processConfigBeanDefinitions(registry);
this.reader.loadBeanDefinitions(configClasses);//ConfigurationClassPostProcessor.java
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);//此处的变量内容如下图 //并不是每个configModel都会走这个方法
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 这个方法就是我们之前看过的
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
//jdk动态代理还是CGLIB动态代理
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
//暴露代理对象
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);//就是给bean定义中添加一个属性是exposeProxy
}
}
}