由于md文档部分hugo插件语法不兼容,建议访问作者网站查阅文章:wlizhi.cc
spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi/spring-framework 。
链接中源码是作者从 github 下载,并以自身理解对核心流程及主要节点做了详细的中文注释。
1 AOP入口
AOP是通过 BeanPostProcessor.postProcessAfterInitialization() 实现的,来到 doCreateBean() -> initializeBean(),在初始化方法执行完成后,会调用 applyBeanPostProcessorsAfterInitialization(),这里循环调用了所有 BeanPostProcessor 的 postProcessAfterInitialization(),AOP 的入口就在其中的一个实现类,也是 AbstractAutoProxyCreator 的子类实现。
要看代理对象的生成过程,首先要看支持这个功能的类,是在哪里注册的,它源自哪里?
2 XMl配置方式BeanPostProcessor的注册
XMl方式注入AOP支持的BeanPostProcessor,是通过 <aop:aspectj-autoproxy/>
标签注入的。
根据SPI加载规则,找到 spring-aop 模块下的 META-INF/spring.handlers 文件。
可以看到以下内容:
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
来到 AopNamespaceHandler 类,源码如下:
public class AopNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
// AspectJAutoProxyBeanDefinitionParser标签 <aop:aspectj-autoproxy/> 的支持,
// 在其 parse() 中注册了AOP的入口类 AnnotationAwareAspectJAutoProxyCreator,是一个 BeanPostProcessor
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
我们在使用Spring XML配置方式使用 <aop:aspectj-autoproxy/>
标签激活代理,在 init() 中注册了 aspectj-autoproxy
属性的解析类,在这个解析类中,注入了 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition。
源码如下:
步骤一:
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 对aspectj-autoproxy属性的支持
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
// 添加IncludePatterns
extendBeanDefinition(element, parserContext);
return null;
}
}
步骤二:
public abstract class AopNamespaceUtils {
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
// 这里注册了AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
}
步骤三:
public abstract class AopConfigUtils {
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
}
可以看到,步骤三中,最后 return
语句后注册了 AnnotationAwareAspectJAutoProxyCreator。
{{< admonition type=“info” title=“信息” open=true >}}
回顾:BeanPostProcessor 提前注册到IOC容器的流程。
- 创建 BeanFactory,完成所有 BeanDefinition 的搜集。
- 执行 invokeBeanFactoryPostProcessors()(BeanDefinition的后置处理)。BeanFactoryPostProcessor 及子接口 BeanDefinitionRegistryPostProcessor 实现类的方法。
- 执行 registerBeanPostProcessors。从 beanFactory 中获取所有的 BeanPostProcessor,优先进行 getBean() 操作,实例化。
{{< /admonition >}}
3 注解方式BeanPostProcessor的注册
3.1 注解方式案例
先看一个案例:
- 切面类:
@Component @Aspect @Slf4j
public class CustomAspect {
@Pointcut("execution(* top.wlz922.aspect.*.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void before(){
log.info("CustomAspect.before execute...");
}
}
- 业务类:
@Component
@Slf4j
public class Apple {
public void showTaste(){
log.info("Apple is sour and sweet.");
}
}
- 配置类:
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "top.wlz922")
public class AspectAnoConfiguration {
}
- 测试类:
@Slf4j
public class ApplicationContextTest {
@Test
public void testAnoAop(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectAnoConfiguration.class);
Apple apple = context.getBean(Apple.class);
apple.showTaste();
}
}
执行结果:
12:23:34.294 [main] INFO top.wlz922.aspect.CustomAspect 16 - CustomAspect.before execute...
12:23:34.325 [main] INFO top.wlz922.aspect.Apple 10 - Apple is sour and sweet.
以上是一个简单的注解方式激活AOP功能的案例。
3.2 AspectJAutoProxyRegistrar的注册
下面来看注解方式,注入对应支持的 BeanPostProcessor 的入口。
这是 @EnableAspectJAutoProxy 的声明:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
可以看到,@EnableAspectJAutoProxy 上有一个 @Import,那么它在创建 BeanFactory,扫描注册 BeanDefinition 时,会把 AspectJAutoProxyRegistrar 类包装为 BeanDefinition 注册到容器中。
看 AspectJAutoProxyRegistrar 的声明:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// TODO 注册自动代理的支持类的BeanDefinition到容器中。
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
// 如果激活了自动代理,这里会设置AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对应的属性值
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
来到 registerAspectJAnnotationAutoProxyCreatorIfNecessary():
public abstract class AopConfigUtils {
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
}
可以看到,在这里对 AnnotationAwareAspectJAutoProxyCreator 进行了注册。
具体的注册逻辑源码(注意参数的传递):
public abstract class AopConfigUtils {
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
// 前面注册的类没用,注册不进来,这里会根据等级返回BeanDefinition,注解方式会返回AnnotationAwareAspectJAutoProxyCreator
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// 这里会有一个比较,在注册AbstractAdvisorAutoProxyCreator时,会有一个优先级。
// 如果这里已经注册过AbstractAdvisorAutoProxyCreator,在此注册的时候,
// 会与之前的注册的进行优先级比较,优先级高的会覆盖掉优先级低的。注解的优先级最高。
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 创建BeanDefinition,并设置一些属性。
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册到BeanDefinitionRegistry
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
}
首先这里会判断容器中是否包含指定名称的 BeanDefinition,如果包含,拿这次将要注册的类型与已存在的类型进行优先级比对,以优先级高的为准进行 BeanDefinition 的注册。
看一下获取优先级的代码:
public abstract class AopConfigUtils {
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
static {
// 这里默认包含三个代理生成类
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
private static int findPriorityForClass(@Nullable String className) {
for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
Class<?> clazz = APC_PRIORITY_LIST.get(i);
if (clazz.getName().equals(className)) {
return i;
}
}
throw new IllegalArgumentException(
"Class name [" + className + "] is not a known auto-proxy creator class");
}
}
在 AopConfigUtils 静态代码块中,初始化了三个 BeanPostProcessor 的实现,按照在 list 容器中的索引大小来确定优先级。优先级大小顺序为:
AnnotationAwareAspectJAutoProxyCreator > AspectJAwareAdvisorAutoProxyCreator > InfrastructureAdvisorAutoProxyCreator