一、从@EnableAspectJAutoProxy开始
要使用Spring 的 AOP功能,就得先开启该功能,在注解式开发中,该功能的开关就是@EnableAspectJAutoProxy,我们先来看看这个注解的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
// ① 导入了一个AspectJAutoProxyRegistrar
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
可以看到①使用了@Import导入了一个AspectJAutoProxyRegistrar类,我们再点进去看看它是个什么
//①
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
//importingClassMetadata 标有@import注解的类的元信息
//BeanDefinitionRegistry 其他bean定义的注册表
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// ② 如果有需要则注册AspectJAnnotationAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//获取@EnableAspectJAutoProxy注解的属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
// 强制使用CGLIB
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//是否暴露被代理后的bean到AopContext中,详见该注解属性的用法
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
可以看到AspectJAutoProxyRegistrar是一个ImportBeanDefinitionRegistrar(import注解的bean定义导入器,用来手动注册bean定义信息,在Spring的复习笔记中也提到过)。接下来观察下它的源码,非常明显②是最关键的。
//如果有需要则注册AspectJAnnotationAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
进去看看,下面AutoProxyCreator(自动代理创建器)简称Apc,
// ① Apc的bean名称,该bean名称将在后面的源码分析中经常出现
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
//往下一层调用
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
// ② 往下一层调用,按需要注册或者升级Apc,这里我们需要注册AnnotationAwareAspectJAutoProxyCreator(注解版Apc)
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//判断bean注册表中是否有Apc,我们这里只用了注解的AOP且程序第一次启动,所以容器中没有其他的Apc
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//若有则取出,并与我们传进来的AspectJAnnotationAutoProxyCreator比较优先级,取优先级较高的Apc
//有哪些Apc可以具体点进findPriorityForClass方法查看
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;
}
// ③ 创建 注解版Apc的bean定义
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
// TODO 设置bean定义的一些属性
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 向bean定义注册表中 注册了 注解版Apc
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
结合①②③,我们可以总结出,在我们这个例子中@EnableAspectJAutoProxy实际作用就是往bean定义注册表中注册了AnnotationAwareAspectJAutoProxyCreator(注解版Apc)的bean定义信息。
对于一个类,我们可以观察的它的继承体系来快速了解它的基本作用,我们观察下注解版Apc的继承体系
关注红框部分,在之前的复习笔记中得知,注解版Apc不仅能够Aware(感知)BeanFactory和BeanClassLoader还是一个BeanPostProcess能够处理其他bean在初始化前后的一些逻辑。不仅如此,我们可以发现它还是个InstantiationAwareBeanPostProcess,观察这个接口定义的方法,不能判断出它可以处理bean在实例化前后的逻辑,这使 bean的生命周期变得更加灵活。在之后的笔记中,我们再来分析注解版Apc是如何实现这些接口的,实现方法中又做了哪些事情。