- refresh--> invokeBeanFactoryPostProcessors
- PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法
- PostProcessorRegistrationDelegate的invokeBeanDefinitionRegistryPostProcessors方法
- ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
- ConfigurationClassPostProcessor的processConfigBeanDefinitions方法
- ConfigurationClassParser的parse方法
- ConfigurationClassParser的processConfigurationClass方法
- ConfigurationClassParser的doProcessConfigurationClass方法
- ConfigurationClassParser的processImports方法---处理@Import注解的方法
- ConfigurationClassBeanDefinitionReader的loadBeanDefinitions方法
- ConfigurationClassBeanDefinitionReader的loadBeanDefinitionsForConfigurationClass方法
- ConfigurationClassBeanDefinitionReader的loadBeanDefinitionsFromRegistrars方法
- AspectJAutoProxyRegistrar的loadBeanDefinitionsFromRegistrars方法---圆回来了
环境搭建
代码语言:javascript复制@Slf4j
@Component
public class Bean {
public String say(){
log.info("bean's say method is invoke");
return "say";
}
public String eat(){
log.info("bean's eat method is invoke");
return "eat";
}
}
代码语言:javascript复制@Aspect
@Slf4j
public class LogAspect {
@Pointcut("execution(* org.aop.MyBean.*(..))")
public void point(){}
@Before("point()")
public void beforeLog(){
log.info("方法执行,当前时间: " System.currentTimeMillis());
}
@AfterReturning("point()")
public void afterReturning(){
log.info("获取方法返回结果后,当前时间: " System.currentTimeMillis());
}
@After("point()")
public void after(){
log.info("方法执行完毕后,当前时间: " System.currentTimeMillis());
}
@Around("point()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long end = System.currentTimeMillis();
log.info("方法执行时间为 {} ms",end-start);
log.info("-------------------------------------");
return proceed;
}
}
代码语言:javascript复制@EnableAspectJAutoProxy
@Configuration
public class MyConfiguration {
@Bean(name = "bean")
public MyBean bean(){
return new MyBean();
}
@Bean
public LogAspect logAspect(){
return new LogAspect();
}
}
代码语言:javascript复制public class AopMain {
public static void main(String[] args) {
//AnnotationConfigApplicationContext会自动向容器中注册三个常用后置处理器
//ConfigurationAnnotationProcessor
//AutowiredAnnotationProcessor
//CommonAnnotationProcessor
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean bean = (MyBean)applicationContext.getBean("bean");
bean.say();
bean.eat();
}
}
Spring启用注解式aop的两种方式
Spring启用注解式aop支持有两种方式:
- XML方式
<aop:aspectj-autoproxy/>
- 注解方式
@EnableAspectJAutoProxy
我们下面先依次分析一下,这两种方式是如何通过不同的方式,来启用的注解式aop功能
xml方式–< aop:aspectj-autoproxy/ >
下面这篇文章讲过spring的标签解析过程,aop:aspectj-autoproxy严格来说属于自定义标签,
spring默认和自定义标签的解析过程
代码语言:javascript复制< aop:aspectj-autoproxy/ >
不属于spring的默认标签,也算自定义标签的行列,因此我们来回顾一下自定义标签的解析过程是什么样子的:
既然是自定义标签,那么对应就需要有一个自定义命名空间的解析器—即NameSpaceHandler,而spring-aop给aop的自定义命名空间,提供一个AopNameSpaceHandler,负责解析aop:开头的命名空间。
代码语言:javascript复制public class AopNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// In 2.0 XSD as well as in 2.5 XSDs
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace in 2.5
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
可以看到这里是注册了一些解析器来解析aop标签的,这里我们最关心的是下面这行代码:
代码语言:javascript复制 registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
显然AspectJAutoProxyBeanDefinitionParser是用来解析aop:aspectj-autoproxy这个标签的,下面看一下他的parse方法做了什么事情
,因为当spring解析到这个标签的时候,会定位到AspectJAutoProxyBeanDefinitionParser,然后调用其parse方法进行解析
AspectJAutoProxyBeanDefinitionParser —专门解析aop:aspectj-autoproxy标签
代码语言:javascript复制class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册AspectJAnnotationAutoProxyCreator
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//对于注解中子类的处理
extendBeanDefinition(element, parserContext);
return null;
}
...
}
AopNamespaceUtils—处理xml形式的aop命名空间工具类
下面来看一下AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法:
代码语言:javascript复制 public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary是重点
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//检查标签上的proxy-target-class属性是否为true,如果为true的话会强制使用cglib完成代理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册组件并通知监听器
registerComponentIfNecessary(beanDefinition, parserContext);
}
AopNamespaceUtils的useClassProxyingIfNecessary
代码语言:javascript复制 private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
//拿到标签上的proxy-target-class属性
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
//强制使用cglib代理
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//拿到exposeProxy属性
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
//强制将代理bean暴露到aopcontext中去
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary–注册自动代理创建器
代码语言:javascript复制 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//注册还是对代理创建器进行升级
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
代码语言:javascript复制@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, 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;
}
//构造一个自动dialing创建器,放入容器中去,自动代理创建器是一个后置处理器,他的优先级被设置为最高
//beanName被设置为了AUTO_PROXY_CREATOR_BEAN_NAME
//角色是ROLE_INFRASTRUCTURE
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying—强制使用cglib完成代理
代码语言:javascript复制 public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
//AUTO_PROXY_CREATOR_BEAN_NAME是自动代理创建器再容器中的专属名称--上面已经默认注册过了,因此这里可以直接拿出来
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//设置其proxyTargetClass属性为true,强制该自动代理创建器,创建出来的代理对象都是通过cglib完成的代理
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
AopConfigUtils.forceAutoProxyCreatorToExposeProxy—将目标对象暴露到aopcontext中
代码语言:javascript复制 public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//拿出容器中已经注册好的自动代理创建器,设置其exposeProxy属性为true,表示该代理创建器创建的所有bean都需要暴露到aopcontext中
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
注解方式-@EnableAspectJAutoProxy
代码语言:javascript复制//Enables support for handling components marked with AspectJ's {@code @Aspect} annotation,
//similar to functionality found in Spring's {@code <aop:aspectj-autoproxy>} XML element.
//Note: {@code @EnableAspectJAutoProxy} applies to its local application context only,(说明此注解只会作用于本容器,对子、父容器是无效得)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
// 决定该类采用CGLIB代理还是使用JDK的动态代理(需要实现接口),默认为false,表示使用的是JDK得动态代理技术
boolean proxyTargetClass() default false;
// @since 4.3.1 代理的暴露方式:解决内部调用不能使用代理的场景 默认为false表示不处理
// true:这个代理就可以通过AopContext.currentProxy()获得这个代理对象的一个副本(ThreadLocal里面),从而我们可以很方便得在Spring框架上下文中拿到当前代理对象(处理事务时很方便)
// 必须为true才能调用AopContext得方法,否则报错:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
boolean exposeProxy() default false;
}
当然,最重点的,还是这一句@Import(AspectJAutoProxyRegistrar.class),下面看看它
AspectJAutoProxyRegistrar—为容器注册 自动代理创建器
代码语言:javascript复制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) {
// 若为true,表示强制指定了要使用CGLIB,那就强制告知到时候使用CGLIB的动态代理方式
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 告知,强制暴露Bean的代理对象到AopContext
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
和xml的思想一样
AspectJAutoProxyRegistrar的registerBeanDefinitions方法何时被调用—可以一览配置类的解析大致流程
首先明确一点ConfigurationClassPostProcessor负责解析import,configuation注解和处理ImportBeanDefinitionRegistrar 相关回调接口
refresh–> invokeBeanFactoryPostProcessors
ConfigurationClassPostProcessor是一个工厂Bean后置处理器,在refresh方法的invokeBeanFactoryPostProcessors中会去调用所有注册上来的工厂bean后置处理器。
代码语言:javascript复制 public void refresh() throws BeansException, IllegalStateException {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
postProcessBeanFactory(beanFactory);
//触发调用工厂bean的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
...
invokeBeanFactoryPostProcessors方法
代码语言:javascript复制 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法
代码语言:javascript复制public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
//处理的是编码设置的工厂bean后置处理器,这里不管
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//这里会调用 ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//获取到容器中所有类型为BeanDefinitionRegistryPostProcessor工厂bean后置处理器
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
...排序啥的,处理一通
//调用后置处理器的invokeBeanDefinitionRegistryPostProcessors方法---我们就重点分析这里,剩余的就先不管了
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
....
PostProcessorRegistrationDelegate的invokeBeanDefinitionRegistryPostProcessors方法
代码语言:javascript复制 private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
//调用这类工厂bean后置处理器的postProcessBeanDefinitionRegistry方法,向容器中放入一下bean的定义
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
代码语言:javascript复制 @Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
....
//处理配置类中bean的定义
processConfigBeanDefinitions(registry);
}
ConfigurationClassPostProcessor的processConfigBeanDefinitions方法
代码语言:javascript复制 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
//将容器中所有标注了@Configuration注解的配置类加入configCandidates集合
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
//配置类集合排序---通过配置类上的@order注解决定
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
//尝试从容器中获取自定义的bean名称生成器,该自定义bean名字生成器的beanName是固定的CONFIGURATION_BEAN_NAME_GENERATOR
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
//通过ConfigurationClassParser挨个解析每个配置类
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 {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//parser.parse(candidates);这个过程是解析配置类的关键过程,但是我们这里不进行深入分析,因为本文重点不在于此
//但是该方法会去拿到import注解上导入的ImportBeanDefinitionRegistrar,然后放入当前后置处理器的对应集合中保存起来
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
//ConfigurationClassBeanDefinitionReader配置类bean定义信息读取
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//去加载bean的定义,我们自动代理创建器的那个注册方法在该方法中被调用
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
...
}
这个方法非常关键,但是对于我们要探究自动代理配置器的注册过程而言,只需要重点关注parser.parse(candidates);和this.reader.loadBeanDefinitions(configClasses);方法即可
ConfigurationClassParser的parse方法
代码语言:javascript复制 protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
ConfigurationClassParser的processConfigurationClass方法
代码语言:javascript复制 protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
...
do {
//真正处理解析配置类的方法
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
ConfigurationClassParser的doProcessConfigurationClass方法
代码语言:javascript复制 protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
....
// Process any @Import annotations
//关注这里***
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
...
}
ConfigurationClassParser的processImports方法—处理@Import注解的方法
代码语言:javascript复制private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//拿到import导入的所有bean,挨个处理
for (SourceClass candidate : importCandidates) {
//如果导入的bean继承了ImportSelector,那么进行相关处理
if (candidate.isAssignable(ImportSelector.class)) {
...
}
//如果导入的bean继承了ImportBeanDefinitionRegistrar,那么进行相关处理
//这不就是AspectJAutoProxyRegistrar继承的父接口吗
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
//实例化该导入bean定义的注册器
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
//添加到 configClass的相关属性集合中去
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
...
}
}
到这里我们已经知道了import导入的bean如果继承了ImportBeanDefinitionRegistrar接口,那么会被放到ConfigurationClass的ImportBeanDefinitionRegistrars集合中进行保存
ConfigurationClassBeanDefinitionReader的loadBeanDefinitions方法
代码语言:javascript复制 // 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());
}
this.reader.loadBeanDefinitions(configClasses);
分析一下该方法:
代码语言:javascript复制 public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
ConfigurationClassBeanDefinitionReader的loadBeanDefinitionsForConfigurationClass方法
代码语言:javascript复制 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());
//看这里---详细大家应该猜到了,configClass在parse步骤就已经拿到了当前配置类上的ImportBeanDefinitionRegistrar
//并保存在其自身的属性集合中
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
ConfigurationClassBeanDefinitionReader的loadBeanDefinitionsFromRegistrars方法
代码语言:javascript复制 private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}
依次调用每个BeanDefinitionsFromRegistrar的registerBeanDefinitions方法
AspectJAutoProxyRegistrar的loadBeanDefinitionsFromRegistrars方法—圆回来了
代码语言:javascript复制 public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法已经分析过了,这里不再多讲