引言
在执行ac.getBean("car")的过程中,spring如何加载bean的?
FactoryBean
public interface FactoryBean<T>
{
//......
}
当配置文件<bean>中的class的类是FactoryBean接口的实现类时,getBean返回的就不是对应的类,而是这个实现类调用get
Object()方法所返回的对象,相当于是getObject()代理了getBean()类
从缓存中获取单例类
单例在spring中只会创建一次,后续获取bean直接从单例缓存中获取,首先尝试从缓存中加载,后序在尝试从SingletonFactories中获取.
Spring创建bean的原则就是在创建一个bean时候,不等bean创建完成就将ObjectFactory提早曝光到缓存中.下次有bean依赖到这个已经创建的bean的时候,就直接使用ObjectFactory
Object sharedInstance = getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
首先查看缓存中是否有实例,如果有就获取
如果没有的话,全局加锁,在从earlySingletonObjects中获取,如果还是获取不到,就从singletonFactories中获取BeanName对应的ObjectFactory,然后调用这个singletonFactory来创建singletonObject,然后放到earlySingletonObjects中去,然后从singletonFactories清除掉这个beanName.
其中有大量的map,我们来进行梳理一下:
- singletonObjects bean和BeanName的关系如果其中有bean,就可以直接创建
- singletonFactories BeanName和Bean工厂之间的关系
- earlySingletonObjects BeanName和bean,主要是用来做循环检验的
这个时候我们就获取到了beanName对应的bean了
从bean的实例中获取对象
如果缓存不为空的话,我们就已经获取到实例了,记住这个时候我们是从缓存中获取的实例,然后我们继续回到最开始的方法
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
我们进入到这个方法中
这个代码大概的意思就是,尝试从缓存中获取加载bean,如果加载失败,我们就可以明确的知道是Factorybean类型的,然后调用getObjectFromFactoryBean这个方法,其中doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
object = factory.getObject();之后回到上一层代码,会调用如下的一段代码
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
这个就是后处理器的使用,在后面我们会详细的介绍
创建单例
sharedInstance = getSingleton(beanName, () -> {
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,然后从bean的实例中获取对象.接下来就是如果缓存中没有bean,我们该怎么办,我们进入到这个重载的getSingleton中
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
其中singletonObject = singletonFactory.getObject();是初始化bean的,我们来看看在它之前都做了些什么?检查和记录
beforeSingletonCreation(beanName);和 afterSingletonCreation(beanName);都是用来记录加载状态的,最后将缓存假加入到缓存中,并删除一些缓存记录.
我们已经了解了bean的逻辑架构,真正的bean加载过程是在传入的匿名内部类中实现的
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
我们来深入了解createBean方法.
首先是解析Class,然后是对override方法进行标记和验证
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
try {
mbdToUse.prepareMethodOverrides();
}
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization是对getSingleton方法中的后处理的调用,
bean在实例化前会有一个后处理器的调用,将AbstractBeanDefinition转化成BeanWrapper,经过处理这有可能是一个经过处理的bean,而后处理的过程,就是将bean注册的过程,当bean再次使用时,就不必在进行创建了
创建bean
然后我们进入到doCreateBean方法中,这里是常规的bean操作.
如果是单例,首先需要清除缓存.实例化bean,将BeanDefinition转换为BeanWrapper.使用工厂方法,使用构造方法,使用默认构造方法