getBean简单介绍
- 本文源码基于spring-framework-5.3.10。
- spring启动的时候会创建非懒加载的单例Bean。
- 通过BeanFactory或者实现BeanFactory的子类(ApplicationContext)进行调用。
@DependsOn注解介绍
- 通知spring在创建当前Bean的时候,先去创建@DependsOn注解中配置的Bean。
源码流程
- 调用doGetBean方法
- 获取BeanName(transformedBeanName方法):获取FactoryBean的getObject方法中的值,name传值的前面需要加一个&符号。一个Bean有多个名字(别名),要获取到这个别名对应主要的BeanName。
- FactoryBean直接走getObject的逻辑,普通Bean开始创建获取。
- 普通Bean有父BeanFactory,直接调用父BeanFactory的getBean
- 普通Bean检查是不是抽象bean,抽象Bean抛异常。
- 普通Bean去创建@DependsOn注解中配置的Bean。
- 根据不同的Scope去获取Bean。
- 校验类型是否匹配。
源码重点关注内容
- FactoryBean和普通Bean的区别
- @DependsOn优先加载Bean的逻辑
- 不同Scope加载Bean的逻辑:进阶可以理解mvc中request作用域与session作用域的实现方式。
getBean方法源码分析
// 4个方法全部调用doGetBean方法
/**
* 参数是Bean的名字
*/
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
/**
* 参数是Bean的名字和Bean的类型
*/
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
/**
* 参数是Bean的名字和Bean构造方法的参数
*/
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
/**
* 参数是Bean的名字和Bean的类型和Bean构造方法的参数
*/
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}
getBean的核心:doGetBean源码分析
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// FactoryBean的逻辑:name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
// 别名逻辑:name有可能传入进来的是别名,那么beanName就是id
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
// 直接从单例池去获取Bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 拿到单例Bean,并且是无参的时候,执行下面的逻辑
// 这里就是打印日志
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 + "'");
}
}
// 如果是FactoryBean,那么就调用getObject()返回对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 循环依赖的时候使用:记录当前的Bean正在创建
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 获取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
// 存在父BeanFactory,并且当前beanDefinitionMap中没有这个Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 名字的转换:&&&&xxx---->&xxx
String nameToLookup = originalBeanName(name);
// 使用不同的参数去调用父BeanFactory的方法
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 循环依赖的时候使用:把Bean标记为已创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
// JFR时间记录开始位置
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
// JFR的标签
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 拿到合并之后的BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查BeanDefinition是不是Abstract的,抽象的会抛异常!
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 得到@DependsOn注解中配置的值:加载当前Bean需要的前置Bean
String[] dependsOn = mbd.getDependsOn();
// 这个判断说明配置类@DependsOn注解
if (dependsOn != null) {
// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
for (String dep : dependsOn) {
// beanName是不是被dep依赖了,如果是则出现了循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value。方便其他Bean进行上门的判断
registerDependentBean(dep, beanName);
// 创建所依赖的bean
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 单例Bean的创建逻辑
if (mbd.isSingleton()) {
// 创建单例Bean,并添加到单例池
sharedInstance = getSingleton(beanName, () -> {
try {
// 真正的创建一个Bean
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.
// 有问题销毁当前的单例Bean
destroySingleton(beanName);
throw ex;
}
});
// 如果是FactoryBean,那么就调用getObject()返回对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型Bean的创建逻辑
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 创建Bean的前置逻辑:标记Bean正在创建
beforePrototypeCreation(beanName);
// 真正的创建一个Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建Bean的后置逻辑:标记Bean完成创建
afterPrototypeCreation(beanName);
}
// 如果是FactoryBean,那么就调用getObject()返回对象
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 这里是其他的作用域:比如说mvc里面的request,session作用域
// 得到当前BeanDefinition的scope属性
String scopeName = mbd.getScope();
// 没有值,抛异常
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 得到当前名字对应的具体Scope
Scope scope = this.scopes.get(scopeName);
// Scope不存在的时候抛异常
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 类似单例,放到他自己的作用域:单例放在单例池。request需要保证这个对象中获取的是同一个Bean。缓存到一个变量。
// session.getAttriute(beaName):缓存在session的一个变量中
// request.getAttriute(beaName):缓存在request的一个变量中
Object scopedInstance = scope.get(beanName, () -> {
// 创建Bean的前置逻辑:标记Bean正在创建
beforePrototypeCreation(beanName);
try {
// 真正的创建一个Bean
return createBean(beanName, mbd, args);
}
finally {
// 创建Bean的后置逻辑:标记Bean完成创建
afterPrototypeCreation(beanName);
}
});
// 如果是FactoryBean,那么就调用getObject()返回对象
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
// 当前的Bean从alreadyCreated删除调用
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
// JFR时间记录开始位置
beanCreation.end();
}
}
// 传入的类型判断:检查通过name所获得到的beanInstance的类型是否是requiredType
return adaptBeanInstance(name, beanInstance, requiredType);
}
转化为主要的BeanName的方法:transformedBeanName源码分析
/**
* 转化BeanName
*/
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
/**
* FactoryBean的逻辑:name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
*/
public static String transformedBeanName(String name) {
// BeanName为空抛异常
Assert.notNull(name, "'name' must not be null");
// 不是&开头,直接返回名字
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 以&开头,FactoryBean:获取去掉&的名字
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
// 这是是个循环,一直到开头不是&。所以说写一个&和多个&&&&&是没有区别的,都会干掉
do {
// 去掉&符号
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
// 返回去掉&符号的名称
return beanName;
});
}
/**
* 别名逻辑:name有可能传入进来的是别名,那么beanName就是id
*/
public String canonicalName(String name) {
// 赋值当前Name
String canonicalName = name;
// Handle aliasing...
// 处理别名
String resolvedName;
// aliasMap的结构是{别名:真实名字,别名:真实名字},一直找到这个Map中没有
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
// 返回真实的BeanName
return canonicalName;
}
判断类型匹配的逻辑
<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
// Check if required type matches the type of the actual bean instance.
// 类型不满足的时候,进行下面的逻辑
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 类型转化成功的时候,才会返回Bean,否则抛异常
Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return (T) 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());
}
}
// 类型满足,直接返回Bean
return (T) bean;
}
获取单例Bean的方法getSingleton源码分析
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// beanName为空,抛异常
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从单例池获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 没有获取到的逻辑
// Bean被销毁,抛异常
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);
// 新的单例的标志为False
boolean newSingleton = false;
// 获取排除标志
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
// 排除标志为null的时候,设置这个标志不为null:标明执行开始了
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 调用上面的lambda去真正的创建Bean
singletonObject = singletonFactory.getObject();
// 创建Bean成功
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 {
// 将排除的标志变为null:标明执行完成了
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 循环依赖一级缓存中放入
afterSingletonCreation(beanName);
}
// 添加到单例池
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
// 返回得到的单例Bean
return singletonObject;
}
}
结束语
- 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
- 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
- 关注公众号,后续持续高效的学习JVM!
- 这个公众号,无广告!!!每日更新!!!