当前位置:网站首页>Tencent two sides: @bean and @component are used on the same class. What happens?
Tencent two sides: @bean and @component are used on the same class. What happens?
2022-06-30 12:29:00 【Java technology stack】
source :cnblogs.com/youzhibing/p/15354706.html
Doubt background
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.
Spring Boot I won't introduce the foundation , Recommend this practical tutorial :
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 ). If you want to know more , You can read :Spring The cycle of dependence , Detailed analysis of source code → Do you really need level 3 cache ?
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, You can see :
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 the definition 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 [email protected] Embellished UserManager Definition .Bean The type is also defined by ScannedGenericBeanDefinition replaced ConfigurationClassBeanDefinition.
Subsequently passed BeanDefinition When creating an instance , The nature created is @[email protected] 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 .
Recommend a Spring Boot Basic tutorials and practical examples :
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-project\spring-boot-bean-component\target\classes\com\lee\qsl\manager\UserManager.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 .
total junction
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 @[email protected] 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, Wrong front , I went to 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 .

Spring4.1.2 introduction 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 .
Recent hot article recommends :
1.1,000+ Avenue Java Arrangement of interview questions and answers (2022 The latest version )
2. Explode !Java Xie Cheng is coming ...
3.Spring Boot 2.x course , It's too complete !
4. Don't write about the explosion on the screen , Try decorator mode , This is the elegant way !!
5.《Java Development Manual ( Song Mountain version )》 The latest release , Download it quickly !
I think it's good , Don't forget to like it + Forward !
边栏推荐
- Redis installation on Linux system
- grep匹配查找
- 3D视觉检测在生产流水的应用有哪些
- 光谱共焦位移传感器的原理是什么?能应用那些领域?
- Flutter 从零开始 006 单选开关和复选框
- Layout of pyqt5 interface and loading of resource files
- Pinda general permission system (day 7~day 8)
- The format of RTSP address of each manufacturer is as follows:
- Flutter 从零开始 005 图片及Icon
- HMS core audio editing service 3D audio technology helps create an immersive auditory feast
猜你喜欢
随机推荐
各厂家rtsp地址格式如下:
Redis installation on Linux system
Hannaiping of Qilin software: the construction of Digital China needs its own open source root community
How do different types of variables compare with zero
Embedded SIG | 多 OS 混合部署框架
拆分电商系统为微服务
1020. 飞地的数量
视频按每100帧存一个文件夹,处理完再图片转视频
List集合
Flutter 从零开始 006 单选开关和复选框
Biological network analysis using deep learning
List collection
Hisilicon 3559 universal platform construction: introduction to YUV format
A new journey of the smart court, paperless office, escorting the green trial of the smart court
A review of quantum neural networks 2022 for generating learning tasks
Introduction to new features of ES6
ZABBIX monitors the number of TCP connections
Redis configuration files and new data types
MySQL索引和优化的理解学习
串行通信接口8250






