这次算是对以前的一次温习吧,以前对spring的源码理解的也不是很渗透,这次好好系统学习。spring的初始化话,是通过配置文件,然后通过resoure接口加载。
下面我们通过最简单的demo来查看spring源码的执行和设计之美~
applicationContext.xml
public static void main(String[] args){
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ac.getBean("hello"));
System.out.println("__________输出实例___________");
}
看看这个ClassPathXmlApplicationContext的构造函数:
/**
* Create a new ClassPathXmlApplicationContext, loading the definitions
* from the given XML file and automatically refreshing the context.
* @param configLocation resource location
* @throws BeansException if context creation failed
*/
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
解释:是通过加载configLocation这个文件路径applicaton,classpath找到ApplicationContext.xml文件。
继续走:
/**
* Create a new ClassPathXmlApplicationContext with the given parent,
* loading the definitions from the given XML files.
* @param configLocations array of resource locations
* @param refresh whether to automatically refresh the context,
* loading all bean definitions and creating all singletons.
* Alternatively, call refresh manually after further configuring the context.
* @param parent the parent context
* @throws BeansException if context creation failed
* @see #refresh()
*/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
从这里我们看出,ApplicatonContext 支持多层级关系的context,也就是说从这个层面上来看,我们可以多个project,互通ApplicationContext里面的对象,即使Spring
没有提供这样的扩展,那么我相信Spring肯定会提供这样的扩展接口给开发者。
上面这个是YY的~
然后进入进入setConfigLocations,这个方法主要是给设置配置文件的方法,我先不进去,因为想进入refresh方法看看。
refresh方法内容:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
网上看到大牛写的refresh代码介绍,建议看看:
public void refresh() throws BeansException, IllegalStateException {
// 整个刷新过程是同步的
synchronized (this.startupShutdownMonitor) {
// 刷新前的准备工作
prepareRefresh();
// 关闭释放旧的beanFactory创建新的beanFactory,读取配置文件等
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对beanFactory进行一些基本的初始化
prepareBeanFactory(beanFactory);
try {
// 下面两行主要用户扩展,处理所有已注册的BeanFactoryPostProcessor,实现在已经加载配置但未初始化bean时对配置进行修改
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
// 处理所有已注册的BeanPostProcessor,主要用于扩展,实现bean初始化前后的一些定制操作
registerBeanPostProcessors(beanFactory);
// 初始化消息源bean
initMessageSource();
// 初始化事件监听器集,也有人叫事件监听器的注册表,所有的事件监听器都在这个bean里进行管理
initApplicationEventMulticaster();
// 主要用于扩展,实现一些特殊bean的初始化,时间点是类似消息源事件监听器集等特殊bean初始化后,普通的bean初始化前
onRefresh();
// 注册监听器
registerListeners();
// 初始化其余的非延迟加载的单例bean
finishBeanFactoryInitialization(beanFactory);
// 刷新完成调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件
finishRefresh();
} catch (BeansException ex) {
// 销毁已经创建的单例bean
destroyBeans();
// 重新设置active标记
cancelRefresh(ex);
throw ex;
}
}
}