刚接触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有着众多的实现类
重点讲下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前缀
可以直接用盘符加路径表示绝对路径