由于 getBean 内容比较多, 所以单独出来, 接着上一篇的顺序来看.
复制代码
//org.springframework.beans.factory.support.AbstractBeanFactory#getBean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
复制代码
doGetBean里面, 有一堆乱七八糟的判断,
复制代码
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两个原因
* 1、name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean
* 实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储
* 方式是一致的,即 <beanName, bean>,beanName 中是没有 & 这个字符的。所以我们需要
* 将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。
* 2、还是别名的问题,转换需要
* &beanName
*/
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 这个方法在初始化的时候会调用,在getBean的时候也会调用
* 为什么需要这么做呢?
* 也就是说spring在初始化的时候先获取这个对象
* 判断这个对象是否被实例化好了(普通情况下绝对为空====初始化完之后, 此处返回就不是空了)
* 从spring的bean容器中获取一个bean,由于spring中bean容器是一个map(singletonObjects)
* 所以你可以理解getSingleton(beanName)等于beanMap.get(beanName)
* 由于方法会在spring环境初始化的时候(就是对象被创建的时候调用一次)调用一次
* 还会在getBean的时候调用一次
*
* 需要说明的是在初始化时候调用一般都是返回null
*/
Object sharedInstance = getSingleton(beanName);
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 + "'");
}
}
/**
* 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。
* 但如果 sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的 bean 实例。
* 如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回即可。
* 毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
/**
* 原型模式
* 如果是原型不应该在初始化的时候创建
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
......
}
if (!typeCheckOnly) {
//添加到 alreadyCreated set集合当中,表示他已经创建过一场
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//bd检测, 如果是 abstract, 则抛异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 单例创建
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;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
......
}
else {
......
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
......
}
return (T) bean;
}
复制代码
方法比较长, 我删掉一部分. 不影响观看.
主要看两个方法 :
1.getSingleton(String beanName, ObjectFactory<?> singetonFactory)
2.createBean
getSingleton
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#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 + "'");
}
/**
* 将beanName添加到singletonsCurrentlyInCreation这样一个set集合中
* 表示beanName对应的bean正在创建中
*/
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//这里会调用传入的 lambda 表达式创建的匿名 singletonFactory 对象, 调用他的 getObject() 方法
//其方法内部, 也就是调用 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean 方法
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 的地方.
1. 在创建之前, 通过 beforeSingletonCreation() 方法, 执行了 this.singletonsCurrentlyInCreation.add(beanName) 这句代码,
这里其实是在做一个标志, 表示 这个 beanName 对应的 bean 正在创建当中. 将 singletonsCurrentlyInCreation 翻译过来, 就能看懂.
这里做到了变量名的命名就是最好的注释.
2. 调用 factory.getObject 方法, 进行 bean 的创建, 调用的其实就是 createBean() 方法.
3. 创建完成之后, 通过 afterSingletonCreation() 方法, 将标志位改回去, 其内部执行了 this.singletonsCurrentlyInCreation.remove(beanName) 这句代码.
4. 在最后, 通过 addSingleton() 方法, 将创建的 bean 放到 spring 容器中 : this.singletonObjects.put(beanName, singletonObject)
这里的这个顺序很重要, 尤其是那个 正在创建的标志, 很重要的 : singletonsCurrentlyInCreation
这个正在创建的标志, 在解决 循环依赖的时候, 起了很重要的作用
createBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
复制代码
@Override
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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//Prepare method overrides.
//处理xml中的 lookup-method 和 replace-method 配置,Spring将这两个配置统称为override method
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 在 bean实例化之前 应用后置处理,如果后置处理返回的bean不为空,则直接返回
// 返回的是一个寡妇对象, 属性什么的, spring不会去维护
// spring不推荐开发人员使用这个接口 InstantiationAwareBeanPostProcessor
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 {
// 创建bean
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);
}
}
深圳网站建设www.sz886.com