AbstractBeanFactory.getBean的流程,有点像老外点餐,不信我们往下看。。spring
AbstractBeanFactory中有getBean的通用逻辑缓存
//AbstractBeanFactory 中getBean方法第源码
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
复制代码
核心逻辑在:doGetBean中。bash
玩笑事后让咱们看点实在的。app
/**
* Return an instance, which may be shared or independent, of
the specified bean.
* 得到一个实例,能够是共享(原型的),独立(单例的),指定的
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance
* using explicit arguments
* (only applied when creating a new instance as opposed to
retrieving an existing one)
* (仅在建立一个新实例时使用,而不是获取一个已经存在的bean)
* @param typeCheckOnly whether the instance is obtained
for a type check,not for actual use
* 是否仅仅是类型检查
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly)
throws BeansException {
//1.获取对应的beanName ,BeanFactory去掉&,别名找到对应的BeanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//2. 尝试从缓存中获取单例 Spring会,在Bean未建立完成的状况下,建立Bean的ObjectFactory对象,提前曝光,以方便解决循环依赖。
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 + "'");
}
}
//根据bean实例获取对象,若是是FactoryBean 获取它建立的对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance: // We're assumably within a circular reference.
//3.原型依赖的检查,若是是原型,假设存在循环引用,抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 4.检查bean,是否认义在了BeanFactory中,
BeanFactory parentBeanFactory = getParentBeanFactory();
// 若是父BeanFactory不为空&&当前并无beanDefinitionMap不包含,
// 委托给父BeanFactory
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
//委托给,须要参数的 getBean方法
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 委托给标准的getBean方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
//不只是,类型检查,标记bean为建立
// 容许bean能够从新合并
markBeanAsCreated(beanName);
}
try {
//5.将GernericBeanDefinition转换为RootBeanDefinition,
//若是Bean有父Bean,时会合并父类的相关属性。
final RootBeanDefinition mbd =
getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that
// the current bean depends on.
// 6.保证bean的依赖先初始化了
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 对应@DependsOn 注解,
/**
* 检测是否存在 depends-on 循环依赖,若存在则抛异常。
* 好比 A 依赖 B,
* B 又依赖 A,他们的配置以下:
@Bean(name="a")
@DependsOn("b")public A a () {
return new A();}
@Bean(name = "b")
@DependsOn("a")
public B b () {
return new B();
}
* a 要求 b 在其以前被建立,但 b 又要求 a 先于它
* 建立。这个时候造成了循环,对于 depends-on 循环,Spring 会直接
* 抛出异常
*
*@see org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
*/
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册,Dependent和Bean的关系
registerDependentBean(dep, beanName);
try {
//先建立Dependent
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//7.建立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;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. // 8.进行类型转换 // requiredType.isInstance(bean) 相似 bean instanceof requiredType // 为true表示能够直接返回,或强转 //clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj) //仅当obj not null if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } 复制代码
当看完主流程时,我有以下疑问:ide
getObjectForBeanInstance和createBean的逻辑下一篇再聊,预计20190921前上传。 这里先说下2,4。ui
简单说,就是清除原有的RootBeanDefinition,再经过当前的多个GenericBeanDefinition合并成新的RootBeanDefinition,供BeanFactory使用。this
若是有兴趣能够搜索url
org.springframework.beans.factory.config.BeanDefinition org.springframework.beans.factory.support.GenericBeanDefinition org.springframework.beans.factory.support.RootBeanDefinitionspa
我最开始觉得是bean须要依赖,处理Autowired注解,然而不是。 利用IDEA查找了调用BeanDefinition的setDependsOn的地方, .net
发现了AnnotationConfigUtils.processCommonDefinitionAnnotations方法中如以下代码:
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
复制代码
也就是说doGetBean中的
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
.....
}
复制代码
是对@DependOn注解的支持,我孤陋寡闻,工做中重来没有使用过@DependOn注解。从网上查阅了资料。
当时我查下的资料的url:blog.csdn.net/qq_30257149…
@DependOn注解用来表示一个bean A的实例化依赖另外一个bean B的实例化, 可是A并不须要持有一个B的对象
读源码不容易,最开始我老是揪住一个方法不放,个把小时下来,已经不知道本身读到哪里了,后来老是浑沦吞枣,一味求快,好像看了不少,实际上什么也不知道。今年9月初,不知道是北京的天气变凉快了,仍是什么别的缘由,我本身也不清楚,居然能静下心来,不求快,一层一层读,一点一点翻译,天天仅读40分钟,总算感受是明白了点,不由感慨以下:
只抓细节太糊涂
浑沦吞枣净瞎看
静心慢读未必快
反正我是入门了