Starter introduction of SpringBoot

1.1 What is a Starter?

Before SpringBoot, if we wanted to use SpringMVC to build our Web projects, we had to do a few things:

  • First, we need to introduce SpringMVC dependencies into the project
  • To register SpringMVC in web.xmlDispatcherServletAnd configure the URL mapping
  • writespringmcv-servlet.xmlIn which, several important components of SpringMVC are configured, such as HandlerMapping, HandlerAdapter and ViewResolver.
  • inapplicationcontext.xmlFile importspringmvc-servlet.xmlfile

If we need to interact with the database, we need to configure the DataSource in the application.xml file. If we need to interact with the database, we need to configure the TransactionManager.

Here are some of the problems with developing projects using the Spring framework:

  • Dependency import issues: Each project needs to maintain its own dependent JAR packages separately, and the dependencies need to be introduced depending on the functionality used in the project. Manually importing dependencies is error-prone and cannot be managed in a centralized manner
  • Cumbersome configuration: After introducing dependencies, there are complex configurations that are necessary for every project, such as web.xml configuration (Listener configuration, Filter configuration, Servlet configuration), log4J configuration, database connection pool configuration, and so on. These configurations are repetitive and complex, requiring multiple iterations in different projects, which greatly reduces our development efficiency

When SpringBoot came along, it provided us with a powerful solution to those two pain points: SpringBoot’s starters.

Spring Boot is a series of scenario starters that we extracted from our common functional scenarios, and these starters helped us import all of the specific components that we relied on to implement each function. We just introduced these Starters into the project, and all of the specific scenarios’ dependencies would be imported. And we can do away with the complex configuration, just through the configuration file for a small amount of configuration can use the corresponding function.

Principles of the SpringBoot initiator

After the imported starter, SpringBoot does two main things for us:

  • Automatic import of related components
  • Automatic configuration of related components

These two things together are called automatic configuration of SpringBoot

2.1 Principles of Automatic Configuration

2.1.1 Automatic configuration class acquisition and injection

Let’s explore how the process works from the main entry:

Public class CommunityApplication {public static void main(String[]) {public static void main(String[]) The args) {/ / start applying springboot SpringApplication run (CommunityApplication. Class, args); }}Copy the code

Spring Boot foundation is not introduced, recommend the actual combat tutorial: github.com/javastacks/…

The internal structure of the @SpringBootApplication annotation is shown below:

AutoConfigurationImportSelector: focus on the class of rewriting selectImports method, take a look at it returns an array of strings is how:

You can use the spring-boot-autoconfigure package in the “Spring. factories” file.

You can see that this is the candidate list of all the auto-configuration classes that SpringBoot has officially provided for us. We can find a familiar auto-configuration class and take a look at its internal implementation:

You can see that each of these is a JavaConfig configuration class, and all of them inject some beans into the container via the @Bean annotation

Conclusion:

  • SpringBoot starts from the classpathMETA-INF/spring.factoriesGets the fully qualified class names of all auto-configuration classes specified by EnableAutoConfiguration
  • Import these auto-configuration classes into the container, and the auto-configuration classes take effect to help us with the auto-configuration work.
  • The entire J2EE solution and automatic configuration is therespring-boot-autoconfigureJar package;
  • It imports a lot of auto-configuration classes (xxxAutoConfiguration) into the container, which is to import all the components needed for this scenario into the container and configure them;
  • With the automatic configuration class, we do not need to manually write configuration injection function components;

2.1.2 Automatic configuration process

Automatic configuration class is injected into the container, will help us to component’s automatic configuration and automatic injection of work, we take HttpEncodingAutoConfiguration (Http code automatic configuration) as the example to explain the process:

Let’s start by looking at the way configuration files are mapped to POJO classes in SpringBoot, which is the basis for automatic configuration.

Centralized configuration management: All configurable items in SpringBoot are concentrated in a single file (application.yml). The configuration in this file is associated with POJO classes defined internally by our program through the @ConfigurationProperties annotation. These POJO classes are named xxxProperties, and each property field in these xxxProperties classes has its own default value, which is an example of SpringBoot convention over configuration, minimizing the number of choices the user has to make while maintaining flexibility. The configuration in the configuration file can override the defaults whenever we want.

Later, through cooperating with @ EnableConfigurationProperties annotations, can automatically and binding configuration file is good for us to use this class into the container.

The workflow of the auto-configuration class:

  • Inject components into a container based on qualified conditions
  • Use xxxProperties to configure the related properties of the injected component
// Indicates that this is a configuration class that can add components to the container just like the configuration files we wrote before; @configuration // Inject a class that is bound to the Configuration file into the container for it to take effect // Go to HttpProperties and bind the corresponding value in the Configuration file to HttpProperties; / / and the HttpProperties join the ioc container @ EnableConfigurationProperties (HttpProperties. Class) / / Spring bottom @ Conditional comments / / judging according to different conditions, If the specified conditions are met, the configuration in the entire configuration class takes effect. // Check whether the current application is a Web application. If so, The current configuration class effective @ ConditionalOnWebApplication (type = ConditionalOnWebApplication. Type. The SERVLET) / / judgment have CharacterEncodingFilter this class in the system, if there is only effective configuration class @ ConditionalOnClass (CharacterEncodingFilter. Class) / / judge whether there is a configuration file configuration: Spring. HTTP. Encoding. Enabled; / / matchIfMissing = true indicates that even if we are in the configuration file is not configured pring. HTTP. Encoding. The enabled = true, the configuration class is also the default effect; @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", MatchIfMissing = true) public class HttpEncodingAutoConfiguration {/ / this class has been with the configuration file binding private final HttpProperties. The Encoding  properties; / / build the automatic configuration class is to bind with the configuration file configuration such as the participation in public HttpEncodingAutoConfiguration (HttpProperties properties) {enclosing the properties = properties.getEncoding(); } @Bean @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); // The bean is initialized with the value of the property in the configuration class, Equivalent to the value in the configuration file is mapped to the filter on the certain properties of components. SetForceRequestEncoding (this) the properties) shouldForce (Type. REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; // Inject the configured bean}}Copy the code

A quick summary of how the auto-configuration class works:

  • First, the container decides whether the configuration class is valid or not based on the current conditions.
  • Once this configuration class takes effect; This configuration class adds components to the container;
  • The properties of these components are obtained from the corresponding Properties classes, each of which is bound to the configuration file;
  • All properties that can be configured in the configuration file are encapsulated in the xxxxProperties class. What can be configured in the configuration file? Refer to the property field in the property class corresponding to this prefix
@configurationProperties (prefix = "spring.http") public class HttpProperties {//..... }Copy the code

2.2 Summary of SpringBoot Automatic configuration

  • SpringBoot launches load a large number of auto-configuration classes

  • We can first see if the functionality we need is in the automatic configuration class written by SpringBoot default;

  • Let’s take a look at what components are configured in this auto-configuration class; (As long as the component we want to use exists in it, we don’t need to configure it manually.)

  • When you add a component to the auto-configuration class in the container, you get some properties from the Properties class. We only need to specify the values of these properties in the configuration file;

    • xxxxAutoConfigurartion: automatic configuration class; Add components to the container
    • xxxxProperties: encapsulates properties in the configuration file.

After understanding the principle of auto-assembly, let’s pay attention to a detail. Auto-configuration classes must be effective under certain conditions. @Conditional derived annotations (the native @Conditional role of Spring annotations)

Function: only if the conditions specified in @Conditional are true, can a component be added to the container, and all the contents in the configuration take effect;

There are so many auto-configuration classes that must be effective under certain conditions. That is, we loaded so many configuration classes, but not all of them worked.

How do we know which auto-configuration classes are in effect?

We can do this by enabling the debug=true attribute; To have the console print the auto-configuration report, so we can easily know which auto-configuration classes are in effect;

# Enable springBoot debug=true in the configuration fileCopy the code

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)
Copy the code

Negative matches: (Not started, no auto-configuration classes successfully matched: Negative matches)

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)
Copy the code

Exclusions, enfeavers classes (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
Copy the code

3. Customize the scenario initiator

Now that we understand the concept of a scene launcher and the underlying principle of auto-configuration, we can extend SpringBoot’s capabilities and define our own scene launcher.

3.1 Naming conventions of starter

Official namespace

  • The prefix: spring – the boot – starter –
  • Mode: spring-boot-starter- Module name
  • For example, spring-boot-starter-web and spring-boot-starter- JDBC

Custom namespaces

  • Suffix: – spring – the boot – the starter
  • Mode: module-spring-boot-starter
  • Example: mybatis – spring – the boot – the starter

Spring Boot: github.com/javastacks/…

3.2 Overall structure of the Starter module

From the above introduction, it can be concluded that the overall implementation logic of starter consists of two basic parts:

XxxAutoConfiguration: Automatic configuration class. It can automatically inject some components that need to be used in a certain scenario, and use the xxxProperties class to configure components

XxxProperties: According to the official definition of SpringBoot, the function of a Starer is to rely on aggregation. Therefore, it is not appropriate to implement code directly within the starter. The starter should only play the role of relying on import. The specific code implementation should be handed over to other modules to implement, and then reference the module in the starter, so the overall composition of the starter should be as follows:

It can be seen that the starter module relies on two parts, one is some common dependencies, the other is the dependence on the automatic configuration module, and the specific implementation of xxxAutoConfiguration and xxxProperties are encapsulated in the automatic configuration module. The starter provides external functions through the starter module.

3.3 Autoconfigure module development

3.3.1 Dependency introduction

First, all auto-configuration modules introduce two JAR dependencies:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <! Contains definitions of many auto-configuration-related annotations, </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <! -- Optional, you can enter our custom configuration in the configuration file when the corresponding prompt, Properties file (SpringBoot uses application.yml by default)--> <optional>true</optional> </dependency> <dependencies>Copy the code

Other dependency options can be added based on project needs

3.3.2 implementation of xxxAutoConfiguration

The most important thing in autoconfigure module is the preparation of automatic configuration class, which realizes automatic configuration and automatic injection of components for us.

When writing an auto-configuration class, we should think about what components to inject into the container and how to configure it.

@ Configuration @ ConditionalOnxxx @ ConditionalOnxxx / / qualified automatic Configuration class effect of some conditions @ 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)); . }}Copy the code

3.3.3 implementation of xxxProperties

This is the class that is bound to the configuration file. The properties in the class are things that we can configure in the configuration file and then bind to the configuration file via @ConfigurationProperties:

@configurationProperties (prefix = "your properties") // Use the @configurationProperties annotation to bind the configuration file public class xxxProperties { private boolean enabled = true; private String clientId; private String beanName; private String scanBasePackage; private String path; private String token; }Copy the code

3.3.4 Configuring the Spring. factories file

“Spring. factories” (xxxAutoConfiguration)

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.meituan.xframe.boot.mcc.autoconfigure.xxxAutoConfiguration
Copy the code

3.4 Starter module Development

The starter module does dependency imports only, add the autoConfigure module dependencies to the POM file, and add some other necessary dependencies:

<dependencies> ================================================================ <! Starter </groupId> <dependency> com.test.starter</groupId> <artifactId>xxx-spring-boot-autoconfigure</artifactId> </dependency> = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = <! --> <dependency> <groupId> Commons -collections</groupId> <artifactId> Commons -collections</artifactId> </dependency> </dependencies>Copy the code

Once both modules are developed, we can publish the package to a local or central repository using the MVN install command or deploy command to reference our custom starter module directly in other projects

Source: blog.csdn.net/qq_21310939/article/details/107401400

Recent hot articles recommended:

1.1,000+ Java Interview Questions and Answers (2021)

2. Don’t use if/ else on full screen again, try strategy mode, it smells good!!

3. Oh, my gosh! What new syntax is xx ≠ null in Java?

4.Spring Boot 2.6 is out with a lot of new features.

5. “Java Development Manual (Songshan version)” the latest release, quick download!

Feel good, don’t forget to click on + forward oh!