@Detailed explanation of the difference between Configuration and @ Component as Configuration classes

Posted by rfighter on Fri, 29 Oct 2021 13:49:50 +0200

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.

Topics: Java Spring Back-end