Spring容器启动,扫描得到所有BeanDefinition之后,就会先实例化所有非懒加载的单例Bean的
入口
Spring容器启动刷新的方法里:
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
我们知道beanFacotory就是DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 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.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//1. 合并BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//判断BeanDefinition,非抽象,是单例,非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//2. FactoryBean逻辑,第二节提到过
if (isFactoryBean(beanName)) {
//FACTORY_BEAN_PREFIX="&"
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {...}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
//创建真正的Bean对象(这里是FactoryBean.getObject()对象)
getBean(beanName);
}
}
}
else {
//3. 创建Bean对象
getBean(beanName);
}
}
}
// 4. 所有非懒加载单例Bean都创建完成后
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
// 从单例池里拿beanName对应的单例Bean(里面实现涉及到循环依赖,以后讲,先简单理解)
Object singletonInstance = getSingleton(beanName);
// 判断单例Bean是否实现了SmartInitializingSingleton接口
// 这个接口也属于Spring生命周期里的一种接口
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {...}
else {
//触发afterSingletonsInstantiated方法
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
1. 合并BeanDefinition
应用场景
通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition,和Java父子类类似,但是完全不是一回事。
BeanDefinition也可以设置成抽象的,这样该BeanDefinition就不会创建Bean实例,可以被其他BeanDefinition继承(不设置抽象也能继承)
父子BeanDefinition实际用的比较少,使用是这样的,比如:
这么定义的情况下,child是单例Bean:
<bean id="parent" class="com.yth.service.Parent" scope="prototype"/>
<bean id="child" class="com.yth.service.Child"/>
但是这么定义的情况下,child就是原型Bean了:
<bean id="parent" class="com.yth.service.Parent" scope="prototype"/>
<bean id="child" class="com.yth.service.Child" parent="parent"/>
因为child的父BeanDefinition是parent,所以会继承parent上所定义的scope属性。
而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整的child的BeanDefinition。
源码分析
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 合并过,就直接返回
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
mergedBeanDefinitions:合并之后的BeanDefinition Map,value就是RootBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {...}
if (mbd == null || mbd.stale) {
previous = mbd;
// 判断有没有父亲
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
// 没有parent就生成一个新的RootBeanDefinition
if (bd instanceof RootBeanDefinition) {
//复制新的
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
//new新的
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
// 获取parentName对应的BeanDefinition
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
//递归获取父亲的RootBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
//如果beanName和parentName一样,则从父亲工厂里获取BeanDefinition
else {...}
}
//最终获取不到会抛异常
catch (NoSuchBeanDefinitionException ex) {...}
// Deep copy with overridden values.
// 深拷贝,生成一个RootBeanDefinition
// 先基于父BeanDefinition生成RootBeanDefinition
mbd = new RootBeanDefinition(pbd);
// 然后和自己合并,自己优先级更高
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {...}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {...}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
//保存到mergedBeanDefinitions Map
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {...}
return mbd;
}
}
真正创建Bean的时候,用的是合并之后的这个Map:mergedBeanDefinitions
2. FactoryBean
2.1 判断是否是FactoryBean
org.springframework.beans.factory.support.AbstractBeanFactory#isFactoryBean(java.lang.String)
这个方法除了这,其他地方也会掉
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
//先从单例池获取FactoryBean本身的对象
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
//没有拿到FactoryBean本身的对象,则根据BeanDefinition对象来判断
// 当前容器没有name对应的BeanDefinition,则从父容器获取
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
//拿到合并后的BeanDefinition判断是否是FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
//根据BeanDefinition的isFactoryBean属性判断
Boolean result = mbd.isFactoryBean;
if (result == null) {
//isFactoryBean属性缓存为空,则直接根据类的类型判断
//根据BeanDefinition推测Bean类型(获取BeanDefinition的beanClass属性)
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
//判断是否实现了FactoryBean接口
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
mbd.isFactoryBean = result;
}
return result;
}
BeanDefinition里的很多属性,其实是起到缓存的作用,一开始为null也不影响,会去专门解析,然后在保存起来作为缓存使用。
2.2 创建FactoryBean本身的对象
getBean源码见2.4(带一点)、或者3(下一章节讲解)。
2.3 SmartFactoryBean
如果我们FactoryBean实现的是SmartFactoryBean接口:
并重写了isEagerInit方法,返回true:
那么Spring容器启动的时候,就会把改FactoryBean对应的getObject()方法的对象生成,否则只有getBean的时候才会生成。
没有调getBean已经有了:
2.4 FactoryBean的getObject触发时机
FactoryBean对应的getObject对象是通过调容器getBean方法实例化的
- beanName获取FactoryBean的getObject对象
- “&” + beanName获取FactoryBean本身的对象
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//name有可能是 &xxx 或者 xxx
//如果name是&xxx,beanName返回的beanName就是xxx
//name如果是别名,beanName就是id
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {...}
//如果sharedInstance是FactoryBean,那么就调用getObject()返回对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {...}
return adaptBeanInstance(name, beanInstance, requiredType);
}
//name是&xxx或者xxx
//beanName是xxx
//beanInstance从单例池里拿到的bean
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 判断name是不是带了&符号,是的话就是FactoryBean的引用
if (BeanFactoryUtils.isFactoryDereference(name)) {
//走到这说明想获取FactoryBean本身
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//判断从单例池里拿到的Bean是不是FactoryBean
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
//是,则直接返回
return beanInstance;
}
//走到这说明想获取的是普通Bean对象,或者FacotryBean的getObject对象
// 单例池里的对象不是FactoryBean,则直接返回
if (!(beanInstance instanceof FactoryBean)) {
//返回普通对象
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//先从缓存拿
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//核心在这里
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
//多线程同时来创建需要控制,保证单例
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//核心在这
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {...}
else {
//是否要进行后处理,可以发现FactoryBean只会经过“初始化后”的生命周期
if (shouldPostProcess) {...}
if (containsSingleton(beanName)) {
//放到缓存
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
//FactoryBean也支持多例情况
else {...}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {...}
else {
//这里调用了FactoryBean的getObject方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {...}
catch (Throwable ex) {...}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {...}
object = new NullBean();
}
return object;
}
3. 创建Bean对象
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
下一章节讲。
4. SmartInitializingSingleton
应用场景
定义一个单例Bean的时候,可以实现SmartInitializingSingleton接口,它会在所有非懒加载的单例Bean都创建成功以后触发。注意!!是在所有!
源码分析
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons