Spring IOC容器分为两部分:创建、实例化
引言
pom.xml中引入(引入当前即可,会自动把spring其他基础jar包引入):
org.springframework
spring-context
4.3.11.RELEASE
然后使用:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
继承体系如下:
使用例子:
//获取bean 当前context就是上面拿到的ApplicationContext
MessageService messageService = context.getBean(MessageService.class);
messageService.getMessage();
-applicationContext.xml为:
BeanFactory简介
作用:负责生产和管理bean实例。
1 BeanFactory(org.springframework.beans.factory):
作用:提供最基础的容器查看的功能,保存了bean的定义,并且可以根据不同条件获取bean,查看bean是否单利,获取bean的别名。有一个&用来表示获取工厂本身而不是获取到工厂的实例。
学到了什么?
bean生命周期:一堆接口->init-method->BeanPostProcessors接口(一切就绪之后的接口)->destory-method()。
可给bean指定别名。
bean工厂有层级关系,找bean过程是:从子到父。
2 ListableBeanFactory(org.springframework.beans.factory):
作用:返回一系列bean,根据不同的条件获取。
学到了什么?
提供了list的bean工厂,可以枚举每一个bean定义。或者获取bean信息或者bean的实例。使用时不需要考虑已经注册了的bean和层级关系。
3 EnvironmentCapable(org.springframework.core.env):
作用:实现spring上下文的接口,获取上下文。可通过如下获取:
Environment getEnvironment();
4 HierarchicalBeanFactory:层级分层
启动过程分析
先从入口类ClassPathXmlApplicationContext.java看起:
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private Resource[] configResources;
public ClassPathXmlApplicationContext() {
}
// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
setConfigLocations(configLocations);
if (refresh) {
refresh(); //重点!!!
}
}
@Override
protected Resource[] getConfigResources() {
return this.configResources;
}
.....................
.....................
}
refresh()将原来ApplicationContext销毁后重新执行初始化操作,其代码如下(AbstractApplicationContext.java 446):
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
// 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置beanFactory类加载器,添加多个beanPostProcesser
prepareBeanFactory(beanFactory);
try {
// 允许子类上下文中对beanFactory做后期处理
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessor各个实现类的方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
//初始化ApplicationContext的MessageSource
initMessageSource();
//初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
// 初始化子类特殊bean(钩子方法)
onRefresh();
// 注册事件监听器
registerListeners();
// 初始化所有singleton bean 重点!!重点!!
finishBeanFactoryInitialization(beanFactory);
// 广播事件,ApplicationContext初始化完成
finishRefresh();
} catch (BeansException ex) {
....................
}
refresh详细流程解析如下:
1 prepareRefresh():准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写。
2 obtainFreshBeanFactory()
-(AbstractApplicationContext.java 536):重要!!==>初始化beanFactory,注册Bean
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新上下文环境,关闭旧的beanFactory,并创建新的
refreshBeanFactory();
//返回刚创建的beanFactory (return this.beanFactory;)
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
2.1 obtainFreshBeanFactory()->refreshBeanFactory()
-(AbstractRefreshableApplicationContext.java 120):
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) { //关闭旧的beanFactory
destroyBeans();
closeBeanFactory();
}
try {//创建新的beanFactory(创建的是DefaultListableBeanFactory)
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId()); //然后重新设置在closeBeanFactory()置为null的serialzationId
customizeBeanFactory(beanFactory); //自定义beanFactory,设置是否允许覆盖、是否循环引用标识
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch........................................
}
2.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->destroyBeans()
-(AbstractApplicationContext.java 907):
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
销毁所有beans,默认实现是销毁所有缓存的单例。这里提供了一个模板方法模式,在DefaultListableBeanFactory.java、DefaultSingletonRegistry.java做了具体的实现。其中DefaultListableBeanFactory 实现了基本实现了上层所有接口含注解的AbstractAutowireCapableBeanFactory.java,所以DefaultListableBeanFactory是最牛逼的BeanFactory。
2.1.2 obtainFreshBeanFactory()->refreshBeanFactory()->closeBeanFactory()
-(AbstractRrefreshableApplicationContext.java 149):
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}
将beanFactory和serializationId设置为null。
2.1.3 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations() !!重要!!
-(AbstractRrefreshableApplicationContext.java 80):
根据配置加载各个bean,然后放到BeanFactory中
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 将beanFactory传入XmlBeanDefinitionReader中,并解析、加载配置
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 配置beanDefination,环境资源加载如
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//加载beanFactory 重要!!
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
2.1.3.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()
-(AbstractXmlApplicationContext.java 120):
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources(); //新建一个ClassPathResource
if (configResources != null) {
reader.loadBeanDefinitions(configResources); //加载beandefation
}
String[] configLocations = getConfigLocations();//加载beandefation
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
2.1.3.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->getConfigResources()
-(ClassPathXmlApplicationContext.java 202):
protected Resource[] getConfigResources() {
return this.configResources;
}
2.1.3.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->loadBeanDefinitions()
-(AbstractBeanDefinitionReader.java 177):
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource); //调用了XmlBeanDefintionReader.java的loadBeanDefinitions
}
return counter;
}
上面会一个个加载并返回加载的数量。
2.1.3.1.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->loadBeanDefinitions()->loadBeanDefinitions()
-(XmlBeanDefinitionReader.java 303):
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
/**
* 从指定xml解析beanDefination
*/
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
....................................
//使用ThreadLocal存放配置文件资源
Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
........................................
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//装饰者模式包装
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//真实从指定xml解析beanDefination !重点!
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
..................................
} catch (IOException ex) {
...................................
} finally {
.............................
}
}
//==>真实从指定xml解析beanDefination===========================
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//将xml转为document对象
Document doc = doLoadDocument(inputSource, resource);
//用给定的dom文档注册beanDefinition
return registerBeanDefinitions(doc, resource);
}catch............................
}
接下来的解析过程就不详细探讨,到这里初始化了bean容器,将xml配置转成BeanDefinition,并注册了,发送了注册事件。
上面讲完了refresh()的obtainFreshBeanFactory()如下:
接下来我们继续往下看:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
// 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置beanFactory类加载器,添加多个beanPostProcesser
prepareBeanFactory(beanFactory);
try {
// 允许子类上下文中对beanFactory做后期处理
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessor各个实现类的方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
//初始化ApplicationContext的MessageSource
initMessageSource();
//初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
// 初始化子类特殊bean(钩子方法)
onRefresh();
// 注册事件监听器
registerListeners();
// 初始化所有singleton bean 重点!!重点!!
finishBeanFactoryInitialization(beanFactory);
// 广播事件,ApplicationContext初始化完成
finishRefresh();
} catch (BeansException ex) {
....................
}
上面的基本注释已经很明显了,所以可跳过上面的直接将finishBeanFactoryInitialization(),这步负责初始化所有singleton bean。
3 finishBeanFactoryInitialization()
-AbstractApplicationContext.java 736
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化名字为conversionService的bean
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 初始化LoadTimeWeaverAware相关bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时类加载器进行类型匹配,置null
beanFactory.setTempClassLoader(null);
// 冻结(this.configurationFrozen = true;)所有beanDefinition,不让bean继续注册
beanFactory.freezeConfiguration();
// 实例化所有剩余的(非延迟-init)单例
beanFactory.preInstantiateSingletons();
}
//---------------------------------
// 实例化所有剩余的(非延迟-init)单例
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 拿到所有beanName 去遍历
List beanNames = new ArrayList(this.beanDefinitionNames);
// 触发所有非懒加载的singleton bean的初始化
for (String beanName : beanNames) {
//将非RootBeanDefinition转换为RootBeanDefinition以方便后续操作,
//因为Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//如果当前“不是抽象类 && 是单例 && 不是延迟加载” 则执行
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) { //判断是否factoryBean
//返回一个共享或独立的实例
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
//安全管理器部分,先不管他,有兴趣可去看
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
//返回一个实例
getBean(beanName);
}
} else {
getBean(beanName);
}
}
}
// 为所有适合的bean触发初始化后回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction