ApplicationContext源码二三事

刚接触Spring的时候,我们都会对bean的生命周期有一个基本的了解,而在这之中,bean会实现几个特殊的接口,其中就有ApplicationContext接口

接口结构

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

通过ApplicationContext接口的源码可知道:该接口继承了BeanFactory的接口,有着BeanFactory的所有功能
BeanFactory可以说是Spring的核心,Factory表明其是一个工厂类,在Spring中所有的Bean都是由BeanFactory进行管理,它的职责有:对应用程序中的对象进行配置、实例化、定位以及建立这些对象间的依赖关系

除了BeanFactory的基本功能,在其他方面(如国际化支持,资源访问,事件传播)都有良好支持

实现类

ApplicationContext有着众多的实现类
ApplicationContext实现类
重点讲下ClassPathXMLApplicationContext和FileSystemXMLApplicationContext这两个类
这两个类都是项目用得比较多的ApplicationContext实例化的实现类
两者都是将xml文件地址作为参数传入,找到并装载完成ApplicationContext的实例化工作,下面以ClassPathXMLApplicationContext为例阐述其几种使用方式

从构造函数可发现,主要的构造函数为

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

    }

其中有一个比较特殊的refresh()方法:

public void refresh() throws BeansException, IllegalStateException {
        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 var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

这里可以看到方法比较多
可以看看各方法的具体用途:

方法作用
prepareRefresh,prepareBeanFactory做一些准备工作
postProcessBeanFactory在BeanFactory准备工作完成后做一些定制化的处理,一般结合BeanPostProcessor接口的实现类一起使用,注入一些重要资源
invokeBeanFactoryPostProcessors也是对一些接口调用一些处理器进行处理
registerBeanPostProcessors注册BeanPostProcessor
initMessageSource初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
initApplicationEventMulticaster初始化多路广播器,为监听器做准备
onRefresh子类进行扩展
registerListeners注册监听器
finishBeanFactoryInitialization实例化所有非懒加载的bean对象

使用
ClassPathXMLApplicationContext的实例
ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
或者可以多个参数
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{“applicationContext1.xml”,“applicationContext2.xml”});
还可以用通配符
ApplicationContext ac = new ClassPathXmlApplicationContext("*.xml");

ClassPathXMLApplicationContext和FileSystemXMLApplicationContext区别:
ClassPathXMLApplicationContext:
默认src目录下的路径
要用绝对路径时需加上file前缀
FileSystemXMLApplicationContext:
默认是项目根目录,要用src目录下的路径时需要加classpath前缀
可以直接用盘符加路径表示绝对路径

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值