美文网首页
Spring ClassPathXmlApplicationCo

Spring ClassPathXmlApplicationCo

作者: Tinyspot | 来源:发表于2022-07-09 09:45 被阅读0次

    入口

    • ClassPathXmlApplicationContext 加载 CLASSPATH 下的配置文件
    • 对所有 Bean 实例的加载,入口在 ClassPathXmlApplicationContext 的构造函数中

    流程分析

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        // parent 为 null,表示无父容器
        super(parent);
        // 将参数 configLocations 指定的 Spring 配置文件路径中的 ${PlaceHolder} 占位符,替换为系统变量中PlaceHolder对应的Value值,并存储到成员变量configLocations中
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }
    

    1. refresh()

    • 调用父类 AbstractApplicationContext.refresh()
    • 完成容器初始化
    public void refresh() throws BeansException, IllegalStateException {
        // 方法主体加了同步锁
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            // 1.Prepare this context for refreshing.
            prepareRefresh();
            // 2.Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // 3. Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                /**
                 * 4. Allows post-processing of the bean factory in context subclasses.
                 * 模板设计模式:空实现,可扩展
                 */
                postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                /**
                 * 5. Invoke factory processors registered as beans in the context.
                 *   BeanDefinitionRegistryPostProcessor: BeanDefinition 的修改和注册
                 *   BeanFactoryPostProcessor
                 */
                invokeBeanFactoryPostProcessors(beanFactory);
                /**
                 * 6. Register bean processors that intercept bean creation.
                 *   BeanPostProcessor
                 */
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                // 7. Initialize message source for this context.
                initMessageSource();
                // 8. Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                /**
                 * 9. Initialize other special beans in specific context subclasses.
                 * 模板设计模式:空实现,可扩展
                 *  spring boot 内嵌 tomcat
                 */
                onRefresh();
                /**
                 * 10. Check for listener beans and register them.
                 *  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
                 */
                registerListeners();
                /**
                 * 11. Instantiate all remaining (non-lazy-init) singletons.
                 *  1. bean 实例化
                 *  2. IOC
                 *  3. 注解支持
                 *  4. BeanPostProcessor 执行
                 *  5. AOP 入口
                 */
                finishBeanFactoryInitialization(beanFactory);
                // 12. Last step: publish corresponding event.
                finishRefresh();
            }
        }
    }
    

    2. obtainFreshBeanFactory()

    1. 创建 BeanFactory 对象
    2. xml 解析
    3. 把解析出来的 xml 标签封装成 BeanDefinition 对象

    2.1 refreshBeanFactory()

    • AbstractRefreshableApplicationContext#refreshBeanFactory
    protected final void refreshBeanFactory() throws BeansException {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 3.1 "allowBeanDefinitionOverriding" and "allowCircularReferences" settings
            customizeBeanFactory(beanFactory);
            // 3.2 xml解析
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
    }
    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    
    public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
        private Boolean allowBeanDefinitionOverriding;
        private Boolean allowCircularReferences;
        private volatile DefaultListableBeanFactory beanFactory;
    }
    
    public final ConfigurableListableBeanFactory getBeanFactory() {
        // 成员变量 beanFactory,该实例为 DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = this.beanFactory;
        return beanFactory;
    }
    

    3.1 customizeBeanFactory()

    • 要修改,必须拿到 BeanFactory 对象
    • 类一定要加 @Component
    // 源码
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        if (this.allowCircularReferences != null) {  
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }
    }
    
    @Component
    public class BeanProcessorDemo implements BeanDefinitionRegistryPostProcessor {
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
        }
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            DefaultListableBeanFactory defaultBeanFactory = (DefaultListableBeanFactory) beanFactory;
            defaultBeanFactory.setAllowBeanDefinitionOverriding(true);
            defaultBeanFactory.setAllowCircularReferences(true);
        }
    } 
    

    3.2 loadBeanDefinitions()

    • AbstractRefreshableApplicationContext#loadBeanDefinitions
    // 子类 AbstractXmlApplicationContext#loadBeanDefinitions
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 委托模式:专人专事
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        initBeanDefinitionReader(beanDefinitionReader);
        // 4.1
        loadBeanDefinitions(beanDefinitionReader);
    }
    

    4.1 loadBeanDefinitions()

    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
        for (Resource resource : resources) {
            // 模板设计模式,调用子类中的方法
            count += loadBeanDefinitions(resource);
        }
    }
    

    相关文章

      网友评论

          本文标题:Spring ClassPathXmlApplicationCo

          本文链接:https://www.haomeiwen.com/subject/ymtfvrtx.html