源码分析:
getBean() -> doGetBean()
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 1. 从Spring容器里获取beanObject sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {//打印日志的,不看}// 2. 因为sharedInstance对象可能是普通单实例对象,也可能是FactoryBean对象bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 3. 检查PROTOTYPE原型模式下的循环依赖问题if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 4. 没看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 urn (T) Bean(nameToLookup, args);}else {// No args -> delegate to standard Bean(nameToLookup, requiredType);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}// 5. 合并bd,因为bd支持继承try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);//检查一下当前mbd是不是抽象类型,抽象类型就不能创建checkMergedBeanDefinition(mbd, beanName, args);// 6. deponds-on 依赖检查String[] dependsOn = DependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new ResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new ResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.// 7.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 = Scope();final Scope scope = (scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = (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.if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, Class());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type '" QualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, Class());}}return (T) bean;
}
这里思考了一个问题: 为什么需要三级缓存对象 -》Spring框架里面AOP是需要动态代理对象实现的,三级缓存里存的ObjectFactory对象的getObject()方法会去判断需要返回的是原生对象还是动态代理增强后的对象。
这个方法也可以解决循环依赖问题: setter循环依赖 A->B B->A
获取A,发现没有,就会在三级缓存中生成一个A的ObjectFactory对象包装A,然后去检查依赖信息,调用getBean(B)
获取B,发现没有,就会在三级缓存中生成一个B的ObjectFactory对象包装B,然后去检查依赖信息,调用getBean(A)
这时候,getBean(A)这个方法就会来到getSingleton()这个方法里面,此时就会获取到三级缓存中的A对象,从而跳出了循环依赖
一级缓存:单例对象缓存,当bean已经被初始化,实例化过后,也就是完全创建过后,就会被放入一级缓存里
二级缓存:早期单例对象缓存,当bean已经被初始化,但是还没有被注入属性的早期暴露bean。
三级缓存:单例工厂缓存,存的是bean对象的工厂,当一级二级缓存中没有的对象的话,就会来到三级缓存中,如果三级缓存中存在单例工厂缓存,就会涉及到缓存升级 -> 从工厂里面的getObject方法获得保存的早期单例对象,并放入二级缓存中,再把工厂从三级缓存中删除
protected Object getSingleton(String beanName, boolean allowEarlyReference) {//从一级缓存里面拿bd对象Object singletonObject = (beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//若一级缓存没有,则从二级缓存里面拿synchronized (this.singletonObjects) {singletonObject = (beanName);if (singletonObject == null && allowEarlyReference) {//如果二级缓存没有,则从三级缓存里面拿ObjectFactory<?> singletonFactory = (beanName);if (singletonFactory != null) {//对象缓存升级,三级升级为二级。singletonObject = Object();this.earlySingletonObjects.put(beanName, singletonObject);ve(beanName);}}}}return singletonObject;
}
为什么拿到了bean还要再次处理bean呢?
因为bean分为三种情况的bean
1.普通单实例bean
2.FactoryBean,名字以&开头
3.FactoryBean,但是名字不以&开头,是FactoryBean里面的getObject里面所管理的bean。
当然不可能每一次获取这种bean都要调用一次getObject,所有spring会有一个叫factoryBeanObjectCache的缓存来存这种bean
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// 说明当前对象是FactoryBean对象if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}if (!(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), Class());}}//当前bean是单实例对象if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}//当前bean是Factory对象,但是是FactoryBean对象内部管理的实例对象Object object = null;if (mbd == null) {//从缓存拿,拿不到则去注册中心拿 ->object = getCachedObjectForFactoryBean(beanName);}if (object == null) {FactoryBean<?> factory = (FactoryBean<?>) beanInstance;if (mbd == null && containsBeanDefinition(beanName)) {// ->这里就是去注册中心拿mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;
}
怎么检查的呢?
假如有一个PrototypeA 和 一个B
1.先往集合里面加入A的beanName
2.创建一个早期对象A
3.发现依赖,去创建B
4.创建出了早期对象B
5.发现依赖,又去创建A
6.由于A是一个Prototype类型,所有会在集合里面找到它的beanName
7.isPrototypeCurrentlyInCreation返回true,结束循环依赖注入
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {//记录当前线程相关的正在创建的原型对象beanNamebeforePrototypeCreation(beanName);//创建对象prototypeInstance = createBean(beanName, mbd, args);}finally {//从正在创建中的集合中 移除。afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//逻辑就是:检查有没有threadLocal里面有没有beanName,没有就创建一个String类型的
//如果有就升级为set集合,再往set集合里面加入beanName
//或者已经有set集合了,也是继续往set集合里加入beanName//这个方法是用来记录在原型模式下正在创建的bean对象
protected void beforePrototypeCreation(String beanName) {Object curVal = ();if (curVal == null) {this.prototypesCurrentlyInCreation.set(beanName);}else if (curVal instanceof String) {Set<String> beanNameSet = new HashSet<>(2);beanNameSet.add((String) curVal);beanNameSet.add(beanName);this.prototypesCurrentlyInCreation.set(beanNameSet);}else {Set<String> beanNameSet = (Set<String>) curVal;beanNameSet.add(beanName);}
}
//如果bean对象创建完了,就移除掉
//逻辑和上面一样
protected void afterPrototypeCreation(String beanName) {Object curVal = ();if (curVal instanceof String) {ve();}else if (curVal instanceof Set) {Set<String> beanNameSet = (Set<String>) ve(beanName);if (beanNameSet.isEmpty()) {ve();}}
}
其中prototypesCurrentlyInCreation是一个threadlocal集合
private final ThreadLocal<Object> prototypesCurrentlyInCreation =new NamedThreadLocal<>("Prototype beans currently in creation");
逻辑:1.如果bd没有使用继承,就把当前bd创建为RootBeanDefinition类型,并设置当前bd为mbd返回
2.如果bd使用了继承,先处理一下父bd的名字,然后递归一下看看有没有爷爷bd,递归完就创建根据父bd信息创建mbd
然后以子bd信息为主,覆盖父bd,缓存mbd,最后返回mbd
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (dBeanDefinitions) {//表示合并后的bd信息RootBeanDefinition mbd = null;//表示当前beanName对应的过期mbd信息RootBeanDefinition previous = null;// Check with full lock now in order to enforce the same merged instance.if (containingBd == null) {mbd = (beanName);}//条件成立:说明mbd是null 或者 过期..if (mbd == null || mbd.stale) {//表示当前beanName对应的过期mbd信息previous = mbd;//CASE-未使用继承://条件成立:说明当前beanName对应BD没有使用继承,就不用处理继承了..if (bd.getParentName() == null) {// Use copy of given root bean definition.if (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {mbd = new RootBeanDefinition(bd);}}//CASE-使用继承:else {// Child bean definition: needs to be merged with parent.//表示 BD的父信息BeanDefinition pbd;try {//拿到处理了别名和“&”的真实父bd beanName名称。String parentBeanName = ParentName());//条件成立:子bd和父bd名称不一样,就是普通情况。if (!beanName.equals(parentBeanName)) {//这里是一个递归调用,最终返回父BD信息pbd = getMergedBeanDefinition(parentBeanName);}//条件成立:子bd和父bd名称一样,不是一般情况..else {BeanFactory parent = getParentBeanFactory();if (parent instanceof ConfigurableBeanFactory) {pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new ResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.//按照父BD信息创建 mbd对象。mbd = new RootBeanDefinition(pbd);//子bd覆盖mbd信息,以子bd为基准,pbd为辅mbd.overrideFrom(bd);}// Set default singleton scope, if not configured before.if (!StringUtils.Scope())) {mbd.setScope(SCOPE_SINGLETON);}// A bean contained in a non-singleton bean cannot be a singleton itself.// Let's correct this on the fly here, since this might be the result of// parent-child merging for the outer bean, in which case the original inner bean// definition will not have inherited the merged outer bean's singleton status.if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {mbd.Scope());}// Cache the merged bean definition for the time being// (it might still get re-merged later on in order to pick up metadata changes)if (containingBd == null && isCacheBeanMetadata()) {//缓存合并后的mbd信息dBeanDefinitions.put(beanName, mbd);}}if (previous != null) {copyRelevantMergedBeanDefinitionCaches(previous, mbd);}return mbd;}
}
在registerDependentBean里面存在两个map集合,dependentBeanMap(依赖当前bean的集合) 和 dependentForMap(当前bean依赖的集合)
public void registerDependentBean(String beanName, String dependentBeanName) {String canonicalName = canonicalName(beanName);synchronized (this.dependentBeanMap) {Set<String> dependentBeans =this.dependentBeanMapputeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));if (!dependentBeans.add(dependentBeanName)) {return;}}synchronized (this.dependenciesForBeanMap) {Set<String> dependenciesForBean =this.dependenciesForBeanMapputeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));dependenciesForBean.add(canonicalName);}
}
在isDependent()方法里面判断是否发生了循环依赖
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {if (alreadySeen != null && ains(beanName)) {return false;}String canonicalName = canonicalName(beanName);Set<String> dependentBeans = (canonicalName);if (dependentBeans == null) {return false;}if (ains(dependentBeanName)) {return true;}//判断环形循环依赖//A depends-on B//B depends-on C//C depends-on A//-> dependentMap{B:{A},C:{B},A:{C}} dependentForMap{A:{B},B:{C},C:{A}}for (String transitiveDependency : dependentBeans) {if (alreadySeen == null) {alreadySeen = new HashSet<>();}alreadySeen.add(beanName);if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {return true;}}return false;
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Null(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {Object singletonObject = (beanName);if (singletonObject == null) {//容器销毁时,会设置这个属性为true,这个时候就不能再创建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 + "'");}//将当前beanName放入到“正在创建中单实例集合”,放入成功,说明没有产生循环依赖,失败,则产生循环依赖,里面会抛异常。//举个例子:构造方法参数依赖//A->B B->A//1.加载A,根据A的构造方法,想要去实例化A对象,但是发现A的构造方法有一个参数是B(在这之前,已经向这个集合中添加了 {A})//2.因为A的构造方法依赖B,所以触发了加载B的逻辑..//3.加载B,根据B的构造方法,想要去实例化B对象,但是发现B的构造方法有一个参数是A(在这之前,已经向这个集合中添加了 {A,B})//4.因为B的构造方法依赖A,所以再次触发了加载A的逻辑..//5.再次来到这个getSingleton方法里,调用beforeSingletonCreation(A),因为创建中集合 已经有A了,所以添加失败,抛出异常beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {singletonObject = Object();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 = (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;}
}
本文发布于:2024-02-01 23:46:52,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170680739139951.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |