在Spring Boot经过一系列的准备工作后,在finishBeanFactoryInitialization()函数中开始真正地创建Bean。创建Bean的过程是Spring IoC的核心,完成对Bean创建由用户到Spring控制的转移。
以被@Component注解的Bean创建为例。从类AbstractApplicationContext的refresh()函数开始,调用finishBeanFactoryInitialization()。
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
进入函数finishBeanFactoryInitialization()后,直接来到函数的最后一行,调用类DefaultListableBeanFactory中的函数preInstantiateSingletons()实例化所有余下的单例Bean。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//...略去部分代码...
// 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();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons()函数调用父类AbstractBeanFactory的getBean()方法实例化,走到下面代码的31行,Spring Boot源码中的761行(1.5.7.RELEASE版本)。
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("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<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
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 {
getBean(beanName);
}
}
}
//...略去部分代码...
}
getBean()方法调用AbstractBeanFactory类中的doGetBean()方法。这里是Spring Boot实例化Bean的公共逻辑,不仅用户自定义的Bean实例化会调用这个函数,其他的包括系统需要实例化的processors,上下文信息等都共用这里逻辑进行Bean的实例化。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
doGetBean()方法比较长,会先判断缓存中是否已经存在了实例化的Bean。我们的示例中不存在Bean与Bean依赖关系,首次创建缓存查询返回null,直接创建实例化Bean。Spring设置三级缓存处理Bean的依赖关系,实例化Bean之前还需要先实例化当前Bean所依赖的Bean,另外三级缓存可以解决Bean的循环依赖,关注公众号《 魔法师和ta的南瓜小屋》中其他文章详细介绍。
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//...略去部分代码...
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//...略去部分代码...
return (T) bean;
}
执行类AbstractAutowireCapableBeanFactory中的createBean()函数。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
//...略去部分代码...
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
调用类AbstractAutowireCapableBeanFactory中的doCreateBean()函数后,继续调用其createBeanInstance()函数和instantiateBean()函数。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
//...略去部分代码...
return exposedObject;
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//...略去部分代码...
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
类AbstractAutowireCapableBeanFactory中的instantiateBean()函数,使用了一个设计模式——策略模式,把Bean的实例化委托给了一个简单的实例化策略类进行。
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
//...略去部分代码...
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
//...略去部分代码...
}
类SimpleInstantiationStrategy中instantiate()调用类BeanUtils的static方法instantiateClass()进行实例化。
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
//...略去部分代码...
return BeanUtils.instantiateClass(constructorToUse);
//...略去部分代码...
}
BeanUtils.instantiateClass()通过Java反射机制,利用构造函数对Bean进行最终的实例化,生成一个新的Bean。而Bean的类信息是通过BeanDefinition结构获得的。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}