本系列文章将从@EnableAspectJAutoProxy注解入手分析spring aop的核心原理:
- 使用@EnableAspectJAutoProxy注解的效果
- AnnotationAwareAspectJAutoProxyCreator后置处理器的引入
- AnnotationAwareAspectJAutoProxyCreator匹配切入点、创建通知、创建bean代理的原理
- AOP通知的执行原理
本系列文章基于spring.5.2.12.RELEASE版本,springboot使用的应该是org.springframework.boot.autoconfigure.aop.AopAutoConfiguration自动装配方式,本文暂不讨论,原理上也是一样的。
本文将从@EnableAspectJAutoProxy注解,看一下AnnotationAwareAspectJAutoProxyCreator后置处理器是如何注入到spring中的。
@EnableAspectJAutoProxy注解
spring aop是通过@EnableAspectJAutoProxy注解开启的,我们先看一下使用该注解前后spring容器的区别。
使用前:
使用后:
可以看到使用@EnableAspectJAutoProxy注解之后spring多注入了一个叫做AnnotationAwareAspectJAutoProxyCreator的beanPostProcessor处理器。
本文就将分析这个后置处理器是如何注入到spring容器的。
AspectJAutoProxyRegistrar注册AnnotationAwareAspectJAutoProxyCreator后置处理器
我们看一下@EnableAspectJAutoProxy注解的源码,他import了一个AspectJAutoProxyRegistrar组件:
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a ThreadLocal
* for retrieval via the AopContext class.
*/
boolean exposeProxy() default false;
AspectJAutoProxyRegistrar将向容器中注入AnnotationAwareAspectJAutoProxyCreator后置处理器:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注入AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// other code
}
}
那么这个方法是什么时候调用的?
debug一下可以发现几个比较重要的方法:
上方的红框标注的方法在ConfigurationClassPostProcessor类,用于从config配置类解析出bean definition并将其注册到容器。
下方的红框标注的方法在AbstractApplicationContext类,用于调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor处理器。
invokeBeanFactoryPostProcessors方法
AbstractApplicationContext的refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors方法
Instantiate and invoke all registered BeanFactoryPostProcessor beans, respecting explicit order if given. Must be called before singleton instantiation.
实例化并调用所有注册的BeanFactoryPostProcessor bean,如果指定顺序,则遵循显式顺序。必须在单例实例化之前调用。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate
.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime.
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法中会先调用所有的BeanDefinitionRegistryPostProcessor处理器:
// currentRegistryProcessors是一个BeanDefinitionRegistryPostProcessor集
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
此时里面只有一个ConfigurationClassPostProcessor处理器,他是在容器初始化最开始时注册的,暂时不做分析。
看一下invokeBeanDefinitionRegistryPostProcessors方法:
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors,
BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry实现
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
processConfigBeanDefinitions(registry);
}
processConfigBeanDefinitions中有这样一段逻辑:
- 使用ConfigurationClassParser从容器里面解析configurationModel集
- 然后从configurationModel集解析import的bean definition
解析config配置类
// ...
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
parser.parse(candidates);
parser.validate();
// 解析出configurationModel集
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 解析import的beanDefinition
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
// ...
parser.parse(candidates)中有解析配置类导入ImportBeanDefinitionRegistrar的逻辑:
protected void processConfigurationClass(
ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 省略
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 解析配置类
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
// 中间代码省略,只记录重要的内容
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
// 省略
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// 省略
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// 这个分支解析ImportBeanDefinitionRegistrar
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
// 在本例中,解析出来的是AspectJAutoProxyRegistrar类
Class<?> candidateClass = candidate.loadClass();
// 这里就是把AspectJAutoProxyRegistrar实例化
ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils
.instantiateClass(candidateClass,
ImportBeanDefinitionRegistrar.class,
this.environment,
this.resourceLoader,
this.registry);
// 添加configClass里面以便后续使用
configClass
.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// 省略
}
}
}
}
}
reader.loadBeanDefinitions(configClasses)
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 判断配置是否跳过
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 从ImportBeanDefinitionRegistrar导入BeanDefinition
// configClass的importBeanDefinitionRegistrars已经在之前的逻辑中介绍了
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsFromRegistrars(
Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
// 在此处就调用了AspectJAutoProxyRegistrar的registerBeanDefinitions方法
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}
到此就已经把AnnotationAwareAspectJAutoProxyCreator后置处理器注册到了spring容器的BeanDefinition中。
后续还需要把BeanPostProcessor从BeanDefinition中找出来,实例化并添加到beanPostProcessors集,以便后续使用。
registerBeanPostProcessors方法
这个方法很简单,就是将容器里面的BeanPostProcessor找出来,做优先级匹配、排序等,然后进行初始化,注入到容器里面。
代码就不记录了。
下一篇文章将介绍AnnotationAwareAspectJAutoProxyCreator的工作:
- 切入点的匹配
- 通知创建
- 代理创建