文章目录
1 简诉
spring-aop的核心原理用一句概况,我觉得可以是:
在目标业务bean创建+初始化过程中spring利用
动态代理机制
对原始的业务bean进行了增强。
通过前面几篇文章的铺垫,其实应该比较容易想到,具体的执行者肯定就是后置处理器(BeanPostProcessor),这里对应的后置处理器在spring中的
- bean name为
org.springframework.aop.config.internalAutoProxyCreator
- 具体的实体类对象为AnnotationAwareAspectJAutoProxyCreator。
当然internalAutoProxyCreator既然是对目标对象进行增强的处理器,那它肯定在目标对象创建之前就已经存在于spring的IOC容器了,本篇文章将主要来探索一下该对象是如何被率先注入到IOC容器的。
2 internalAutoProxyCreator的注册
在《【Spring - AOP】— AOP使用简介》这篇文章里讲到,要想开启Spring的AOP功能,必须在配置类中加上@EnableAspectJAutoProxy
注解,下面为该注解的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) //比较重要的一个注解
public @interface EnableAspectJAutoProxy {
//true强制使用CGLIB代理,false非强制
boolean proxyTargetClass() default false;
//是否暴露被代理的类
boolean exposeProxy() default false;
}
通过EnableAspectJAutoProxy源码,可以看到一个比较重要的注解@Import(AspectJAutoProxyRegistrar.class)
,其实在《【Spring注解】@Import》那篇文章里就已经介绍过@Import注解是框架源码中经常用到的一个向IOC容器中注入bean的注解 — internalAutoProxyCreator的注册正是通过该注解完成的。跟进AspectJAutoProxyRegistrar源码:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//真正注册internalAutoProxyCreator的代码
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//省略N行
}
可以看到它是用了实现ImportBeanDefinitionRegistrar接口的方式进行bean的注册 — 在《【Spring注解】@Import》也讲到过。接着跟进代码,可以看到如下两个比较重要的方法
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//第一个参数为AnnotationAwareAspectJAutoProxyCreator的类型
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
//实际进行internalAutoProxyCreator注册的方法
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//先去看注册中心registry里是否已经有internalAutoProxyCreator的定义了
//注意:AUTO_PROXY_CREATOR_BEAN_NAME其实就是org.springframework.aop.config.internalAutoProxyCreator
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;
}
//利用AnnotationAwareAspectJAutoProxyCreator的class类型新建RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
//向beanDefinition对象中加入其它一些属性
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//将新定义的beanDefinition注入到注册中心
//注意:AUTO_PROXY_CREATOR_BEAN_NAME其实就是org.springframework.aop.config.internalAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
对比《【Spring注解】@Import》那篇文章可知,上面方法中最终要的就是利用给定的类型AnnotationAwareAspectJAutoProxyCreator.class新建一个RootBeanDefinition 对象,并将该对象注入到注册中心,这样spring就会在启动时将该对象注入到IOC容器中。
3 internalAutoProxyCreator的继承关系
在了解了internalAutoProxyCreator的注册机制之后,接下来看一下internalAutoProxyCreator的继承关系,其继承关系图如下。接下来我会在internalAutoProxyCreator的创建+初始化过程中对图中标注的三点进行稍微比较细致的讲解。
4 internalAutoProxyCreator创建+初始化过程
4.1 入口refresh()方法
无论是BeanPostProcessor还是业务bean的创建入口都是AbstractApplicationContext类中的refresh()方法,下面仅展示了processor注册(或者也可以叫做定义)、processor创建+初始化和业务bean创建+初始化的代码:
//调用processor的注册方法 -> 本文第2部分将internalAutoProxyCreator注册到注册中心就是这里进行调用的
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // 对应源代码528行
//processor的创建+初始化
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); //对应源代码531行
//省略N行代码
//其他普通单实例bean的创建+初始化 -> 如我们的业务bean
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//对应源码546行
4.2 跟进processor创建+初始化的源码
跟进去registerBeanPostProcessors,可以看到会进一步进入到public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext)
方法,该方法的关键逻辑如下:
4.3 internalAutoProxyCreator初始化过程中BeanFactoryAware的作用时机
之前的文章如《【bean的生命周期】— 对象创建+初始化流程分析 — 【重点@Autowired的作用时机】》在讲单实例bean的初始化过程即下面方法的具体实现时,只讲到了前置处理、bean的初始化和后置处理器如下图。
exposedObject = initializeBean(beanName, exposedObject, mbd);
但实际上initializeBean方法的具体实现类里在前置处理器之前还有一个方法:
invokeAwareMethods(beanName, bean);
跟进该方法的源码:
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
//如实现了BeanNameAware将bean在IOC容器中的beanname给当前bean
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
//如实现了BeanClassLoaderAware将ClassLoader给当前bean
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//如实现了BeanFactoryAware将BeanFactory给当前bean
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
可以看到,其实很简单,就是判断当前bean是否实现了上面三个Aware,如果实现了,就将相应的内容给到当前bean。看到这里肯定就会明白为什么我会在《真实工作中经常用到的Aware使用简介》那篇文章的代码注释里写 BeanNameAware接口的调用逻辑会在前置处理器applyBeanPostProcessorsBeforeInitialization方法之前
了。