@The difference between component and @ configuration as configuration classes

Time:2021-8-2

With the fire of spingboot, annotated configuration has been warmly welcomed by everyone. Both @ component and @ configuration can be used as configuration classes. I haven’t thought there is any difference between the two before. Maybe sometimes the program runs differently from what I think.

Until you see this article:my.oschina.net/guangshan/blog/1807…。 I realize that @ component and @ configuration are different, and wrong use may lead to serious consequences.

See the following code:

@Configuration
public class MyTestConfig {

    @Bean
    public Driver driver(){
        Driver driver = new Driver();
        driver.setId(1);
        driver.setName("driver");
        driver.setCar(car());
        return driver;
    }

    @Bean
    public Car car(){
        Car car = new Car();
        car.setId(1);
        car.setName("car");
        return car;
    }
}

The test code is as follows

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests {

    @Autowired
    private Car car;

    @Autowired
    private Driver driver;

    @Test
    public void contextLoads() {
        boolean result = driver.getCar() == car;
        System.out.println(result ? " Same car ":" different cars ");
    }

}

The printing results are as follows:
Same car

Print results after replacing with component:
Different cars
From the above results, it can be found that when using configuration, the same object is in the driver and spring containers, while when using component, it is different.
The reason for the different results is in the configurationclasspostprocessor class. Cglib proxy is performed for the annotated @ configuration class by calling the enhanceconfigurationclasses method
Although the Component annotation will also be treated as a configuration class, it will not generate a cglib proxy class for it. Therefore, when generating the driver object and the car object, the car () method is called to perform the new operation twice, so it is a different object. At that time, the configuration annotation generates the subclass class of the current object and intercepts the method. When calling the car () method for the second time, the object is directly obtained from the beanfactory, so the same object is obtained.

This work adoptsCC agreement, reprint must indicate the author and the link to this article