当前位置:网站首页>@What happens if bean and @component are used on the same class?

@What happens if bean and @component are used on the same class?

2022-07-07 12:06:00 Program ape DD_

| Doubt description

lately , In the process of development , Found a way to write before , It's like this :

fd3a5a5639d24ab18b046d30446def0d.png
picture

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 :

a1f092e860c51848b4842f77384b7b9f.png
picture

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 .

d2a77c14745c4018a06bab6415fc6114.gif
picture

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 ?

https://www.cnblogs.com/youzhibing/p/14337244.html

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 .

21e81e9e8cdc028f177893b9aaa01c55.png
picture

therefore @Configuration It can be component scan.

among ConfigurationClassPostProcessor And @Configuration Is closely linked , The class inheritance structure is as follows :

b193b843223d39f91737ca06b21b59b6.png
picture

It has achieved BeanFactoryPostProcessor Interface and PriorityOrdered Interface .

About BeanFactoryPostProcessor, You can see :

https://www.cnblogs.com/youzhibing/p/10559337.html

from AbstractApplicationContext Of refresh Method called invokeBeanFactoryPostProcessors(beanFactory) Start , Follow the source code .

c406c091d144460e943934d58a2d10e0.gif
picture

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 .

8053a4ac4f86b3890d1bfb58997bdf41.png
picture

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

4019898ad7b54a44233805edb3b6230d.gif
picture
c222a22962e14bb3e4326322a2f49b71.png
picture

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

2fac0df9a5a8b1dd10b050c745f3a177.gif
picture

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 .

f58b72a05d6039a7f2d83a113ef4dc59.gif
picture

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 .

Let's see in detail .

c9899c542a2333553f65dcea682ce5c8.gif
picture

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 .

a014ec3c1ff008534117894f8463c82c.gif
picture

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 .

ab739a7a6b4715abae1ef81fde57c8e8.png
picture

Spring4.1.2 introduction isAllowBeanDefinitionOverriding() Method .

d89855f8f84e8775bc75086a8bf19d04.png
picture

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.

3a1fd8dfb8655da40560b1fc1a779ff9.png 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 .

9021e99e012ce698f70cc0b01ed9bf98.gif
picture

About allowBeanDefinitionOverriding, I think you should have made it clear .

We have created a high-quality technical exchange group , With good people , I will be excellent myself , hurriedly Click Add group , Enjoy growing up together . in addition , If you want to change jobs recently , Years ago, I spent 2 A wave of large factory classics were collected in a week , Those who are ready to change jobs after the festival can Click here to get

Recommended reading

··································

Hello , I'm a procedural ape DD,10 Old driver developed in 、 Alibaba cloud MVP、 Tencent cloud TVP、 I have published books and started a business 、 State-owned enterprises 4 In the Internet 6 year . From ordinary developers to architects 、 Then to the partner . Come all the way , My deepest feeling is that I must keep learning and pay attention to the frontier . As long as you can hold on , Think more 、 Don't complain 、 Do it frequently , It's easy to overtake on a curve ! therefore , Don't ask me what I'm doing now, whether it's in time . If you are optimistic about one thing , It must be persistence to see hope , Instead of sticking to it when you see hope . believe me , Just stick to it , You must be better than now ! If you don't have any direction , You can pay attention to me first , Some cutting-edge information is often shared here , Help you accumulate the capital to overtake on the curve .

Click to collect 2022 newest 10000T Learning materials

原网站

版权声明
本文为[Program ape DD_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071004028633.html