1, Introduction to SpringBoot starter
1.1 what is a starter
Before SpringBoot, if we want to use spring MVC to build our web project, we must do the following:
- First, we need to introduce spring MVC dependencies into the project
- Register the dispatcher servlet of spring MVC in web.xml and configure the url mapping
- Write springmcv-servlet.xml and configure several important components in spring MVC, such as handler mapping, handler adapter and view resolver
- Introduce the springmvc-servlet.xml file into the applicationcontext.xml file
- ...
The above steps only configure spring MVC. If we still need to interact with the database, we need to configure the database connection pool DataSource in application.xml. If we need database transactions, we also need to configure the TransactionManager
These are some of the problems caused by developing projects using the Spring framework:
- Dependency import: each project needs to maintain its dependent jar package separately, and what dependencies need to be introduced according to the functions used in the project. Manually importing dependencies is error prone and cannot be managed centrally
- Cumbersome configuration: complex configuration is required after dependency is introduced, and these configurations are necessary for each project, such as web.xml configuration (Listener configuration, Filter configuration, Servlet configuration), log4j configuration, database connection pool configuration, etc. These configurations are repetitive and complex, and need to be developed repeatedly in different projects, which greatly reduces our development efficiency
After the emergence of SpringBoot, it provides us with a powerful function to solve the above two pain points, which is SpringBoot starters (scene starters).
Spring Boot makes a series of scenario initiators by extracting our common function scenarios. These initiators help us import all the components that we need to rely on to realize various functions. We only need to introduce these starters into the project, and all the dependencies of relevant scenarios will be imported, and we can abandon complex configurations, Only a small amount of configuration through the configuration file is required to use the corresponding functions.
2, Principle of SpringBoot scenario launcher
After importing the starter, SpringBoot mainly helps us accomplish two things:
- Automatic import of related components
- Automatic configuration of related components
These two things are collectively called spring boot auto configuration
2.1 automatic configuration principle
2.1.1 acquisition and injection of automatic configuration class
Let's explore the principle of the whole process from the main program entrance:
@SpringBootApplication //This class is an application of springboot public class CommunityApplication { public static void main(String[] args) { //Start the springboot application SpringApplication.run(CommunityApplication.class, args); } }
I won't introduce the basics of Spring Boot. I recommend this practical tutorial:
https://github.com/javastacks...
@The internal structure of the SpringBootApplication annotation is shown in the following figure:
AutoConfigurationImportSelector: focus on the overridden selectImports method in this class to see how the returned string array is obtained:
We can go to the spring.factories file mentioned above, find the spring boot autoconfigure package officially provided by spring, and find the file below:
You can see that this is the candidate list of all automatic configuration classes officially provided by SpringBoot. We can find a familiar automatic configuration class to see its internal implementation:
You can see that these are JavaConfig configuration classes one by one, and some beans are injected into the container through @ Bean annotation
Conclusion:
- When SpringBoot starts, obtain the fully qualified class names of all automatic configuration classes specified by EnableAutoConfiguration from META-INF/spring.factories under the classpath
- Import these automatic configuration classes into the container, and the automatic configuration class will take effect to help us with automatic configuration;
- The whole J2EE solution and automatic configuration are in the jar package of spring boot autoconfigure;
- It will import many automatic configuration classes (xxxAutoConfiguration) into the container, that is, import all components required for this scenario into the container and configure these components;
- With the automatic configuration class, it eliminates the work of manually writing configuration injection function components;
2.1.2 automatic configuration process
After the automatic configuration class is injected into the container, it will help us with the automatic configuration and automatic injection of components. We take httpencoding autoconfiguration (Http encoding autoconfiguration) as an example to explain this process:
First, let's take a look at the mapping method between the configuration file and the POJO class in SpringBoot, which is the basis for automatic configuration.
Centralized configuration management: all configurable items in SpringBoot are centralized in one file (application.yml). The configuration in this file is associated with the POJO classes defined inside our program through the @ ConfigurationProperties annotation. These POJO classes are uniformly named xxxProperties, and each property field in these xxxProperties classes has its own default value, This is also the embodiment of the concept that the SpringBoot convention is greater than the configuration concept, so as to reduce the number of choices made by users as much as possible, but at the same time, it is not inactive. The configuration in the configuration file can override the default value at any time we want.
After that, the class bound to the configuration file can be automatically injected into the container for our use by cooperating with the @ EnableConfigurationProperties annotation.
Workflow of automatic configuration class:
- Inject the components into the container according to the defined conditions
- Use xxproperties to configure the related properties of the injected component
//Indicates that this is a configuration class. Like the previously written configuration file, you can also add components to the container; @Configuration //Inject a class bound to the configuration file into the container to make it effective //Enter the HttpProperties view and bind the corresponding values in the configuration file with HttpProperties; //And add HttpProperties to the ioc container @EnableConfigurationProperties(HttpProperties.class) //Spring underlying @ Conditional annotation //According to different conditions, if the specified conditions are met, the configuration in the whole configuration class will take effect; //This means to judge whether the current application is a web application. If so, the current configuration class will take effect @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) //Judge whether there is a CharacterEncodingFilter class in the system. If there is a configuration class, it will take effect @ConditionalOnClass(CharacterEncodingFilter.class) //Judge whether there is a configuration in the configuration file: spring.http.encoding.enabled; //matchIfMissing = true indicates that even if pring.http.encoding.enabled=true is not configured in our configuration file, the configuration class is effective by default; @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration { //This class is already bound to the configuration file private final HttpProperties.Encoding properties; //When building the automatic configuration class, the configuration class bound to the configuration file is passed in as an input parameter public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); } @Bean @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); //When injecting a bean, it is initialized with the value of the attribute in the configuration class, which is equivalent to mapping the value in the configuration file to some attributes of the component filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; //Inject configured bean s } }
In one sentence, summarize the working process of automatic configuration class:
- First, the container will determine whether the configuration class is effective according to different current conditions!
- Once the configuration class takes effect; This configuration class will add corresponding components to the container;
- The properties of these components are obtained from the corresponding properties classes, and each property in these classes is bound to the configuration file;
- All properties that can be configured in the configuration file are encapsulated in the xxxproperties class. What can be configured in the configuration file can refer to the property field in the property class corresponding to the prefix
//Get the specified value from the configuration file and bind it with the properties of the bean @ConfigurationProperties(prefix = "spring.http") public class HttpProperties { // ..... }
2.2 summary of spring boot automatic configuration
- SpringBoot boot will load a large number of auto configuration classes
- First, we can see whether the functions we need are in the auto configuration class written by SpringBoot by default;
- Let's look at which components are configured in this automatic configuration class; (as long as the component we want to use exists in it, we don't need to configure it manually)
- When adding components to the automatic configuration class in the container, some properties will be obtained from the properties class. We only need to specify the values of these attributes in the configuration file;
- Xxxautoconfiguration: automatic configuration class; Add components to container
- Xxxproperties: encapsulates the related properties in the configuration file;
After understanding the principle of automatic assembly, let's pay attention to a detail. The automatic configuration class must take effect under certain conditions@ Conditional derived annotation (the native @ conditional function of Spring annotation version)
Function: only when the conditions specified by @ Conditional are satisfied can components be added to the container and all contents in the configuration take effect;
So many auto configuration classes can only take effect under certain conditions; In other words, we loaded so many configuration classes, but not all of them took effect.
How do we know which auto configuration classes work?
We can enable the debug=true attribute; To let the console print the automatic configuration report, so that we can easily know which automatic configuration classes are effective;
#Open the debugging class of springboot in the configuration file debug=true
Positive matches: (auto configuration class enabled: positive matches)
Positive matches: ----------------- AopAutoConfiguration matched: - @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice', 'org.aspectj.weaver.AnnotatedElement' (OnClassCondition) - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition) AopAutoConfiguration.CglibAutoProxyConfiguration matched: - @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition) AuditAutoConfiguration#auditListener matched: - @ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.listener.AbstractAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition) AuditAutoConfiguration#authenticationAuditListener matched: - @ConditionalOnClass found required class 'org.springframework.security.authentication.event.AbstractAuthenticationEvent' (OnClassCondition) - @ConditionalOnMissingBean (types: org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches: (no startup, no matching successful automatic configuration class: negative matching)
Negative matches: ----------------- ActiveMQAutoConfiguration: Did not match: - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition) AopAutoConfiguration.JdkDynamicAutoProxyConfiguration: Did not match: - @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property 'proxy-target-class' (OnPropertyCondition) AppOpticsMetricsExportAutoConfiguration: Did not match: - @ConditionalOnClass did not find required class 'io.micrometer.appoptics.AppOpticsMeterRegistry' (OnClassCondition) ArtemisAutoConfiguration: Did not match: - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
Exclusions, Unconditional classes:
Exclusions: ----------- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration Unconditional classes: ---------------------- org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration
3, Custom Scene launcher
Now that we have understood the concept of scenario launcher and the principle of automatic configuration hidden behind it, we can expand the functions of SpringBoot and define our own scenario launcher.
3.1 naming specification of starter
Official namespace
- Prefix: spring boot starter-
- Mode: spring boot starter module name
- Examples: spring boot starter web, spring boot starter JDBC
Custom namespace
- Suffix: - spring boot starter
- Mode: module spring boot starter
- Example: mybatis spring boot starter
Recommend a basic Spring Boot tutorial and practical example:
https://github.com/javastacks...
3.2 overall structure of starter module
Through the above introduction, we can summarize the overall implementation logic of starter, which is mainly composed of two basic parts:
xxxAutoConfiguration: automatic configuration class, which automatically injects some components that need to be used in a scenario, and uses the xxxProperties class to configure components
xxxProperties: the integration of all configurable properties in a scenario. The property values can be overridden by configuring in the configuration file. According to the official definition of SpringBoot, the role of starter is to rely on aggregation. Therefore, it is not in line with the regulations to directly implement the code inside the starter. The starter should only rely on import, The specific code implementation should be handed over to other modules for implementation, and then the module can be referenced in the starter. Therefore, the overall composition of the starter should be as shown in the figure below:
It can be seen that the starter module depends on two parts, one is some common dependencies, and the other is the dependence on the automatic configuration module. The specific implementation of xxxAutoConfiguration and xxxProperties are encapsulated in the automatic configuration module. In fact, the starter provides corresponding functions externally through this module.
3.3 autoconfigure module development
3.3.1 dependency import
First, all automatic configuration modules need to introduce two jar package dependencies:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <!-- Definitions that contain many annotations related to automatic configuration must be introduced --> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <!-- It's not necessary. After importing, you can enter our custom configuration in the configuration file with corresponding prompt, or through other methods.properties File for attribute mapping of related classes( SpringBoot Default use application.yml)--> <optional>true</optional> </dependency> <dependencies>
Other dependencies can be added according to the needs of the project
3.3.2 implementation of xxxautoconfiguration
The most important thing in the autoconfigure module is to write the automatic configuration class, which realizes the automatic configuration and automatic injection of components for us.
When writing automatic configuration classes, we should consider what components are injected into the container and how to configure it.
@Configuration @ConditionalOnxxx @ConditionalOnxxx//Some conditions that limit the effectiveness of automatic configuration classes @EnableConfigurationProperties(xxxProperties.class) public class xxxAutoConfiguration { @Autowired private xxxProperties properties; @Bean public static BeanYouNeed beanYouNeed() { BeanYouNeed bean = new BeanYouNeed() bean.setField(properties.get(field)); bean.setField(properties.get(field)); bean.setField(properties.get(field)); ...... } }
3.3.3 implementation of xxproperties
This is a class bound to the configuration file. The properties inside are the contents we can configure in the configuration file, and then bind them to the configuration file through @ ConfigurationProperties:
@ConfigurationProperties(prefix = "your properties") //Bind the configuration file using the @ ConfigurationProperties annotation public class xxxProperties { private boolean enabled = true; private String clientId; private String beanName; private String scanBasePackage; private String path; private String token; }
3.3.4 configuring the spring.factories file
Create a new META-INF folder under the resource directory, a new spring.factories file under the folder, and add the written xxautoconfiguration class:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.meituan.xframe.boot.mcc.autoconfigure.xxxAutoConfiguration
3.4 Starter module development
Only dependency import is performed in the starter module. Add the dependency on the autoconfigure module in the pom file, and add some other necessary dependencies:
<dependencies> ================================================================ <!--Added pair autoconfigure Module reference--> <dependency> <groupId>com.test.starter</groupId> <artifactId>xxx-spring-boot-autoconfigure</artifactId> </dependency> =============================================================== <!--Other necessary dependencies--> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> </dependencies>
After the two modules are developed, publish the package to the local or central warehouse through mvn install command or deploy command, and you can directly reference our customized starter module in other projects
Source: blog.csdn.net/qq_21310939/article/details/107401400
Recent hot article recommendations:
1.1000 + Java interview questions and answers (2021 latest version)
2.Stop playing if/ else on the full screen. Try the strategy mode. It's really fragrant!!
3.What is the new syntax of xx ≠ null in Java?
4.Spring Boot 2.6 was officially released, a wave of new features..
5.Java development manual (Songshan version) is the latest release. Download it quickly!
Feel good, don't forget to like + forward!