spring学习(四)——Bean的加载(不从缓存中获取bean)
参考文章:
假如spring未从缓存中获得bean的话,执行的业务逻辑
//缓存中不存在
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//因为 Spring 只解决单例模式下得循环依赖,在原型模式下如果存在循环依赖则会抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//如果容器中没有找到,则从父类容器中加载
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
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.
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);
}
try {
//从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查并且合并bean
checkMergedBeanDefinition(mbd, beanName, args);
//处理所依赖的 bean
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 若给定的依赖 bean 已经注册为依赖给定的 bean
// 循环依赖的情况
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);
}
}
}
// bean 实例化
// 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.
// 显式从单例缓存中删除 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);
}
// 从指定的 scope 下创建 bean
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;
}
}
内容非常长,大概的逻辑为
可以看到里面主要的方法为:
-
#isPrototypeCurrentlyInCreation(String beanName)
方法,判断当前 Bean 是否正在创建 -
#containsBeanDefinition(String beanName)
方法中不存在beanName
相对应的 BeanDefinition 对象时 -
#doGet
使用父类的方法来获得bean -
#getMergedLocalBeanDefinition(String beanName)
方法,获取相对应的 BeanDefinition 对象 -
#checkMergedBeanDefinition()
方法,检查给定的合并的 BeanDefinition 对象 -
#处理依赖
方法,实例化依赖的 Bean 对象 -
#isDependent(String beanName, String dependentBeanName)
方法,是校验该依赖是否已经注册给当前 Bean -
#registerDependentBean(String beanName, String dependentBeanName)
方法,将该依赖进行注册,便于在销毁 Bean 之前对其进行销毁 -
#getBean(String beanName)
方法,实例化依赖 Bean 对象
下面开始看这些方法内容
isPrototypeCurrentlyInCreation
判断当前 Bean 是否正在创建
/**
* Return whether the specified prototype bean is currently in creation
* (within the current thread).
* 首先检查该 beanName 是否处于原型模式下且正在创建中
* @param beanName the name of the bean
*/
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
//其实检测逻辑和单例模式一样,一个“集合”存放着正在创建的 Bean ,
//从该集合中进行判断即可,只不过单例模式的“集合”为 Set ,而原型模式的则是 ThreadLocal
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
#containsBeanDefinition(String beanName)
方法中不存在
beanName
相对应的 BeanDefinition 对象时
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
#doGet
/doGetBean方法
使用父类方法获得bean
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.
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);
}
}
#getMergedLocalBeanDefinition(String beanName)
方法
获取相对应的 BeanDefinition 对象
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 快速从缓存中获取,如果不为空,则直接返回
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// 获取 RootBeanDefinition,
// 如果返回的 BeanDefinition 是子类 bean 的话,则合并父类相关属性
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
#checkMergedBeanDefinition()
方法
检查给定的合并的 BeanDefinition 对象‘
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
//
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
}
处理依赖
方法
实例化依赖的 Bean 对象
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 若给定的依赖 bean 已经注册为依赖给定的 bean
// 循环依赖的情况
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);
}
}
}
#isDependent(String beanName, String dependentBeanName)
方法
是校验该依赖是否已经注册给当前 Bean
protected boolean isDependent(String beanName, String dependentBeanName) {
synchronized (this.dependentBeanMap) {
return isDependent(beanName, dependentBeanName, null);
}
}
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
// alreadySeen 已经检测的依赖 bean
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 获取原始 beanName
String canonicalName = canonicalName(beanName);
// 获取当前 beanName 的依赖集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
// 存在,则证明存在已经注册的依赖
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
// 递归检测依赖
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
// 添加alreadySeen中
alreadySeen.add(beanName);
// 递归
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
//对象保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
#registerDependentBean(String beanName, String dependentBeanName)
方法
将该依赖进行注册,便于在销毁 Bean 之前对其进行销毁
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
// 添加 <canonicalName, <dependentBeanName>> 到 dependentBeanMap 中
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
// 添加 <dependentBeanName, <canonicalName>> 到 dependenciesForBeanMap 中
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
/** Map between dependent bean names: bean name to Set of dependent bean names. */
/**
* 保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
/**
* 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
#getBean(String beanName)
方法
实例化依赖 Bean 对象
然后使用getBean获得类
public Object getBean(String name) throws BeansException {
return doGetBean(name, //要获取 Bean 的名字
null, //要获取 bean 的类型
null, //创建 Bean 时传递的参数。这个参数仅限于创建 Bean 时使用
false);//是否为类型检查
}