IOC容器初始化时,创建所有单例的bean,今天深入探索IOC容器的实质:
其内部的创建代码如下:
调用了本类的另一个构造器方法
根据beanName获取所有单例模式的bean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
而singtonObjects,此属性的定义如下:
我们发现这些单例的对象其实是保存在一个map中
这个所谓的IOC容器就是一个map,所有的单例都保存在这个map中
具体流程:
ioc容器一启动就调用初始化---->AbstractApplicationContext.refresh()---->初始化所有的单实例对象
---->AbstractApplicationContext.finishBeanFactoryInitialization()----->调用getBean初始化bean
---->所有的getbean又调用AbstractBeanFactory.doGetbean();---->调用doGetBean的getSingleton(beanName);
---->第一次ioc初始化烦hi的是null,第二去调用getBean通过这个方法就已经返回了
bean实例,调用的是DefaultSingletonBeanRegistry.getSingleton();
就是从singletonObjects里面拿出对应的bean。
singletonObjects是一个map,声明如下,
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
这就是我们保存所有单实例对象的地方,ioc容器。
IOC容器初始化即创建ClassPathXmlApplicationContext对象,如下:
ApplicationContext ioc = new ClassPathXmlApplicationContex("applicationContext.xml");
其内部的创建代码如下:
ClassPathXmlApplicationContext类中的构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
调用了本类的另一个构造器方法
ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
//设置本地参数
setConfigLocations(configLocations);
if (refresh) {
//创建IOC容器
refresh();
}
}
创建IOC容器的方法在org.springframework.context.support.AbstractApplicationContext
@Override
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();
//准备beanFactory
// 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();
//初始化beanFactory
// 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;
}
}
}
初始化beanFactory即调用本类的方法,如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
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));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
//初始化所有的单实例bean
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
至此初始化所有的单实例bean,调用org.springframework.beans.factory.support.DefaultListableBeanFactory的preInstantiateSingletons()方法
//创建所有的单实例bean
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
//获得所有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);
}
//遍历所有beanName的集合
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>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
//从IOC容器中获取bean,如果没有这个bean,
//就去创建一个bean,并返回,如果有就从容器中拿
getBean(beanName);
}
}
}
}
从IOC容器中获取bean,即执行org.springframework.beans.factory.support.AbstractBeanFactory类中的getBean方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
所有的getbean方法皆调用了本类的doGetBean方法
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
...
//根据beanName获得所有单例模式的bean
Object sharedInstance = getSingleton(beanName);
...
根据beanName获取所有单例模式的bean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
如下即是具体的方法代码
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从这个类的singletonObjects属性中获取
Object singletonObject = this.singletonObjects.get(beanName);
...
而singtonObjects,此属性的定义如下:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
我们发现这些单例的对象其实是保存在一个map中
这个所谓的IOC容器就是一个map,所有的单例都保存在这个map中
具体流程:
ioc容器一启动就调用初始化---->AbstractApplicationContext.refresh()---->初始化所有的单实例对象
---->AbstractApplicationContext.finishBeanFactoryInitialization()----->调用getBean初始化bean
---->所有的getbean又调用AbstractBeanFactory.doGetbean();---->调用doGetBean的getSingleton(beanName);
---->第一次ioc初始化烦hi的是null,第二去调用getBean通过这个方法就已经返回了
bean实例,调用的是DefaultSingletonBeanRegistry.getSingleton();
就是从singletonObjects里面拿出对应的bean。
singletonObjects是一个map,声明如下,
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
这就是我们保存所有单实例对象的地方,ioc容器。