文章目录
直接打开AbstractBeanFactory的doGetBean方法。
protected T doGetBean(final String name, @Nullable Final Class requiredType,
@Nullable 最终Object[] 参数,布尔值CheckOnly) 抛出BeansException {
//首先,将方法中传入的名称转换为容器的实际beanName。
//BeanName 以前有三种格式
//一个是原来的BeanName,一个是添加的BeanName,一个是别名
最终字符串beanName=transformedBeanName(name);
对象豆。
//经常检查单例缓存中是否有手动注册的单例。
对象共享实例=getSingleton(beanName);
//如果已经创建了单例bean的实例,且调用的getBean方法传递的参数为空,则执行处理逻辑。
//参数必须为空,因为它不能直接返回,因为它需要进一步赋值。
if (sharedInstance !=null args==null) {
如果(logger.isTraceEnabled()) {
//如果bean仍在创建中,则意味着循环引用
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace(“返回一个积极缓存的单例bean 实例\’” + beanName +
\’\’ 尚未完全初始化- 循环引用的结果。 ”);
}
除此之外{
logger.trace(\”返回单例bean 的缓存实例\’\” + beanName + \”\’\”);
}
}
//对于普通bean,直接返回。对于FactoryBeans,它返回getObject。
bean=getObjectForBeanInstance(sharedInstance, 名称, beanName, null);
}
除此之外{
//如果该bean 已经创建,则失败。实例:
//你可能处于循环引用中。
if (isPrototypeCurrentlyInCreation(beanName)) {
抛出一个新的BeanCurrentlyInCreationException(beanName)。
}
//检查该工厂是否存在bean 定义。
BeanFactory 父BeanFactory=getParentBeanFactory();
if (parentBeanFactory !=null !containsBeanDefinition(beanName)) {
//未找到- 检查父级。
String nameToLookup=原始BeanName(name);
if (AbstractBeanFactory 的父BeanFactory 实例) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(
nameToLookup、requiredType、args、typeCheckOnly);
}
否则if (args!=null) {
//使用显式参数委托给父级。
return (T)parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType !=null) {
//无参数- 委托给标准getBean 方法。
returnparentBeanFactory.getBean(nameToLookup, requiredType);
}
除此之外{
return (T)parentBeanFactory.getBean(nameToLookup);
}
}
如果(!typeCheckOnly){
markBeanAsCreated(BeanName);
}
尝试{
最终RootBeanDefinition mbd=getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//确保当前bean 所依赖的bean 的初始化。
String[] dependentOn=mbd.getDependsOn();
if (dependsOn !=null) {
for (String dep : dependentOn) {
if (isDependent(beanName, dep)) {
抛出新的BeanCreationException(mbd.getResourceDescription(), beanName,
\’\’ + beanName + \”\’ 和\’\” + dep + \”\’\” 之间的循环依赖);
}
registerDependentBean(dep, beanName);
尝试{
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
抛出新的BeanCreationException(mbd.getResourceDescription(), beanName,
\”\’\” + beanName + \”\’ 取决于缺少的bean \’\” + dep + \”\’\”。例子);
}
}
}
//创建一个bean 实例。
//如果BeanDefinition 是单例
如果(mbd.isSingleton()) {
//这里我们使用匿名内部类创建一个bean实例对象,并将其注册到依赖对象中。
SharedInstance=getSingleton(beanName, () – {
尝试{
返回createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//显式地从单例中删除实例。 cache: 可能位于那里。
//创建过程急切地完成,以允许解决循环引用。
//还删除接收到临时引用的bean。
destroySingleton(beanName);
原件扔了。
}
});
bean=getObjectForBeanInstance(sharedInstance, 名称, beanName, mbd);
}
否则如果(mbd.isPrototype()) {
//这是一个原型- 创建一个新实例。
对象原型实例=null;
尝试{
beforePrototypeCreation(beanName);
原型实例=createBean(beanName, mbd, args);
}
最后{
afterPrototypeCreation(beanName);
}
bean=getObjectForBeanInstance(prototypeInstance, 名称, beanName, mbd);
}
除此之外{
字符串作用域名称=mbd.getScope();
最终范围scope=this.scopes.get(scopeName);
如果(范围==空){
抛出新的IllegalStateException(\”ScopeName \’\” +scopeName + \”\’\”);
}
尝试{
对象scopedInstance=scope.get(beanName, () – {
beforePrototypeCreation(beanName);
尝试{
返回createBean(beanName, mbd, args);
}
最后{
afterPrototypeCreation(beanName);
}
});
bean=getObjectForBeanInstance(scopedInstance, 名称, beanName, mbd);
}
catch (IllegalStateException ex) {
抛出新的BeanCreationException(beanName,
\’作用域\’\’+作用域名称+\’\’在当前线程中不活动。 \’ 请考虑+。
“如果从单例引用,则为此bean 定义一个作用域代理”,
原来的);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
原件扔了。
}
}
//检查所需的类型是否与实际bean 实例的类型匹配。
if (requiredType!=null !requiredType.isInstance(bean)) {
尝试{
T ConvertedBean=getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean==null) {
抛出新的BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
返回一个ConvertedBean。
}
catch (TypeMismatchException ex) {
如果(logger.isTraceEnabled()) {
logger.trace(\”无法将Bean \’\” + name + \”\’ 转换为所需类型\’\” +
ClassUtils.getQualifiedName(requiredType) + \”\’\”, 示例);
}
抛出新的BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
返回(T)Bean;
}
第一行首先将方法中传递的名称转换为容器的实际beanName。回过头来看,beanName 可以通过三种格式获取。一种是原来的beanName,一种是添加的beanName,一种是别名。
最终字符串beanName=transformedBeanName(name);
对象豆。
输入转换后的BeanName方法
protected StringtransformedBeanName(字符串名称) {
返回canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
公共静态StringtransformedBeanName(字符串名称){
Assert.notNull(name, \”\’name\’ 不能为null\”);
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
返回名称。
}
returntransformedBeanNameCache.computeIfAbsent(name, beanName – {
做{
beanName=beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
返回beanName。
});
}
首先,它检查是否以前缀开头,如果不是,则全部删除。
接下来,输入canonicalName 方法。
公共字符串规范名称(字符串名称){
字符串规范名称=名称;
//处理别名.
字符串解析名称;
做{
//根据别名获取实际的beanName。如果我传递beanName,我什么也得不到。
solvedName=this.aliasMap.get(canonicalName);
if (resolvedName !=null) {
canonicalName=解析名称;
}
}
while (resolvedName!=null);
返回规范名称。
}
如果在地图中找到真实姓名,则证明传入的别名是别名。这时,为了避免成为别名的别名,就递归直到找不到为止。这就是真名。
返回doGetBean,获取BeanName 后,尝试缓存它并获取bean 实例。
对象共享实例=getSingleton(beanName);
请输入方法
公共对象getSingleton(String beanName) {
返回getSingleton(beanName, true)。
}
第二个参数控制是否允许非延迟加载。 true 表示允许立即加载。
protected Object getSingleton(String beanName, boolean allowedEarlyReference) {
//尝试从主缓存中检索完整的bean
对象singletonObject=this.singletonObjects.get(beanName);
//如果尚未创建完整的单例,则正在创建的bean 的名称将保存在singletonsCurrentlyInCreation 中。
//检查是否已经创建
if (singletonObject==null isSingletonCurrentlyInCreation(beanName)) {
//尝试锁定一级缓存对象,因为接下来将操作该缓存对象。
同步(this.singletonObjects){
//尝试从二级缓存中检索EarlySingletonObjects,该对象存储的是尚未添加的bean实例缓存。
singletonObject=this.earlySingletonObjects.get(beanName);
//如果没有检索到并且第二个参数为true,true表示允许对bean的循环引用。
if (singletonObject==nullallowEarlyReference) {
//尝试从三级缓存singletonFactories 中的ObjectFactory 实例的缓存中检索创建此bean 的单例工厂实例。
ObjectFactory?singletonFactory=this.singletonFactories.get(beanName);
//如果获得工厂实例
如果(singletonFactory!=null){
//调用单例工厂的getObject方法返回对象实例
singletonObject=singletonFactory.getObject();
//将实例放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级缓存中删除
this.singletonFactories.remove(beanName);
}
}
}
}
返回一个单例对象。
}
此方法位于DefaultSingletonBeanRegistry 类中,注册由容器创建的单例,并尝试从映射(singletonObjects) 中使用键BeanName 检索单例实例。这里,singletonObjects是一级缓存。
if (singletonObject==null isSingletonCurrentlyInCreation(beanName))
确保相关实例不是从一级缓存中检索的,并且必须是当前正在创建的实例。
公共布尔isSingletonCurrentlyInCreation(String beanName) {
返回this.singletonsCurrentlyInCreation.contains(beanName)。
}
isSingletonCurrentlyInCreation 方法查询该集合以查看BeanName 是否在正在创建的单例bean 列表中。如果bean是单例并且当前正在创建,则会向主缓存添加同步锁。然后对层缓存执行另外两个操作。
为了提高性能,二级缓存earlySingletonObjects和三级缓存singletonFactories都是HashMap。主缓存是安全的,因为它之前已被锁定。
首先,我们从二级缓存中检索一个bean 实例。
singletonObject=this.earlySingletonObjects.get(beanName);
二级缓存存储尚未实例化(填充)的bean。
稍后,我们将尝试从三级缓存singletonFactories 中检索。这里存储的是bean对应的ObjectFactory实例(工厂)。您可以稍后通过getObject() 属性创建该bean 的实例。 bean实例可能还没有被插入,所以先放入二级缓存,然后从三级缓存中清除(为了避免重复创建,三级缓存只有一层)我们要return non-injected beans(以确保bean实例被保存)(以确保bean实例被保存并且单例被销毁)是为了解决循环依赖的问题。
返回到doGetBean。
如果之前创建了单例bean的实例,并且调用的getBean方法传递的参数为空,则执行管理逻辑。它不能直接返回,因为它需要分配。
无论是否存在循环引用,您都必须调用getObjectForBeanInstance 来返回bean 实例。但是,由于您可能获得工厂而不是实例,因此从工厂创建bean 实例可能会多一个步骤。
受保护的对象getObjectForBeanInstance(
对象beanInstance,字符串名称,字符串beanName,@Nullable RootBeanDefinition mbd) {
//如果bean 不是工厂,则不要在调用代码中取消引用工厂。
if (BeanFactoryUtils.isFactoryDereference(名称)) {
if (nullBean beanInstance 实例) {
返回bean实例。
}
//如果名称开头但不是FactoryBean则直接抛出异常
if (!(FactoryBean 的beanInstance 实例)) {
抛出新的BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd !=null) {
mbd.isFactoryBean=true;
}
返回bean实例。
}
//现在我们有一个bean 实例。这可以是常规Bean 或FactoryBean。
//对于FactoryBean,用它来创建bean
instance, unless the
// caller actually wants a reference to the factory.
// 如果是一个普通的Bean,则直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// FactoryBean创建出bean实例返回
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 单例模式下,FactoryBean仅会创建一个Bean实例
// 因此需要优先从缓存获取,这里的缓存不是前面的三级缓存,这个是缓存工厂创建出来的bean的
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// /若缓存没有则尝试创建
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
jvm里面通过Synthetic来标识是由自己的机制生成的类,用在这里标识这是Spring内部生成的Bean实例,不允许第三方改动。
进入到getObjectFromFactoryBean方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 加果需要在工厂模式下维持单例的话
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 又见双重检查锁机制,尝试再从缓存中获取,防止多线程下可能有别的线程已完成该单例Bean的创建
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 调用工厂方法,创建Bean实例
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// 看看此时是否有别的线程先人一步创建好了Bean实例,如果是,则使用最先创建出来的以保证单例
// 之所以这样做是因为factoryBean是用户自定义的,就有可能是异步模式的,即getObject可能是异步的
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 如果是 Synthetic 的就不能使用后置处理器服务了
if (shouldPostProcess) {
// 该Bean实例是否已经有别的线程在尝试创建,但是还没有进行后置处理
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet…
return object;
}
// 后置处理完成前,先加入缓存里锁定起来
beforeSingletonCreation(beanName);
try {
// 触发BeanPostProcessor,第三方框架可以在此用AOP来包装Bean实例
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
“Post-processing of FactoryBean’s singleton object failed”, ex);
}
finally {
// 创建完成后,从缓存锁定的名字里清除
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
// 将其放入缓存,证明单例已经创建完成了
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 如果不是单例,则直接创建并返回
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, “Post-processing of FactoryBean’s object failed”, ex);
}
}
return object;
}
}
先确保factory创建出来的是单例,如果是就先上锁,这里用到了双重锁检查机制,尝试再去factoryBeanObjectCache缓存里获取一遍,防止多线程下可能有别的线程已完成该单例Bean的创建
回到doGetBean,if块里的代码执行完了之后就会跳过else的代码块,然后再经过一系列检查之后就返回bean实例了
最后
小编这些年深知大多数初中级工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Java全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你需要这些资料,⬅专栏获取
else {
// 如果不是单例,则直接创建并返回
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, “Post-processing of FactoryBean’s object failed”, ex);
}
}
return object;
}
}
先确保factory创建出来的是单例,如果是就先上锁,这里用到了双重锁检查机制,尝试再去factoryBeanObjectCache缓存里获取一遍,防止多线程下可能有别的线程已完成该单例Bean的创建
回到doGetBean,if块里的代码执行完了之后就会跳过else的代码块,然后再经过一系列检查之后就返回bean实例了
最后
小编这些年深知大多数初中级工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Java全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-afYjSJZt-1719529033761)]
[外链图片转存中…(img-SMoRBtmP-1719529033762)]
[外链图片转存中…(img-6THZw4k4-1719529033763)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你需要这些资料,⬅专栏获取
#以上关于SpringloC容器的依赖注入源码解析(2)—— doGetBean之从缓存获取Bean的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92672.html