一. 研究目标: 解析spring如何加载配置类的?
我们经常会在一个类上打上@Configuration, @Component, @Bean等. 带有这些注解的类, 我们在spring启动的时候,是如何被加载的呢?
下面就以此为目的,分析spring源码. 本节的内容是对上一节内容的实战分析, 同时更加详细的解读spring源码
我们知道, spring启动的时候做了3件事, 就是上面的三件事.
第一件事: 调用this()自身的无参构造函数. 初始化了BeanDefinitionReader和BeanDefinitionScanner, 同时初始化了很多spring的原始后置处理器, 这些处理器是用来加载在定义bean的
第二件事: 调用register(..)
第三件事: refresh(..) 这里包含了整个ioc创建bean的全生命周期
二. 自定义配置类
我们先定义好要分析加载的配置类
package com.lxl.www.iocbeanlifecicle; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * 这是一个配置类, * 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean */ @Configuration @ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"}) public class MainConfig { }
这个配置类很简单, 使用@ComponentScan注解指定了扫描的包. @Configuration指定当前是一个配置类
package com.lxl.www.iocbeanlifecicle; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainStarter { public static void main(String[] args) { // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); //context.addBeanFactoryPostProcessor(); Car car = (Car) context.getBean("car"); System.out.println(car.getName()); context.close(); } }
在main里, 通过AnnotationConfigurationApplicationContext读取配置类MainConfig.class.
配置类被传进来以后, 到底是怎么被解析的呢? 这就是我们分析的线索
始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰. 整体内容讲解在这里: https://www.cnblogs.com/ITPower/p/13677635.html
下面, 从入口进入. 我们的入口就是这里
new AnnotationConfigApplicationContext(MainConfig.class);
下面进入AnnotationConfigApplicationContext的构造方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { // 进入构造函数, 首先调用自身的构造方法this(); // 调用自身的构造方法之前, 要先调用父类的构造方法 this(); // register配置注册类 register(componentClasses); // ioc容器shua新接口--非常重要 refresh(); }
三、读取配置类后置处理器ConfigurationClassPostProcessor
3.1 this()无参构造函数
public AnnotationConfigApplicationContext() { /** * 创建了一个Bean定义的读取器. * 完成了spring内部BeanDefinition的注册(主要是后置处理器) * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类(也就是创世纪的类). */ this.reader = new AnnotatedBeanDefinitionReader(this); /** * 创建BeanDefinition扫描器 * 可以用来扫描包或者类, 进而转换为bd * * Spring默认的扫描包不是这个scanner对象 * 而是自己new的一个ClassPathBeanDefinitionScanner * Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner * * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法 * 通过调用context.scan("package name");扫描处理配置类 * 扫描 */ this.scanner = new ClassPathBeanDefinitionScanner(this); }
在初始化AnnotatedBeanDefinitionReader(this);的时候, 注册了很多后置处理器
/** * Register all relevant annotation post processors in the given registry. * @param registry the registry to operate on * @param source the configuration source element (already extracted) * that this registration was triggered from. May be {@code null}. * @return a Set of BeanDefinitionHolders, containing all bean definitions * that have actually been registered by this call */ public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { // 获取到beanFactory DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); /** * 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver * 没有则添加 */ if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } // BeanDefinitionHolder: 为BeanDefinition设置名字和别名 Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); // 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // 构建BeanDefinitionHolder, 并添加到beanDefs beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor Autowired注解bean的后置处理器, 则添加一个 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); // 构建BeanDefinitionHolder, 并添加到beanDefs beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. // 检查对JSR-250的支持, 如果rigistry中没有 CommonAnnotationBeanPostProcessor 通用注解后置处理器, 则添加一个 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); // 构建BeanDefinitionHolder, 并添加到beanDefs beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. // 检查对jpa的支持, 如果不包含 internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个 if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 检查对事件监听的支持, 如果不包含事件监听处理器 internalEventListenerProcessor, 就添加一个 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // 如果不包含事件监听工厂处理器 internalEventListenerFactory , 就添加一个 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
我们看到, 注册了6个原始bean, 这些bean是spring自己提前定义好的, 他们的加载是整个spring的基础. 用于解析spring 中其他的类
而这一次我们要读取配置, 所以重点关注的是下面这个类
ConfigurationClassPostProcessor.class
这里还有很多其他的原始类被注册了, 但我们的目标是分析配置类是如何被读取的, 所以, 其他的先忽略, 只看ConfigurationClassPostProcessor.
3.2 ConfigurationClassPostProcessor的继承结构
可以看到ConfigurationClassPostProcessor是同时实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor. 这一点我们需要记住, 后面会使用到
2.3 ConfigurationClassPostProcessor是如何被注册的
// 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // 构建BeanDefinitionHolder, 并添加到beanDefs beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); }
首先,构建了一个RootBeanDefinition. 然后调用了registerPostProcessor方法, 三个入参分别是
registry: BeanDefinitionRegistry注册器, 用于注册BeanDefinition
def: 刚刚构建的RootBeanDefinition
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: 构建BeanDefinition使用的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor
然后调用registerPostProcessor方法
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } // 从BeanDefinition的一级缓存BeanDefinitionMap中读取BeanDefinition对象, 判断是否已经存在 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { // 判断是否允许BeanDefinition重写 if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } // 以上情况都没有限制, 重置一级缓存的bean定义 this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 处理循环引用的问题 if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { clearByTypeCache(); } }
这里面的关键代码是标红的部分, 将ConfigurationClassPostProcessor放入到了beanDefinitionMap里面
下面的else是处理循环引用的问题, 暂时先不要看. 后面有专门的章节讲解循环引用.
3.3 对照整体框架, 我们知道ConfigurationClassPostProcessor被解析成beanDefinition放入到BeanDefinitionMap中了
ConfigurationClassPostProcessor是一个工具类, 这个类的作用是解析配置类.
工具类有了, 那么还得有主角呀, 那就是我们上面的配置类. 下面看看配置类的加载
3.4 初始化ClassPathBeanDefinitionScanner
在this()构造方法里, 还初始化了ClassPathBeanDefinitionScanner, 这里只说一句.
this.scanner = new ClassPathBeanDefinitionScanner(this);
我们在扫描配置类的时候, 确实使用的是ClassPathBeanDefinitionScanner, 但是, 不是this.scanner对象. 而是自己new的一个ClassPathBeanDefinitionScanner.
这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
通过调用context.scan("package name");扫描处理配置类
使用方式如下:
public static void main(String[] args) { // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); context.scan("package"); Car car = (Car) context.getBean("car"); System.out.println(car.getName()); context.close(); }
到目前为止完成了后置处理器注册为BeanDefinition
四. 读取自定义配置类MainConfig
注册配置类,入口自然是这里了
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { // 进入构造函数, 首先调用自身的构造方法this(); // 调用自身的构造方法之前, 要先调用父类的构造方法 this(); // register配置注册类 register(componentClasses); // ioc容器shua新接口--非常重要 refresh(); }
跟踪进去找到doRegisterBean(...)方法
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) { // 将入参的配置类beanClass构建成AnnotatedGenericBeanDefinition对象 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(supplier); // 读取配置类的元数据 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); // 处理主类通用定义注解 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } if (customizers != null) { for (BeanDefinitionCustomizer customizer : customizers) { customizer.customize(abd); } } // 将MainConfig.java配置类进行解析.放到BeanDefinitionHolder BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
重点就是红色这句话, 其他可以略过, 因为我们的配置类很简单, 直接看BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
我们找到 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法, 进入到DefaultListableBeanFactory查看方法, 这个方法之前我们已经调用过一次
就是在注册ConfigurationClassPostProcessor的时候, 我们需要将其解析为BeanDefinition然后放到BeanDefinitionMap中, 这里也是一样的, 将我们的配置类MainConfig解析成BeanDefinition放入到BeanDefinitionMap中.
这里的代码在整个框架中处于什么位置呢? 将MainConfig解析为BeanDefinition放入到BeanDefinitionMap中
以上两步, 一个是将ConfigurationClassPostProcessor配置类后置处理器, 也就是解析配置的工具类, 解析成BeanDefinition放入到BeanDefinitionMap中
另一个是将我们的目标配置类MainConfig加载到内存, 组装成BeanDefinition放入到BeanDefinitionMap中.
到这里位置我们完成了两步.
五. 调用bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);
在refresh()中有很多步骤, 我们重点来看invokeBeanFactoryPostProcessors(beanFactory);
/** * refresh是spring最核心的方法, 里面包含了整个spring ioc的全过程, 包括spring加载bean到销毁bean的全过程 * 学习spring, 就是学习里面的13个方法, 如果13个方法都学完了, 基本上就打通了 * @throws BeansException * @throws IllegalStateException */ @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1. 准备刷新上下文环境 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. //2. 获取告诉子类初始化bean工厂, 不同工厂不同实现 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. //3. 对bean工厂进行填充属性 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 4. 留个子类去实现该接口 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. /* * * 调用bean工厂的后置处理器 * 我们之前在Reader的时候读取了很多创世纪的PostProcessor后置处理器. * 这里要调用bean工厂的后置处理器. 这么多创世纪的PostProcessor, 只有一个PostProcessor实现了 * BeanFactoryPostProcessor. 那个类就是 ConfigurationClassPostProcessor * 前面已经将ConfigurationClassPostProcessor放入到BeanDefinitionMap中了, * 对应的BeanDefinitionName 是 internalConfigurationAnnotationProcessor * * * */ invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册bean后置处理器 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 初始化国际化资源处理器 initMessageSource(); // Initialize event multicaster for this context. // 创建事件多播放器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 这个方法通用也是留个子类实现的, spring boot也是从这个方法进行启动 onRefresh(); // Check for listener beans and register them. // 将事件监听器注册到多播放器上 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化剩余的单实例bean /** * 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. //最后容器刷新 发布刷新时间(spring cloud是从这里启动的 ) finishRefresh(); } ........ }
invokeBeanFactoryPostProcessors(beanFactory);看名字, 调用的是Bean工厂的后置处理器, 我们在第二部分说了, 初始化的时候初始化了很多spring原生的后置处理器, 这么多后置处理器, 其实, 只有一个后置处理器实现了BeanFactoryPostProcessor, 它就是ConfigurationClassPostProcessor, 还记得上面让大家记住的结构图么, 拿下来, 再看一遍.
这里调用的时候, 原生处理器只会调用ConfigurationClassPostProcessor.
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { /** * 获取两处存储BeanFactoryPostProcessor的对象, 传入供接下来调用 * 1. 当前bean工厂 * 2. 和我们自己调用addBeanFacoryPostProcessor自定义BeanFactoryPostProcessor * * 参数: getBeanFactoryPostProcessors() 传了一个工厂的后置处理器的List, 这个时候list是空的 * getBeanFactoryPostProcessors()里面的值是怎么来的呢? * 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加 * * public static void main(String[] args) { * // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类 * AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); * context.addBeanFactoryPostProcessor(...); * Car car = (Car) context.getBean("car"); * System.out.println(car.getName()); * context.close(); * } */ PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
这里要调用bean工厂的后置处理器了. 看上面的注释, 注释写的很清晰.
在调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());的时候调用了getBeanFactoryPostProcessors()方法.
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }
getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的 getBeanFactoryPostProcessors()里面的值是怎么来的呢? 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加. 也就是通过main 方法手动添加的beanFactoryPostProcessor. 如下所示
public static void main(String[] args) { // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); context.addBeanFactoryPostProcessor(...); Car car = (Car) context.getBean("car"); System.out.println(car.getName()); context.close(); }
接下来重点来了. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 方法实现一共分为两大步:
第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义.
来看看源码是如何定义的. 重点看代码的注释, 每一部分的功能都有明确标出, 注释写的很详细
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { /** * 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器 * 定义已处理的后置处理器 */ // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); /** * 这里一共分为两大步: * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器) * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器 */ /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义 begin****************************/ // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取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; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. /** * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor */ List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用. // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 调用beanFactory.getBean实例化创世界的类ppName currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第一次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 处理完了,清空currentRegistryProcessors currentRegistryProcessors.clear(); // 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // 将其放入到currentRegistryProcessors, 马上就要被调用 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第二次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; // 获取 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 已处理过的postProcessor不再处理 if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第三次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. /* * 调用bean工厂的后置处理器 * registryProcessors: 带有注册功能的bean工厂的后置处理器 * regularPostProcessors: 不带注册功能的bean工厂的后置处理器 */ invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { /* * 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力 * 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法 */ // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义 end****************************/ /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器 begin****************************/ // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. // 优先排序的后置处理器 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 首先, 调用有优先级排序的后置处理器 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 第二, 调用实现了Ordered排序的后置处理器 // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 最后, 调用没有实现任何排序接口的beanFactory后置处理器 // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器 end****************************/ // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
下面我们就来分析上图所示的内容.
1. 对照源码和上图, 我们来看第一次调用
// 第一次, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用. // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 调用beanFactory.getBean实例化创世界的类ppName currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第一次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 处理完了,清空currentRegistryProcessors currentRegistryProcessors.clear();
首先, 拿到了所有实现了BeanDefinitionRegistryPostProcessor的后置处理器, 上面我们做过铺垫,只有ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor后置处理器
所以,这里过滤出来的postProcessorNames只有一个值, 接下来, 判断, 这个类是否实现了PriorityOrdered 优先排序的接口, 如果实现了, 那么放入到currentRegistryProcessors中, 后面会进行调用.
接下来, 执行invokeBeanDefinitionRegistryPostProcessors
这是第一次调用BeanDefinitionRegistryPostProcessors
2. 第二次调用BeanDefinitionRegistryPostProcessors
// 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // 将其放入到currentRegistryProcessors, 马上就要被调用 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第二次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear();
第二次调用的时候 ,依然是获取所有的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器, 且这个处理器没有实现过PriorityOrdered也就是没有被上面调用过. 且实现了Ordered接口
这一类添加到currentRegistryProcessors集合中, 然后调用invokeBeanDefinitionRegistryPostProcessors处理
这是第二次调用BeanDefinitionRegistryPostProcessor
3. 第三次调用BeanDefinitionRegistryPostProcessor
// 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; // 获取 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 已处理过的postProcessor不再处理 if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); /** * 第三次调用BeanDefinitionRegistryPostProcessors * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描 @import 等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); }
第三次调用的是没有实现过任何排序接口的后置处理器. 并将其放入到currentRegistryProcessors, 然后执行invokeBeanDefinitionRegistryPostProcessors
4. 第四次调用
// Now, invoke the postProcessBeanFactory callback of all processors handled so far. /* * 调用bean工厂的后置处理器 * registryProcessors: 带有注册功能的bean工厂的后置处理器 * regularPostProcessors: 不带注册功能的bean工厂的后置处理器 */ // 调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法----为什么是调用BeanDefinitionRegistryPostProcessor? 因为 // ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 调用BeanFactoryPostProcessor 自设的(ConfigurationClassPostProcessor没有) invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
ConfigurationClassPostProcessor同时实现了BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors, 调用的是
一共进行了4次调用
总结: 优先处理的是实现了PriorityOrdered的后置处理器, 然后调用实现了Order接口的后置处理器, 最后调用了没有实现任何排序方法的后置处理器. 最后调用工厂类方法.
下面我们来具体分析invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
5. 提问: 检验一下是否理解了上面四个步骤
1. ConfigurationClassPostProcessor会调用1234哪几步? 因为ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,PriorityOrdered, 因此会调用1,4 2. 如果自己定义了一个MyBeanFactoryPostProcessor会调用1234那几步? package com.lxl.www.iocbeanlifecicle; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.stereotype.Component; @Component public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } } 因为MyBeanFactoryPostProcessor是自定义的, 没有实现任何PriorityOrdered 或者 Order, 因此, 会调用3,4
6. 详细研究第四步, invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);的逻辑.
先说它, 因为他的概念简单一点
我们在这一步打个断点, 然后跟着断点一步一步点击进去
这是registryProcessors里面只有一个后置处理器, 就是ConfigurationClassPostProcessor.
然后进入到ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } // 使用 cglib 配置类进行代理, 因为@Bean方法到时候要进行创建Bean的实例. enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
这里先看enhanceConfigurationClasses(beanFactory);个方法
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE); MethodMetadata methodMetadata = null; if (beanDef instanceof AnnotatedBeanDefinition) { methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata(); } if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) { // Configuration class (full or lite) or a configuration-derived @Bean method // -> resolve bean class at this point... AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef; if (!abd.hasBeanClass()) { try { abd.resolveBeanClass(this.beanClassLoader); } catch (Throwable ex) { throw new IllegalStateException( "Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } } } /** * 只有full版配置才会创建cglib代理 * full是怎么来的呢? 我们使用@Configuration注解了, 在加载的时候, 就会设置为full * 当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理. * * 为什么要创建动态代理呢? * 动态代理可以保证, 每次创建的bean对象只有一个 * * 那么加@Configuration和不加本质上的区别是什么? * 当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean * 如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用. */ if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) { if (!(beanDef instanceof AbstractBeanDefinition)) { throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { logger.info("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; } ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(); for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { AbstractBeanDefinition beanDef = entry.getValue(); // If a @Configuration class gets proxied, always proxy the target class beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.getBeanClass(); Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isTraceEnabled()) { logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } beanDef.setBeanClass(enhancedClass); } } }
粗体部分就是判断是否需要进行cglib代理. 进行cglib代理的条件是, beanDefinition中属性configurationClass的值是full. 只有full版配置才会创建cglib代理
full是怎么来的呢?
如果我们使用@Configuration注解了, 在加载的时候, 就会将configurationClass属性设置为full. 当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理.
cglib动态代理做了什么事情呢? 不看源码的情况下, 简单可以理解为, 去ioc工厂里面通过getBean("car") 查询了看ioc中是否有这个对象, 如果有就取出来, 不再另创建.
这也是@Configuration 和其他注解类似@Component和@ComponentScan的本质区别:
当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean
如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.
下面来看个例子
基础类: public class Car { private String name; private Tank tank; public String getName() { return name; } public void setName(String name) { this.name = name; } public Tank getTank() { return tank; } public void setTank(Tank tank) { this.tank = tank; } } public class Tank { private String name; public Tank() { System.out.println("创建一个tank"); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
这是定义的car和tank的基础类
@Configuration @ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"}) public class MainConfig { @Bean("car") public Car car() { Car car = new Car(); car.setName("zhangsan"); // 这里调用了Tank类, tank是通过@Bean注解注入的. car.setTank(tank()); return car; } @Bean public Tank tank() { return new Tank(); } }
当配置类使用了@Configuration注解的时候, 运行main方法
public class MainStarter { public static void main(String[] args) { // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); context.scan("package"); //context.addBeanFactoryPostProcessor(); Car car = (Car) context.getBean("car"); Car car2 = (Car) context.getBean("car"); System.out.println(car.getName()); context.close(); } }
当去掉@Configuration注解的时候, 再次运行, 我们看到创建了两次tank
//@Configuration @ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"}) public class MainConfig { @Bean("car") public Car car() { Car car = new Car(); car.setName("zhangsan"); // 这里调用了Tank类, tank是通过@Bean注解注入的. car.setTank(tank()); return car; } @Bean public Tank tank() { return new Tank(); } }
在main方法中调用了两次(Car) context.getBean("car");
在ioc容器中, car对象只有一个, 但是在构建car的时候, 调用了tank, tank在ioc容器中却不一定只有一份. 只有使用了@Configuration, 表示需要使用cglib动态代理查找tank类, 保证ioc容器中只有一份.
7. 详细研究四次调用中的第一次调用. 通过分析跟踪@ComponentScan注解是如何解析的,
通过跟踪@ComponentScan注解是如何解析的, 分来理解BeanDefinitionScan, BeanDefinitionRegistry, BeanDefinitionReader是如何工作的.
as