美文网首页
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