spring容器启动过程简要分析

1、ContextLoaderListener 创建以及初始化
在web.xml中配置org.springframework.web.context.ContextLoaderListener 的时候自动实例化ContextLoaderListener ,ContextLoaderListener类实现了javax.servlet.ServletContextListener接口,在web容器启动的时候会调用javax.servlet.ServletContextListener#contextInitialized,然后再ContextLoaderListener 的contextInitialized方法中会初始化实例化WebApplicationContext,调用日志框架、创建父context以及Refresh  WebApplicationContext(configureAndRefreshWebApplicationContext
方法),在此方法中还会将配置文件加载到context中,最主要的是调用refresh()方法,实际上是XmlWebApplicationContext的祖师爷类 org.springframework.context.support.AbstractApplicationContext#refresh。
2、ApplicationContext的refresh
AbstractApplicationContext#refresh方法都做了什么东西?
 (1)、prepareRefresh(),即准备阶段,初始化配置文件、以及系统环境变量验证
   (2)、创建一个ConfigurableListableBeanFactory实例,ConfigurableListableBeanFactory是spring一个非常重要的接口,也是spring容器的BeanFactory,在创建之前会refreshBeanFactory,spring在创建之前都是先refresh,这个refreshBeanFactory方法做啥呢,首先判断是否存在beanfactory ,如果存在就销毁bean和benafactory,如果不存在则进行创建,创建的ConfigurableListableBeanFactory实例实际上就是DefaultListableBeanFactory实例,这个类伴随着spring容器的生命周期由始而终。然后就是创建客户化的beanfactory,然后就是loadBeanDefinitions,这个就是导入所有xml配置文件的关键方法,从这个方法开始的,这个方法是抽象方法,委托给子类处理的,web容器启动的话则是由XmlWebApplicationContext类处理的,此类loadBeanDefinitions方法
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//根据给定的beanfactory创建xml处理器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

// Configure the bean definition reader with this context's
// resource loading environment.
//给xml处理器实例设置环境
beanDefinitionReader.setEnvironment(getEnvironment());
//设置资源文件的loader
beanDefinitionReader.setResourceLoader(this);
//xml文件具体处理类
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
// 空方法,给子类扩展用的
initBeanDefinitionReader(beanDefinitionReader);
//beanDefinitionReader实例去处理配置文件
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}

接下来就都是解析xml文件

spring 读xml文件,如果配置多个xml文件,循环读
解析xml文件的时候先创建NamespaceHandlerResolver(createDefaultNamespaceHandlerResolver)
即为DefaultNamespaceHandlerResolver,实例化的时候DefaultNamespaceHandlerResolver将要处理的spring.handlers(META-INF/spring.handlers,spring通过这里扩展)
设置到handlerMappingsLocation属性上,通过DefaultNamespaceHandlerResolver.resolver方法返回NamespaceHandler,
NamespaceHandler.parse方法解析自定义的xml文件,
什么时候读META-INF/spring.handlers文件的呢?
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve方法中会获得getHandlerMappings,
会通过这个方法load handlers文件(PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);)

(3)、prepareBeanFactory准备beanfactory
    给beanfactory设置classLoader,设置表达式解析器,设置配置文件读取器,设置ApplicationContextAwareProcessor以及设置忽视依赖的类,注册需要依赖的类等等
(4)、postProcessBeanFactory
       Register request/session scopes
(5)invokeBeanFactoryPostProcessors和registerBeanPostProcessors
    invokeBeanFactoryPostProcessors方法是处理所有实现BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的类,调用postProcessBeanFactory、
postProcessBeanDefinitionRegistry
方法,(BeanFactoryPostProcessor是一个很重要的接口,所有spring的扩展都实现了这个接口,包括spring生态圈的spring-context、spring-jdbc、spring-webmvc、spring-web、spring-tx等等,以及dubbo、mybatis等)

registerBeanPostProcessors方法就是Register bean processors that intercept bean creation

(6)registerListeners注册监听器

(7)finishBeanFactoryInitialization完成beanfactory的初始化,其中会调用preInstantiateSingletons,这个方法中会将所有注册到DefaultListableBeanFactory的bean全部实例化



public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}

List<String> beanNames;

//beanDefinitionNames为注册beanfactory的beanname

synchronized (this.beanDefinitionMap) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}














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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值