IoC:控制反转,即把对象交由spring容器进行统一的管理,不需要再手动的new,不仅降低了代码的耦合性,而且提高了程序的易扩展性和健壮性。
spring的初始化过程可以简化为,获取资源定位,载入资源,解析资源(例如xml声明的bean和注解声明的),由相应的BeanDefinitionReader转换成一个个beanDefinition,
然后再有工厂创建和统一管理。BeanDefinitionRegistry负责将bean注册,BeanFactory负责bean的管理。DefaultListableBeanFactory则同时直接和间接实现了上述2个接口,DefaultListableBeanFactory是spring 框架中比较通用的一个BeanFactory。
spring对beanFactory接口下提供几个扩展的子接口
ListableBeanFactory:提供了列举所有bean和bean的类型
HierarchicalBeanFactory:提供了层级的beanFactory,拥有一个获取父类beanFactory的工厂。
AutowireCapableBeanFactory:为已经实例化的对象装配属性,这些属性对象都是Spring管理的。实例化一个类型,并自动装配,这些属性对象都是Spring管理的
ApplicationContext是spring容器核心的容器接口,包含了运行环境的配置,bean实例的获取,spring bean注册资源的定位和装载,事件的发布,国际化信息的接口。
。
我们这里以ClassPathXmlApplicationContext的spring容器初始化,来对ioc容器做个简单的讲解。
ClassPathXmlApplicationContext是以xml的形式加载spring 容器的。实现类提供了多个构造器的重载,首先调用setConfigLocations获取xml文件资源,文件支持默认支持ANT风格,
调用了AbstractApplicationContext的refresh方法,该方法会销毁并重新载入spring容器。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
刷新spring容器前的准备工作,设置容器当前时间,和一些准备工作
// Prepare this context for refreshing.
prepareRefresh();
销毁并刷新spring容器
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
为bean工厂配置设置bean的类加载器,spel表达式解析器,以及一些忽略一些自动注入的接口和注册一些自动注入的接口,添加BeanPostProcessor后置处理器
// 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) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
refresh是创建spring容器的核心方法,代码如上。
1.prepareRefresh()
设置容器启动时间和一些标志位和属性资源的初始化。
2.obtainFreshBeanFactory();
获取刷新后的工厂,
销毁和创建新的工厂,并加载加载beandefine到新的spring工厂
更据依赖的关系递归的创建beandefinition,并将其添加至工厂内。
3.prepareBeanFactory(beanFactory);
在上下文使用前,再对工厂进行一些准备工作,设置bean的类加载器,spel表达式的解析器,以及自动注入该忽略的类,注册自动注入的类。。。等。
4.postProcessBeanFactory(beanFactory);
工厂bean实例初始化前,调用beanFactory的后置处理
5.invokeBeanFactoryPostProcessors(beanFactory);
调用实现了BeanFactoryPostProcessor的beanDefinition的钩子方法,比如修改beanDefinition的属性啊,做一些实例化前的准备工作。比如
在Spring项目的XML配置文件中,经常可以看到许多配置项的值使用占位符,我们可以将占位符所代表的值单独配置到独立的properties文件,容器会自动帮我们解析占位符,底层的工作就是由PropertyPlaceholderConfigurer负责实现的。它间接的实现了BeanFactoryPostProcessor接口。当BeanFactory在第一阶段加载完所有配置信息时,BeanFactory中保存的对象的属性还是以占位符方式存在的,比如 ${port}。当PropertyPlaceholderConfigurer作为BeanFactoryPostProcessor被应用时,它会使用properties配置文件中的值来替换相应的BeanDefinition中占位符所表示的属性值。当需要实例化bean时,bean定义中的属性值会被替换成我们配置的值。
6.registerBeanPostProcessors(beanFactory);
向工厂注册实现了BeanPostProcessors的bean。该接口方法会在每个bean实例化前后,调用其钩子方法。
/*
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
7.initMessageSource();
向工厂注册消息资源的bean,与国家化信息有关的。
8.initApplicationEventMulticaster();
发布spring的事件。事件驱动模型,也就是我们所说的观察者模式。观察者模式有3个对象,目标,观察者,和发布者。容器会检查是否存在name为applicationEventMulticaster的bean,这就是spring事件的发布者,如果没有回创建一个SimpleApplicationEventMulticaster实例,添加至工厂中。观察者模式的好处就是:解耦目标对象和它的依赖对象,目标只需要通知它的依赖对象,具体怎么处理,依赖对象自己决定。
9.finishBeanFactoryInitialization(beanFactory)
递归的创建不是懒加载的bean到spring容器中。
10.finishRefresh()
执行容器最后完成前的操作
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
从工厂中获取lifecycleProcessor的实例,如果没有就创建一个默认的。lifecycleProcessor提供了感知容器启动和关闭的方法。
initLifecycleProcessor();
调用其刷新方法
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
发布上下文刷新事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}