Spring源码阅读(四)—容器的功能拓展ApplicationContext

本文详细探讨了Spring中的ApplicationContext与BeanFactory的区别,重点讲解ApplicationContext的初始化过程,包括BeanFactory的初始化、功能拓展如事件机制、国际化处理,以及Bean的实例化和依赖注入。通过对ApplicationContext的深入理解,揭示了其作为BeanFactory的增强版所具备的高级特性。
摘要由CSDN通过智能技术生成

ApplicationContext和BeanFactory都用于Bean的加载,ApplicationContext包含BeanFactory的所有功能,创建的上下文环境是BeanFactory的功能拓展.

个人主页:tuzhenyu’s page
原文地址:Spring源码阅读(四)—容器的功能拓展ApplicationContext

(0) ApplicationContext和BeanFactory的区别

  • ApplicationContext(应用上下文)和BeanFactory(bean工厂)是Spring的两种容器,ApplicationContext是BeanFactory的功能拓展.

  • BeanFactroy采用的是延迟加载形式来注入依赖的,只有在调用getBean()的时候才对该Bean进行加载实例化.而ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。

  • ApplicationContext扩展了ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource,而BeanFactory是没有扩展ResourceLoader ,只能加载单个资源文件.

  • BeanFactory是不支持国际化功能的,因为BeanFactory没有扩展Spring中MessageResource接口。相反,由于ApplicationContext扩展了MessageResource接口提供了国际化的消息访问功能.

  • ApplicationContext实现了强大的事件机制(Event)

(1) ApplicationContext上下文的入口

  • 初始化ApplicationContext



ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = context.getBean("hello",HelloWorld.class);
  • 调用setConfigLocations()方法将配置文件加载进内存,调用refresh()方法进行上下文的初始化

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if(refresh) {
        this.refresh();
    }

}

(2) ApplicationContext上下文的初始化

上下文初始化主要步骤:

  • 调用prepareRefresh()方法刷新上下文环境,对系统属性和环境变量的初始化进行验证;

  • 调用obtainFreshBeanFactory()方法读取XML配置文件初始化BeanFactory,实现了BeanFactory的功能.

  • 调用prepareBeanFactory()方法对BeanFactory进行功能拓展

  • 实现事件机制

  • 初始化剩下的所有单例bean,进行bean的初始化和依赖的注入


public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var5) {
            this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5);
            this.destroyBeans();
            this.cancelRefresh(var5);
            throw var5;
        }

    }
}

1.调用obtainFreshBeanFactory()方法初始化BeanFactory

  • 调用customizeBeanFactory()定制BeanFactory提供@Autowired支持等

  • 调用loadBeanDefinitions()方法从XML配置文件中装载bean


protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    this.refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    if(this.logger.isDebugEnabled()) {
        this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
    }

    return beanFactory;
}

2.BeanFactory的功能拓展

  • 调用invokeBeanFactoryPostProcessors()方法激活所有注册的BeanBeanFactoryPostProcessor后处理器(对象是BeanFactory).BeanBeanFactoryPostProcessor是在注册Bean工厂加载完所有Bean后执行,通过实现BeanFactoryPostProcessor接口进行注册.



this.invokeBeanFactoryPostProcessors(beanFactory);
  • 调用registerBeanPostProcessors()方法注册BeanPostProcessor后处理器(对象是Bean).BeanPostProcessor是在bean实例化后调用,用于功能拓展.BeanPostProcessor注册的方法是实现InstantiationAwareBeanPostProcessor接口.



this.registerBeanPostProcessors(beanFactory);
  • 调用initMessageSource()方法初始化Message源,进行国际化处理

this.initMessageSource();
  • 实现事件机制

    • 调用initApplicationMuticaster()方法初始化消息广播器,广播器用于存放监听器并在合适的时候调用监听器.

    • 调用registerListeners()方法注册bean中的所有监听器listener


this.initApplicationEventMulticaster();
this.registerListeners();
  • 调用finishBeanFactoryInitialization()方法加载所有的bean实例,并进行依赖注入(区别于BeanFactory的重要一点)

调用preInstantiateSingletons()方法进行bean的实例化和依赖注入




protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
        beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
    }

    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    String[] var3 = weaverAwareNames;
    int var4 = weaverAwareNames.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        String weaverAwareName = var3[var5];
        this.getBean(weaverAwareName);
    }

    beanFactory.setTempClassLoader((ClassLoader)null);
    beanFactory.freezeConfiguration();
    beanFactory.preInstantiateSingletons();
}

(3) 总结

ApplicationContext上下文的初始化主要是进行了初始化BeanFactory,并在此基础上进行功能拓展比如事件机制,后处理器等,最后对BeanFactory中的所有bean进行实例化和依赖注入.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值