Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AbstractAutowireCapableBeanFactory#doCreateBean 调用 getSingleton不理解 #59

Open
jaxlove opened this issue Jun 6, 2023 · 4 comments

Comments

@jaxlove
Copy link

jaxlove commented Jun 6, 2023

原代码是
if (beanDefinition.isSingleton()) { //如果有代理对象,此处获取代理对象 exposedObject = getSingleton(beanName); addSingleton(beanName, exposedObject); }
spring已经在 initializeBean后 bean 不是已经被替换为 代理对象了吗,如果这里再调用getSingleton 方法,就会再生成一个新的代理对象。这段逻辑不理解

@Linweixinyo
Copy link

@jaxlove 我不知道我理解的对不对,我认为你应该是在困惑(在初始化完成之后执行postProcessAfterInitialization可能会对原有的Bean进行代理,但是在mini-spring中初始化完成之后调用了getSingleton(beanname)导致触发三级缓存中创建代理的流程,导致原有的代理被覆盖)。其实在spring源码中getSingleton方法还有一个boolean类型的变量boolean allowEarlyReference来控制最多查询到二级缓存,这样就可以避免触发三级缓存中的提前创建代理。以上是我的看法,希望能够对你有所帮助,可以等待原作者的回答

@niuxvdong
Copy link

@jaxlove 可以看到作者在 DefaultAdvisorAutoProxyCreator 中增加了一个 earlyProxyReferences 标记,用来判断这个代理对象问题。创建过则不会再次创建。可以看我写的说明,希望对你有帮助:https://github.com/niuxvdong/small-spring/blob/master/small-spring-16/README.md#6%E5%A2%9E%E5%8A%A0-getearlybeanreference-%E5%AE%9E%E7%8E%B0
其实可以通过 debug 来查看一下整个执行流程来帮助理解。

@DerekYRC
Copy link
Owner

@jaxlove @Linweixinyo 如下图,AbstractAutowireCapableBeanFactory#doCreateBean方法中创建bean后,如果存在代理,则将代理bean放进三级缓存,否则将原始bean放进三级缓存。initializeBean方法入参的bean是原始bean,注意不是代理bean。最后从三级缓存中获取bean,由于是查询缓存,所以不会创建一个新的bean。
image

@DerekYRC
Copy link
Owner

@jaxlove 建议debug对应单测加深理解

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants