1. Configuration classes

The @Configuration annotation tells SpringBoot that this is a Configuration class.

This configuration is familiar, having been used in the previous Spring-related use of full annotations.

In a configuration class, you can use the @bean tag to register components to the container on methods, which are singleton by default.

@configuration // Tells SpringBoot that this is a Configuration class == Configuration file public class MyConfig {@bean ("user1") // Add components to the container. Use the square name as the component ID. The return type is the component type. Public User user01(){return new User("pingguo", 20); } @Bean("pet1") public Pet tomcatPet(){ return new Pet("tomcat"); }}Copy the code

The main running class is the same as in the previous example, printing out the names of all the components.

As you can see, there are two components registered above: user1 and pet1.

Configuration classes are themselves components

In the main method of the main running class, add an output to get the configuration class:

@SpringBootApplication(scanBasePackages = "com.pingguo") public class MainApplication { public static void main(String[] The args) {/ / return the IOC container final ConfigurableApplicationContext run = SpringApplication. Run (MainApplication. Class, args); / / check container components final String [] beanDefinitionNames = run. GetBeanDefinitionNames (); for (String name: beanDefinitionNames) { System.out.println(name); } // Get components from the container MyConfig bean = run.getBean(myconfig.class); System.out.println(" Config class is also component: "+ bean); }}Copy the code

Run main,

You can see the last output, which shows that the configuration class is itself a component.

3. Properties of proxyBeanMethods

Since springboot2.0, @configuration has added a property proxyBeanMethods to proxy beans.

The default value is true, which means that the configuration class is proxyed (CGLIB), and springBoot always checks for the presence of the component in the container when other @bean annotated methods are called in the same configuration file to retrieve the object.

If it’s in the container, just take it. If it does not exist, it will be created to ensure a single instance.

Now let’s look at the false case.

@configuration (proxyBeanMethods = false) public class MyConfig {@bean ("user1"); Use the square name as the component ID. The return type is the component type. Public User user01(){return new User("pingguo", 20); } @Bean("pet1") public Pet tomcatPet(){ return new Pet("tomcat"); }}Copy the code

In the main run program, get objects from the calling method to determine whether the objects are equal.

@SpringBootApplication(scanBasePackages = "com.pingguo") public class MainApplication { public static void main(String[] The args) {/ / return the IOC container final ConfigurableApplicationContext run = SpringApplication. Run (MainApplication. Class, args); / / check container components final String [] beanDefinitionNames = run. GetBeanDefinitionNames (); for (String name: beanDefinitionNames) { System.out.println(name); } // Get components from the container MyConfig bean = run.getBean(myconfig.class); System.out.println(" Config class is also component: "+ bean); User user1 = bean.user01(); User user2 = bean.user01(); System.out.println(user1 == user2); }}Copy the code

If you look at the final output, it will be false.

Full mode Lite mode

  • Full (proxyBeanMethods = true) : In this mode, the same component injected into the container is the same bean instance, i.e. singleton, no matter how many times it is fetched.

In this mode SpringBoot checks for the presence of the component in the container each time it is started.

  • Lite (proxyBeanMethods = false): In this mode, the same component injected into the container is a different bean instance no matter how many times it is fetched.

In this mode, SpringBoot skips checking for the presence of the component in the container each time it is started.

So what scenario is this supposed to solve? Answer: Component dependencies.

Scenarios with component dependencies

Look at the two entity classes: User and Pet.

public class User { private String name; private Integer age; private Pet pet; . .Copy the code

Fixed code parts: parameter constructs, no-parameter constructs, get and set methods, toString methods, are omitted.

public class Pet { private String name; . .Copy the code

Modify the methods in the config class:

@Configuration(proxyBeanMethods = true) public class MyConfig { @Bean("user1") public User user01(){ User pingguo = new User("pingguo",20); pingguo.setPet(tomcatPet()); return pingguo; } @Bean("pet1") public Pet tomcatPet(){ return new Pet("tomcat"); }}Copy the code

Use the main method to test it:

// dependencies User user01 = run.getBean("user1", user.class); Pet pet1 = run.getBean("pet1", Pet.class); System.out.println(" dependency: "+ (user01.getpet () == pet1));Copy the code

If proxyBeanMethods = true, the pet of the User object is the pet of the container.

If so, the result is true.

If proxyBeanMethods = false, run proxyBeanMethods = false

So when are these two modes used?

Full mode is recommended when there are dependencies between bean instances injected into containers in your same Configuration class.

When there are no dependencies between bean instances injected into the container in your same Configuration class, Lite Lightweight mode is recommended to improve springBoot startup speed and performance.