Today, let’s talk about the principle of SpringBoot automatic configuration. In our previous Web project development process, configuration files were cumbersome, and if multiple frameworks are integrated, they may also maintain multiple configuration files. This will take a lot of time to maintain the configuration file, if adding a small feature may require a complex configuration. With SpringBoot, the situation has improved so much that if we use the default configuration, we don’t have to spend time with these configuration files and focus on how our business functions should be implemented.

How does SpringBoot work without seeing where all the configuration items are configured? First we create a Web project, through the IDEA tool, you can directly create a running Web project, I will not demonstrate here. This directory structure is created with a default startup class.

Get down to business; SpringBoot automatic configuration is still mainly dependent on @SpringBootApplication in the boot class, which we can see by clicking on this annotation

Automatic configuration principle:

When SpringBoot starts, the main configuration class is loaded, enabling automatic configuration @enableAutoConfiguration;

@ EnableAutoConfiguration role:

Using EnableAutoConfigurationImportSelector to import some components in the container; We can click on @enableAutoConfiguration to see how it works at the bottom; As shown in figure

You can see the @ Import (AutoConfigurationImportSelector. Class); The point continuously, we will see AutoConfigurationImportSelector getCandidateConfigurations method in class;

     

You can see the auto-selector class; List<String> configurations =SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Methods; Through SpringFactoriesLoader. LoadFactoryNames () to load? Go ahead and click loadFactoryNames() to find it;Copy the code

You can see what’s going on in the SpringFactoriesLoader class;

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if(result ! =null) {
			return result;
		}

		try{ Enumeration<URL> urls = (classLoader ! =null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for(Map.Entry<? ,? > entry : properties.entrySet()) { List<String> factoryClassNames = Arrays.asList( StringUtils.commaDelimitedListToStringArray((String) entry.getValue())); result.addAll((String) entry.getKey(), factoryClassNames); } } cache.put(classLoader, result);return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex); }}Copy the code

  1. SpringFactoriesLoader.loadFactoryNames()
  2. Scan META‐INF/spring.factories under all JAR packages classpath
  3. Wrap the contents of these scanned files as properties objects
  • Obtained from the properties to EnableAutoConfiguration. The class class (class name) corresponding values, then add them in the container;

Add all the EnableAutoConfiguration values configured in meta-INF/Spring. factories under the classpath to the container.

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
    org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
    org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
    org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
    org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
    org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
    org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
    org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
    org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
    org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
    org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
    org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
    org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
    org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
    org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
    org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
    org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
    org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
    org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
    org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
    org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
    org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
    org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
    org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
    org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
    org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
    org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
    org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
    org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
    org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
    org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
    org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
    org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
    org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
    org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
    org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
    org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
    org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
    org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
    org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
    org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
Copy the code

Take a look at what the auto-configuration class does for us; It turns out that basically SpringBoot, which we use a lot, has been taken into account for us, with configuration added to the container; And these configuration classes have a common feature is to end with **AutoConfiguration, each automatic configuration, is through the configuration class to load the configuration into the container; If you are familiar with sping configuration, you will know that when you want to use a feature, you will also configure the specific configuration into the Spring container, which is automatically configured by springBoot.

How is SpringBoot auto-configuration configured? Can we customize the configuration to suit our needs? Let’s take a look at how this auto-configuration is implemented and how we can customize the configuration if we write it ourselves.

First we need to familiarize ourselves with two notes:

1. @Component // To inject POJO objects into the container, you map each property value to the container

@configurationProperties // Tells SpringBoot to bind all properties in this class to the relevant configuration in the configuration file; Prefix = “”: all the attributes under the configuration file are mapped one by one

I use a small example to demonstrate the use of these two annotations. We read the property values in the configuration file (to explain why SpringBoot resolves the property values in the configuration file).

First, let’s look at two entity classes, a Cat class and a Person class.


public class Cat {
    private String name;
    private int age;

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge(a) {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString(a) {
        return "Cat{" +
                "name='" + name + ' '' + ", age=" + age + '}'; }Copy the code
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private int age;
    private List<String> list;
    private List<Cat> listCat;
    private Map<String,String> map;

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge(a) {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getList(a) {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, String> getMap(a) {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public String toString(a) {
        return "Person{" +
                "name='" + name + ' '' + ", age=" + age + ", list=" + list + ", listCat=" + listCat + ", map=" + map + '}'; } public List
      
        getListCat() { return listCat; } public void setListCat(List
       
         listCat) { this.listCat = listCat; }
       
      Copy the code

And then we’re going to assign these properties in the configuration file, and then we’re going to look at these class objects and see if we can get the values that we assigned to these properties in the configuration file;

The configuration file application.yml(the default springBoot configuration file is application.properties&application.yml) recognizes both of these springBoots but uses different syntax. The.yML configuration I’m using here; The syntax of yML can be found on the Internet. Here is the value assigned to the entity class attributes through the configuration file.

server:
  port: 8081
person:
  name: jerry
  age: 24
  list:
    - tom
    - jack
  listCat:
    - cat:
      name: mary
      age: 4
    - cat:
      name: rose
      age: 30
  map:
   {k1: v1.k2: 12}
Copy the code

Once the assignment is complete, the value must be evaluated, so let’s use the test class that the project automatically generates to print our generated value;

With the @ConfigurationProperties annotation, the prefix attribute is used to successfully read the value from the configuration file and inject it into the container;

Let’s take a look at how SpringBoot’s auto-configuration achieves these benefits; Let’s start with an autoconfiguration class, because every configuration class is implemented this way, so let’s just pick one of the configuration classes;

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
Copy the code

Let’s look for the most familiar configuration of DispatcherServle for web projects. If you are familiar with the springMVC framework and have developed with it, you should be familiar with DispatcherServlet. Let’s take a look at how SpringBoot does this for us;

First find this class;

/ * * * {@link EnableAutoConfiguration Auto-configuration} for the Spring
 * {@link DispatcherServlet}. Should work for a standalone application where an embedded
 * web server is already present and also for a deployable application using
 * {@link SpringBootServletInitializer}.
 *
 * @author Phillip Webb
 * @author Dave Syer
 * @author Stephane Nicoll
 * @author Brian Clozel
 */
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
@EnableConfigurationProperties(ServerProperties.class)
public class DispatcherServletAutoConfiguration {

	/* * The bean name for a DispatcherServlet that will be mapped to the root URL "/" */
	public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";

	/* * The bean name for a ServletRegistrationBean for the DispatcherServlet "/" */
	public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";

	@Configuration
	@Conditional(DefaultDispatcherServletCondition.class)
	@ConditionalOnClass(ServletRegistration.class)
	@EnableConfigurationProperties(WebMvcProperties.class)
	protected static class DispatcherServletConfiguration {

		private final WebMvcProperties webMvcProperties;

		private final ServerProperties serverProperties;

		public DispatcherServletConfiguration(WebMvcProperties webMvcProperties, ServerProperties serverProperties) {
			this.webMvcProperties = webMvcProperties;
			this.serverProperties = serverProperties;
		}

		@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
		public DispatcherServlet dispatcherServlet(a) {
			DispatcherServlet dispatcherServlet = new DispatcherServlet();
			dispatcherServlet.setDispatchOptionsRequest(
					this.webMvcProperties.isDispatchOptionsRequest());
			dispatcherServlet.setDispatchTraceRequest(
					this.webMvcProperties.isDispatchTraceRequest());
			dispatcherServlet.setThrowExceptionIfNoHandlerFound(
					this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
			return dispatcherServlet;
		}

		@Bean
		@ConditionalOnBean(MultipartResolver.class)
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}

		@Bean
		public DispatcherServletPathProvider mainDispatcherServletPathProvider(a) {
			return () -> DispatcherServletConfiguration.this.serverProperties.getServlet() .getPath(); }}Copy the code

Extracts, all extracts take up too much space; We can see that the auto-configuration class has a bunch of annotations on it; Take a look at what works:

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)

@Configuration

@ConditionalOnWebApplication(type=Type.SERVLET)

@ConditionalOnClass(DispatcherServlet.class)

@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)

@EnableConfigurationProperties(ServerProperties.class)

AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @autoconfigureOrder (Ordered.HIGHEST_PRECEDENCE) If the precedence is smaller, the precedence is higher. If the precedence is higher, the precedence is precedence.

     /** * Useful constant for the highest precedence value@see java.lang.Integer#MIN_VALUE
	 */
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
Copy the code

That is, if we have the same configuration, whose value is smaller has higher priority,

The second annotation @Configuration, which we should be pretty clear about, indicates that this is a Configuration class, just like the Configuration files we wrote before, that can add components to the container;

The third annotation @ ConditionalOnWebApplication Spring bottom @ Conditional comments, according to different conditions, if meet the specified conditions, the entire configuration configuration will take effect in a class; Check whether the current application is a Web application. If yes, the current configuration takes effect

ConditionalOnClass (” dispatcherServle. class “, “ConditionalOnClass”, “ConditionalOnClass”, “ConditionalOnClass”)

Fifth annotation: @AutoConfigureAfter defines the loading order of these configuration classes.

* key sixth comments: @ EnableConfigurationProperties start specified class ConfigurationProperties function; Bind the corresponding values in the configuration file to ServerProperties; Add ServerProperties to the IOC container;

What does that mean? We can according to need to see how EnableConfigurationProperties, configuration attributes of a class is ServerProperties, here is some of the services we configuration information configuration; Ports, addresses, things like that;

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

	/** * Server HTTP port. */
	private Integer port;

	/** * Network address to which the server should bind. */
	private InetAddress address;

	@NestedConfigurationProperty
	private final ErrorProperties error = new ErrorProperties();

	/** * Whether X-Forwarded-* headers should be applied to the HttpRequest. */
	private Boolean useForwardHeaders;

	/** * Value to use for the Server response header (if empty, no header is sent). */
	private String serverHeader;

	/** * Maximum size, in bytes, of the HTTP message header. */
	private int maxHttpHeaderSize = 0; // bytes

	/** * Time that connectors wait for another HTTP request before closing the connection. * When not set, the connector's container-specific default is used. Use a value of -1 * to indicate no (that is, an infinite) timeout. */
	private Duration connectionTimeout;
Copy the code

I’ve captured the department, and you can see that this is exactly the method that we did that little test, how to read the parameter values in the configuration file, using the @ConfigurationProperties annotation, and you can see the property names in this class, which are the specific properties that we configured;

Taken while we are ahead of us DispatcherServlet configuration related DispatcherServletAutoConfiguration automatic configuration, the configuration of MVC where we can see the specific method; Pick any one of them, method implementation configuration, take the MVC configuration of the Web; I’ve copied this code before, so let’s pull it out for clarity;

@Configuration
	@Conditional(DefaultDispatcherServletCondition.class)
	@ConditionalOnClass(ServletRegistration.class)
	@EnableConfigurationProperties(WebMvcProperties.class)
	protected static class DispatcherServletConfiguration {

		private final WebMvcProperties webMvcProperties;

		private final ServerProperties serverProperties;

		public DispatcherServletConfiguration(WebMvcProperties webMvcProperties, ServerProperties serverProperties) {
			this.webMvcProperties = webMvcProperties;
			this.serverProperties = serverProperties;
		}

		@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
		public DispatcherServlet dispatcherServlet(a) {
			DispatcherServlet dispatcherServlet = new DispatcherServlet();
			dispatcherServlet.setDispatchOptionsRequest(
					this.webMvcProperties.isDispatchOptionsRequest());
			dispatcherServlet.setDispatchTraceRequest(
					this.webMvcProperties.isDispatchTraceRequest());
			dispatcherServlet.setThrowExceptionIfNoHandlerFound(
					this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
			return dispatcherServlet;
		}

		@Bean
		@ConditionalOnBean(MultipartResolver.class)
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}

		@Bean
		public DispatcherServletPathProvider mainDispatcherServletPathProvider(a) {
			return () -> DispatcherServletConfiguration.this.serverProperties.getServlet() .getPath(); }}Copy the code

Have a look at this class configuration file @ EnableConfigurationProperties (WebMvcProperties. Class), WebMvcProperties. Class; Specific attributes in a class;

@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {


public static class Servlet {

		/** * Load on startup priority of the dispatcher servlet. */
		private int loadOnStartup = -1;

		public int getLoadOnStartup(a) {
			return this.loadOnStartup;
		}

		public void setLoadOnStartup(int loadOnStartup) {
			this.loadOnStartup = loadOnStartup; }}public static class View {

		/** * Spring MVC view prefix. */
		private String prefix;

		/** * Spring MVC view suffix. */
		private String suffix;

		public String getPrefix(a) {
			return this.prefix;
		}

		public void setPrefix(String prefix) {
			this.prefix = prefix;
		}

		public String getSuffix(a) {
			return this.suffix;
		}

		public void setSuffix(String suffix) {
			this.suffix = suffix; }}Copy the code

Only part of it was taken; See that all of these configurations that we used before have properties here; He reads the property values in the configuration file through spring.mvc in the ConfigurationProperties annotation, so we can use Spring.mvc directly in the configuration file. Attribute = value to assign configuration file attributes;

Conclusion:

1) SpringBoot launches load a large number of automatic configuration classes

2) We need to see if the function we need is automatic configuration class written by SpringBoot default;

3) Let’s look at what components are configured in this auto-configuration class. (As long as the component we want to use is available, we don’t need to configure it.)

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

XxxxAutoConfigurartion: automatic configuration class; Add components to the container

XxxxProperties: Encapsulates the related properties in the configuration file;

SpringBoot’s automatic configuration greatly simplifies our configuration process and allows us to focus on business development.