当前位置:网站首页>Tencent two sides: @bean and @component are used in the same class, what will happen?
Tencent two sides: @bean and @component are used in the same class, what will happen?
2022-07-27 14:47:00 【Ah size】
Doubt description

lately , In the process of development , Found a way to write before , It's like this
In my understanding ,@Configuration Add @Bean Will create a userName Not for null Of UserManager object , and @Component It will also create a userName by null Of UserManager object
So we inject... Into other objects UserManager Object time , Which object is injected ?
Because the project has been online for a long time , Therefore, this writing method does not compile and report errors , There was no problem with the operation
I'll find my colleagues later to find out , Actually, I want

take effect , In fact, it did take effect
So here comes the question :Spring How many... Are there in the container UserManager Object of type ?
Spring Boot edition
Used in the project Spring Boot The version is :2.0.3.RELEASE
Object's scope Is the default value , That is to say singleton
The results verify that
There are many ways to verify , Sure debug Follow the source code , have a look Spring How many... Are there in the container UserManager object , You can also go straight from UserManager Construction method , See which constructor methods are called , wait
Let's start with the construction method , have a look UserManager How many instances did you instantiate

Only parameterized constructors are called , The nonparametric construction method remains intact ( Not called at all )
since UserManager The constructor is called only once , So the previous question : Which object is injected
The answer is clear , There's no choice , Can only be @Configuration Add @Bean Created userName Not for null Of UserManager object
Here comes the question : Why not @Component Created userName by null Of UserManager object ?
The source code parsing
@Configuration And @Component It's very close

therefore @Configuration It can be component scan
among ConfigurationClassPostProcessor And @Configuration Is closely linked , The class inheritance structure is as follows :

It has achieved BeanFactoryPostProcessor Interface and PriorityOrdered Interface , About BeanFactoryPostProcessor,
So we're from AbstractApplicationContext Of refresh Method called invokeBeanFactoryPostProcessors(beanFactory) Start , Follow the source code

Now it's done com.lee.qsl Under bag component scan , com.lee.qsl Package and sub package UserConfig 、 UserController and UserManager All scanned
Be careful , At the moment @Bean The processing of has not yet started , UserManager It's through @Component And the scanned ; here Spring In the container beanDefinitionMap Medium UserManager That's true

The next step is important , It is closely related to the answer we want


Loop recursive processing UserConfig 、 UserController and UserManager , Package them all into ConfigurationClass , Recursive scanning BeanDefinition
After the cycle , Let's see configClasses

UserConfig bean In definition information beanMethods There's an element in [BeanMethod:name=userManager,declaringClass=com.lee.qsl.config.UserConfig]
Then we went down , Let's take a closer look at the link where the answer appears

Did you find anything ?@Component Embellished UserManager The definition is directly overridden as @Configuration + @Bean Embellished UserManager Definition
Bean The type is also defined by ScannedGenericBeanDefinition replaced ConfigurationClassBeanDefinition
Subsequently passed BeanDefinition When creating an instance , The nature created is @Configuration + @Bean Embellished UserManager , That is, it will reflect the call UserManager The parametric construction method of
Since then , The answer is clear
Spring In fact, it gives a hint
2021-10-03 20:37:33.697 INFO 13600 --- [main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'userManager' with a different definition: replacing [Generic bean: class [com.lee.qsl.manager.UserManager]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\qsl-project\spring-boot-bean-component\target\classes\com\lee\qsl\manager\UserManager.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=userConfig; factoryMethodName=userManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource[com/lee/qsl/config/UserConfig.class]]
Only the log level is info , It's too inconspicuous
Spring Upgrade optimization
Probably Spring The team realized info The level is too inconspicuous , Or realize that the direct coverage is not reasonable
So in Spring 5.1.2.RELEASE (Spring Boot It is 2.1.0.RELEASE ) Optimization is made
Let's see in detail

Start direct error reporting ,Spring Tips are also given
The bean 'userManager', defined in class path resource [com/lee/qsl/config/UserConfig.class], could not be registered. A bean with that name has already been defined in file [D:qsl-projectspring-boot-bean-componenttargetclassescomleeqslmanagerUserManager.class] and overriding is disabled.
Let's follow the source code , Mainly look at and Spring 5.0.7.RELEASE The difference between

New configuration item allowBeanDefinitionOverriding To control whether BeanDefinition Cover , Not allowed by default
We can configure... In the configuration file :spring.main.allow-bean-definition-overriding=true , allow BeanDefinition Cover
This treatment is better , Leave the choice to the developer , Instead of dealing with it secretly , It has achieved the effect that developers want
summary
Spring 5.0.7.RELEASE ( Spring Boot 2.0.3.RELEASE ) Support @Configuration + @Bean And @Component Act on the same class at the same time
When starting, it will give info Level log prompt , At the same time @Configuration + @Bean Embellished BeanDefinition overwrite @Component Embellished BeanDefinition
Maybe Spring The team realized that the above treatment was not appropriate , So in Spring 5.1.2.RELEASE Optimization is made
Added configuration item :allowBeanDefinitionOverriding , Give the initiative to the developer , It's up to the developer to decide whether to allow coverage
Add
About allowBeanDefinitionOverriding , What I said earlier is wrong , Later, I went to look through the source code , Supplemented as follows
Spring 1.2 introduction DefaultListableBeanFactory When it's time private boolean allowBeanDefinitionOverriding = true;, The default is to allow BeanDefinition Cover

Spring 4.1.2 The introduction of isAllowBeanDefinitionOverriding() Method

Spring From beginning to end, the default is to allow BeanDefinition Covered , The change is Spring Boot , Spring Boot 2.1.0 Not covered before Spring Of allowBeanDefinitionOverriding The default value is , Still allowed BeanDefinition Covered
Spring Boot 2.1.0 in SpringApplication Defines private properties :allowBeanDefinitionOverriding

The specified value is not displayed , So the default is false , After the Spring Boot During startup , Will overwrite with this value Spring Medium allowBeanDefinitionOverriding The default value of

About allowBeanDefinitionOverriding , I think you should have made it clear .
边栏推荐
- Interprocess communication
- STM32 - capacitive touch button experiment
- Chinese character style transfer --- antagonistic discriminative domain adaptation (L1)
- 进程间通信
- MySQL advanced II. Logical architecture analysis
- Is the security of online brokerage app account opening guaranteed?
- 2022牛客多校二_ E I
- Redis
- 一篇文章看懂JS执行上下文
- What if win11 wallpaper turns black? The solution of win11 wallpaper blackening
猜你喜欢

SLAM综述阅读笔记四:A Survey on Deep Learning for Localization and Mapping: Towards the Age of Spatial 2020

架构——MVC的升华

终于有人把面试必考的动态规划、链表、二叉树、字符串全部撸完了

Ten thousand words detailed Google play online application standard package format AAB

Redis

如何做好企业系统漏洞评估

大家最想要的,最全的C语言知识点总结,还不赶紧学习

这年头谁还不会抓包,WireShark 抓包及常用协议分析送给你!

JS 疫情宅在家,学习不能停,七千字长文助你彻底弄懂原型与原型链

Stock trading 4
随机推荐
MySQL save data prompt: out of range value for column error
Annual comprehensive analysis of China's online video market in 2022
@What happens when bean and @component are used on the same class?
如果我们是那晚负责修复 B 站崩了的开发人员
Slam overview Reading Note 6: slam research based on image semantics: application-oriented solutions for autonomous navigation of mobile robots 2020
FPGA timing constraint sharing 04_ Output delay constraint
Who can't capture packets these days? Wireshark packet capture and common protocol analysis are for you!
Simple encapsulation steps of request data request of uniapp
JS什么是声明提前?函数与变量声明提前的先后顺序(执行上下文铺垫篇)
Spark job uses log4j appender to append logs to local files or mysql
"Game engine light in light out" 4.1 unity shader and OpenGL shader
STM32 - capacitive touch button experiment
HDU4496 D-City【并查集】
如何做好企业系统漏洞评估
次小生成树【模板】
mysql保存数据提示:Out of range value for column错误
架构——MVC的升华
力扣SQL语句习题,错题记录
telnet远程登录aaa模式详解【华为eNSP】
【医疗行业】DICOM converter Tools