4、Spring Boot 自動配置原理
1.4 Spring Boot 自動配置原理
簡介
spring boot自動配置功能可以根據不同情況來決定spring配置應該用哪個,不應該用哪個,舉個例子:
- Spring的JdbcTemplate是不是在Classpath裏面?如果是,並且DataSource也存在,就自動配置一個JdbcTemplate的Bean
- Thymeleaf是不是在Classpath裏面?如果是,則自動配置Thymeleaf的模板解析器、視圖解析器、模板引擎
那個這個是怎麽實現的呢?原因就在於它利用了Spring的條件化配置,條件化配置允許配置存在於應用中,但是在滿足某些特定條件前會忽略這些配置。
要實現條件化配置我們要用到@Conditional條件化註解。
本篇從如下幾個方面進行展開:
- @Conditional註解
- spring boot 的條件化配置詳解
- spring boot 自動配置源碼分析
- 自己動手實現spring boot starter pom
1.4.1 @Conditional 註解
@Conditional是由Spring 4提供的一個新特性,用於根據特定條件來控制Bean的創建行為。
1.4.2 Spring Boot 的條件化配置詳解
在spring boot項目中會存在一個名為spring-boot-autoconfigure的jar包,條件化配置就是在這個jar裏面實現的,它用到了如下的條件化註解,這些註解都是以@ConditionalOn開頭的,他們都是應用了@Conditional的組合註解:
- @ConditionalOnBean ------------------------ 配置了某個特定的Bean
- @ConditionalMissingBean ------------------- 沒有配置特定的Bean
- @ConditionalOnCalss ----------------------- Classpath裏有指定的類
- @ConditionalOnMissingCalss ---------------- Classpath缺少指定的類
- @ConditionalOnExpression ------------------ 給定的Spring Expression Language(SpEL)表達式計算
- @ConditionalOnJava ------------------------ Java的版本匹配特定值或者一個範圍值
- @ConditionalOnProperty -------------------- 指定的配置屬性要有一個明確的值
- @ConditionalOnResource -------------------- ClassPath裏有指定的資源
- @ConditionalOnWebApplication -------------- 這是一個Web應用程序
- @ConditionalOnNotWebApplication ----------- 這不是一個Web應用程序
以JdbcTemplateAutoConfiguration為例,它裏面有這段代碼:
@Bean
@Primary
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(this.dataSource);
}
只有在不存在JdbcOperations(如果查看JdbcTemplate的源碼,你會發現JdbcTemplate類實現了JdbcOperations接口)實例的時候,才會初始化一個JdbcTemplate 的Bean。
1.4.3 Spring Boot 自動配置源碼分析
spring boot項目的啟動類用的註解--@SpringBootApplication是一個組合註解,其中@EnableAutoConfiguration是自動配置相關的。
查看@EnableAutoConfiguration註解源碼(本文基於spring-boot-starter-parent 2.1.0.RELEASE):
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
而這個@EnableAutoConfiguration註解裏面有個@Import註解導入了EnableAutoConfigurationImportSelector用來實現具體的功能。
進入AutoConfigurationImportSelector.java裏面有個方法selectImports()調用了方法getAutoConfigurationEntry(),然後getAutoConfigurationEntry()方法又調用了getCandidateConfigurations(),進而調用了SpringFactoriesLoader.loadFactoryNames()方法
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
/**
* Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
* of the importing {@link Configuration @Configuration} class.
* @param autoConfigurationMetadata the auto-configuration metadata
* @param annotationMetadata the annotation metadata of the configuration class
* @return the auto-configurations that should be imported
*/
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
在SpringFactoriesLoader.loadFactoryNames()方法裏面,會調用loadSpringFactories(),然後查詢META-INF/spring.factories這個配置文件
// 所要查詢的資源文件
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
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()) {
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
SpringFactoriesLoader屬於Spring框架私有的一種擴展方案,其主要功能就是從指定的配置文件META-INF/spring.factories加載配置。
SpringFactoriesLoader.loadFactoryNames方法會掃描具有META-INF/spring.factories文件的jar包,而我們的spring-boot-autoconfigure.jar裏面就有一個這樣的文件,此文件中聲明了具體有哪些自動配置:
# Initializers
org.springframework.context.ApplicationContextInitializer=org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=org.springframework.boot.autoconfigure.condition.OnBeanCondition,org.springframework.boot.autoconfigure.condition.OnClassCondition,org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# 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.CloudServiceConnectorsAutoConfiguration,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.jdbc.JdbcRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,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.elasticsearch.rest.RestClientAutoConfiguration,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.SecurityRequestMatcherProviderAutoConfiguration,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.servlet.OAuth2ClientAutoConfiguration,org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,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.ClientHttpConnectorAutoConfiguration,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,org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer
# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
我們上面提到的JdbcTemplateAutoConfiguration自動配置類就在裏面。
1.4.4 自己動手實現spring boot starter pom
接下來,我們就來寫一個簡單的spring boot starter pom。
- 新建starter maven項目 spring-boot-starter-autoconfigure
- 修改pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hw</groupId>
<artifactId>spring-boot-starter-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-starter-autoconfigure</name>
<description>Demo project for Spring Boot Autoconfigure</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 這裏需要引入spring boot的自動配置作為依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 屬性配置 HelloServiceProperties.java
package com.hw.springbootstarterautoconfigure.conifg;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @Description TODO
* @Author hw
* @Date 2018/11/18 22:57
* @Version 1.0
*/
/**
* @ConfigurationProperties 自動匹配application.properties文件中hello.msg的值,然後賦值給類屬性msg,這裏的msg默認值為“spring boot”
*/
@ConfigurationProperties(prefix = "hello")
public class HelloServiceProperties {
private static final String MSG = "spring boot";
private String msg = MSG;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
- 判定依據類HelloService.java,後面的代碼會依據此類是否存在,來決定是否生產對應的Bean
package com.hw.springbootstarterautoconfigure.conifg;
/**
* @Description TODO
* @Author hw
* @Date 2018/11/18 23:00
* @Version 1.0
*/
public class HelloService {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String sayHello() {
return "hello " + msg;
}
}
- 自動配置類 HelloServiceAutoConfiguration.java,根據HelloServiceProperties提供的參數,並通過@ConditionalOnClass(HelloService.class)判定HelloService這個類在Classpath中是否存在,存在並且還沒有對應的Bean,就生成對應的helloService Bean
package com.hw.springbootstarterautoconfigure.conifg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description TODO
* @Author hw
* @Date 2018/11/18 23:01
* @Version 1.0
*/
@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix = "hello", matchIfMissing = true, value = "enabled")
public class HelloServiceAutoConfiguration {
@Autowired
HelloServiceProperties helloServiceProperties;
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService() {
HelloService service = new HelloService();
service.setMsg(helloServiceProperties.getMsg());
return service;
}
}
- 註冊配置,需要到META-INF/spring.factories文件中註冊改自動配置類:在src/main/source目錄下新建該文件,然後進行配置。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.hw.springbootstarterautoconfigure.conifg.HelloServiceAutoConfiguration
- 實現controller HelloController.java
package com.hw.springbootstarterautoconfigure.web;
import com.hw.springbootstarterautoconfigure.conifg.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description TODO
* @Author hw
* @Date 2018/11/18 23:07
* @Version 1.0
*/
@RestController
public class HelloController {
/**
* 代碼中沒有配置這個helloService Bean,但是自動配置能夠幫忙實例化,因此可以直接註入
*/
@Autowired
HelloService helloService;
@RequestMapping(value = "/helloService")
public String sayHello() {
return helloService.sayHello();
}
}
- 啟動項目 訪問/helloService 接口。 得到 hello spring boot
- 在application.properties裏面配置hello.msg=hw,然後再次訪問/helloService接口。得到 hello hw
- 本文完整代碼:Spring Boot自動配置
4、Spring Boot 自動配置原理