Preface: This article mainly introduces the differences between @ Configuration and @ Component as Configuration classes in detail. It is introduced in great detail through example code, which has certain reference and learning value for everyone's study or work. Friends who need to learn together with Xiaobian
1. Class of @ configuration annotation:
@Configuration public class test { @Bean public User getUser1(){ return User.builder().id(6).aBC("6").address("6").name("6").num(6).build(); } @Bean public User getUser2(){ return User.builder().id(7).aBC("7").address("7").name("7").num(7).build(); } @Bean public User getUser3( ){ return getUser1(); } @Bean public User getUser4(){ return getUser2(); } }
2. Class of @ Component annotation:
@Component public class test { @Bean public User getUser1(){ return User.builder().id(6).aBC("6").address("6").name("6").num(6).build(); } @Bean public User getUser2(){ return User.builder().id(7).aBC("7").address("7").name("7").num(7).build(); } @Bean public User getUser3( ){ return getUser1(); } @Bean public User getUser4(){ return getUser2(); } }
3. Test
public class UserServiceTest extends ReadwriteApplicationTests { @Resource User getUser1; @Resource User getUser2; @Resource User getUser3; @Resource User getUser4; @Test public void test1(){ System.out.println(getUser1==getUser3); System.out.println(getUser2==getUser4); System.out.println(getUser1); System.out.println(getUser2); System.out.println(getUser3); System.out.println(getUser4); } }
4. Results
4.1 results of @ component
false false User(id=6, num=6, name=6, address=6, aBC=6) User(id=7, num=7, name=7, address=7, aBC=7) User(id=6, num=6, name=6, address=6, aBC=6) User(id=7, num=7, name=7, address=7, aBC=7)
4.2 results of @ configuration
true true User(id=6, num=6, name=6, address=6, aBC=6) User(id=7, num=7, name=7, address=7, aBC=7) User(id=6, num=6, name=6, address=6, aBC=6) User(id=7, num=7, name=7, address=7, aBC=7)
5. Analysis
When you click @ Configuration, you will find that it is also modified by @ Component, so context: Component scan / or @ ComponentScan can handle the classes annotated by @ Configuration.
@The class of the Configuration tag must meet the following requirements:
The configuration class must be provided in the form of a class (not an instance returned by a factory method), allowing runtime enhancement (cglib dynamic proxy) by generating subclasses.
The configuration class cannot be final (it cannot be dynamically represented).
Configuration annotation is usually used to generate Spring container managed classes through @ Bean annotation,
The configuration class must be non local (that is, it cannot be declared in a method or private).
Any nested configuration class must be declared static.
@Bean methods may not in turn create further configuration classes (that is, if the returned bean has
@Configuration will not be specially processed, but will only be used as an ordinary bean).
However, when the spring container is started, it has a class specially dealing with @ Configuration, which will enhance the cglib dynamic proxy modified by @ Configuration. This is part of the reason why @ Configuration needs to meet the above requirements. What do you know about the enhancement?
Here is the idea of personal sorting. If there is any mistake, please give me some advice
getUser1() is called in getUser3(), because it is the method, which is necessarily getUser3() to generate a new User.build(), so the dynamic proxy will be judged if it is added. If the @bean method is modified in getUser3(), it will call the getUser1 instance in the spring container directly instead of calling getUser1(), which must be an object. Because the beans in the spring container are singletons by default. I don't understand beans such as xml configuration
<bean id="country" class="com.hhh.demo.Country" scope="singleton"/>
Here, the scope defaults to a singleton.
But if I just want to use @ Component, what if the class without @ Component has no dynamic proxy?
5.1 the class of @ component has no dynamic proxy, but @ Qualifier or @ Resource can be used
@Component public class test { @Resource private User getUser1; @Bean public User getUser1(){ return User.builder().id(6).aBC("6").address("6").name("6").num(6).build(); } @Bean public User getUser2(){ return User.builder().id(7).aBC("7").address("7").name("7").num(7).build(); } @Bean public User getUser3(){ return getUser1; } @Bean public User getUser4(@Qualifier("getUser2") User user){ return user; } }
This ensures that it is the same User instance
By the way, generally, it does not affect the results. Although it is not the same instance, the content is the same.