Part I: Introduction to basics -- understanding the principle of automatic configuration [i]
1, Container function
1. Add @ Configuration component
Case test:
(1) Configuration class
package org.apache.springboot.config; import org.apache.springboot.bean.Pet; import org.apache.springboot.bean.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** *The @ Bean annotation is used in the configuration class to register components for the container on the method. By default, it is also single instance * The configuration class itself is also a component */ @Configuration //Tell SpringBoot that this is a configuration class = = configuration file public class MyConfig { @Bean //Add components to the container. Take the method name as the id of the component. The return type is the component type. The returned value is the instance of the component in the container public User user01(){ // User zhangsan = new User("zhangsan", 18); //The user component depends on the Pet component return new User("zhangsan",18); } @Bean("tom") //Adding the tag "tom" mainly replaces the method name. Printing will only print out "tom", not tomcatPet. However, if this tag is not added to the "Bean" annotation, it will print the method name, such as user01 method public Pet tomcatPet(){ return new Pet("tomcat"); } }
(2) startup
package org.apache.springboot; import org.apache.springboot.bean.Pet; import org.apache.springboot.config.MyConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ComponentScan; /** * Main program class * @SpringBootApplication: This is a SpringBoot application */ @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) public class MainApplication { public static void main(String[] args) { //1. Return to our IOC container ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2. View the information in the container String[] names = run.getBeanDefinitionNames(); for (String name :names){ System.out.println(name); } //Get components from container Pet tom01 = run.getBean("tom", Pet.class); Pet tom02 = run.getBean("tom", Pet.class); System.out.println("Components:"+(tom01==tom02)); MyConfig bean = run.getBean(MyConfig.class); System.out.println(bean); } }
Printout:
When we want to call the method under the @ bean annotation of the configuration class, such as the user01 method.
You only need to add @ Configuration(proxyBeanMethods = true) to the configuration class
Then get the method in the startup class, such as:
When we start, we find that the printout is true, indicating that we have obtained the method
Specify the proxyBeanMethods = true parameter in the annotation, which adopts the Full mode. Ensure that the returned component of each @ Bean method is single instance no matter how many times it is called, that is, no matter how many times it is called by the external registration method of this component in the configuration class, it will get the single instance object in the previous registration container
Description:
If the @ Configuration(proxyBeanMethods = true) proxy object calls the method. SpringBoot always checks whether the component is in the container.
If @ Configuration(proxyBeanMethods = false), the method is not called by the proxy object. The returned result is false. How many times each @ Bean method is called, the returned component is newly created
Component dependencies must use the Full mode default. Other default Lite modes
2, Automatic configuration [source code analysis] - principle of automatic package rules
1,@SpringBootConfiguration
Represents the current configuration class
2,@ComponentScan
Specify which Spring annotations to scan
3,@EnableAutoConfiguration
@AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {}
3.1,@AutoConfigurationPackage
Auto configuration package? The default package rule is specified
Check the source code, enter "AutoConfigurationPackages" with ctrl+n, and batch register the register method
In fact, in the source code, there is a registerBeanDefinitions method with two parameters:
@Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0])); }
Annotation metadata: meta information of annotations, mainly used to register AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class) //Import a component into the container public @interface AutoConfigurationPackage {} //Use the Registrar to import a series of components into the container //Import all components under a specified package? Under the package of MainApplication.
From debug, you can see where the meta information of the register annotation is explained
In fact, it is really assigned to the startup class
At the same time, it uses new packageimports (metadata) Getpackagenames(), get meta package name
Therefore, import all components under the specified package into the package where MainApplication is located