创建Bean系列一之概述
如果在缓存中不存在已经加载的单例Bean,就需要从头开始bean的加载过程。Spring中使用getSingleton的重载方法实现bean的加载过程。public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name mu
如果在缓存中不存在已经加载的单例Bean,就需要从头开始bean的加载过程。Spring中使用getSingleton的重载方法实现bean的加载过程。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
//先检查对应的bean是否被加载过
Object singletonObject = this.singletonObjects.get(beanName);
//如果没有加载过,则开始进行单例bean的初始化加载
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 {
//初始化bean
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;
}
}
getSingleton方法在单例创建的前后做一些准备和处理的操作。而真正获取单例bean是有singletonFactory.getObject()实现。
getSingleton的主要逻辑
(1)检查缓存中是否已经加载过。
(2)如果没有加载,则记录beanName的正在加载状态
(3)加载单例前记录加载状态
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中,为后续循环依赖提供检测。
(4)调用singletonFactory.getObject()实例化bean
if (mbd.isSingleton()) {
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
创建单例bean的逻辑是函数式接口ObjectFactory的逻辑中的
(5)加载单例后的处理方法调用
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
当bean加载结束后需要移除缓存中对该bean的正在加载状态的记录。
(6)将结果记录在缓存中,删除加载bean过程中所记录的各种辅助状态
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
(7)返回单例bean
一、准备创建bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//锁定class,根据设置的class属性或者根据className来解析Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}try {
//给BeanPostProcessors一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
1、代码逻辑
(1)根据设置的class属性或者根据className来解析Class
(2)对override属性进行标记和验证
在Spring配置中存在lookup-method和replace-method,这两个配置的加载统一放在BeanDefinition中的methodOverrides属性里。此处的override属性就是处理这两个配置的。
(3)应用初始化前的后置处理器,解析指定bean是否存在初始化前的短路操作。
(4)创建bean。
2、处理override属性
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
//获取对应类中对应方法名的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
//标记methodoverrides暂未被覆盖,避免参数类型检查的开销
mo.setOverloaded(false);
}
}
这里的override属性其实就是BeanDefinition中的methodOverrides属性,methodOverrides属性会在bean实例化时动态的为当前bean生成代理并使用对应的拦截器为bean做增强。
这里主要的override属性验证是用来处理类中的方法匹配,如果一个类中有若干个重载方法,那么在函数调用及增强的时候含需要根据参数类型进行匹配,来最终确认当前调用的是哪一个函数。如果当前类中方法只有一个,那么不存在重载方法,这样在后面调用的时候,可以直接使用找到的方法,而不需要进行方法的参数验证。
3、实例化的前置处理
在调用doCreate方法创建bean的实例前调用resolveBeforeInstantiation方法对BeanDefinition中的属性做前置处理。这也是给创建bean前后提供的可扩展的一种体现。同时,前置操作可以实现短路判断。
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;
}
(1)applyBeanPostProcessorsBeforeInstantiation(实例化前的后置处理)
bean在实例化前,给子类修改BeanDefinition的机会,当程序经过这个方法后,bean可能已经不是之前的bean了,或许成为一个经过处理的代理bean,可能是通过cglib生成的,也可以是通过其他方式生成的。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { //由子类覆写postProcessBeforeInstantiation Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } return null; }default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; }
(2)applyBeanPostProcessorsAfterInitialization(实例化后的后置处理器)
从缓存中获取单例bean的时候提到,Spring中的规则是在bean初始化后尽可能保证将注册的后置处理器的postProcessorsAfterInitialization方法应用到该bean中,因为如果返回bean不为空,那么便不会再次经历普通的bean的创建过程,所以只能在这里应用后只处理器的postProcessorsAfterInitialization方法。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { //由子类覆写postProcessAfterInitialization Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
二、创建bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如工厂方法,构造函数自动注入
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}//是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂,aop
//在这里将advice动态织入bean中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入,其中可能存在依赖其他bean的属性,则递归初始依赖bean。
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法,如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
//earlySingletonReference只有检测到有循环依赖的情况下才不会为空
if (earlySingletonReference != null) {
//exposedObject没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//因为bean创建后其所依赖的bean一定是已经创建的,actualDependentBeans不为空
//则表示当前bean创建后其依赖的的bean却没有全部创建完成,说明出现循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}return exposedObject;
}
1、doCreateBean的整体思路
(1)如果是单例,则先清除缓存
(2)实例化bean,将BeanDefinition转换为BeanWrapper
a)如果存在工厂方法则使用工厂方法进行初始化
b)一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
c)如果既不存在工厂方法也不存在有参数的构造函数,则使用默认的构造函数进行bean的实例化。
(3)MergedBeanDefinitionPostProcessor的应用,bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析。
(4)依赖处理
在Spring中会有循环依赖的问题,例如,当A有B属性时,而B中有A属性时就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入的缓存池的ObjectFactory来创建实例。
(5)属性填充
将所有属性填充到bean实例中。
(6)循环依赖检查
spring解决循环依赖只对单例有效,而对于prototype的bean,spring没有好的解决办法,唯一要做的就是抛出异常。在循环检查步骤里会检查已经加载的bean是否已经出现循环依赖,并判断是否要抛出异常。
(7)注册DisposableBean
如果配置了destroy-method,这里需要注册以便在销毁时调用。
(8)完成创建并返回
更多推荐


所有评论(0)