Spring Boot自動配置原理、實戰
Spring Boot自動配置原理
Spring Boot的自動配置註解是@EnableAutoConfiguration,
從上面的@Import的類可以找到下面自動載入自動配置的對映。
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader ) {
String factoryClassName = factoryClass.getName();
try {
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
這個方法會載入類路徑及所有jar包下META-INF/spring.factories配置中對映的自動配置的類。
/**
* The location to look for factories.
* <p>Can be present in multiple JAR files.
*/
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
檢視Spring Boot自帶的自動配置的包:
spring-boot-autoconfigure-1.5.6.RELEASE.jar,開啟其中的META-INF/spring.factories檔案會找到自動配置的對映。
# 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,\
...
再來看看資料來源自動配置的實現註解
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
...
@Configuration,@ConditionalOnClass就是自動配置的核心,首先它得是一個配置檔案,其次根據類路徑下是否有這個類去自動配置。
自動配置實戰
所以,瞭解了自動配置的原理,來自己實現一個自動配置的玩意其實很簡單。
新增配置類:
import org.slf4j.Logger;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import com.oceanpayment.common.utils.logger.LoggerUtils;
public class EnvConfig implements EnvironmentAware {
private final Logger logger = LoggerUtils.getLogger(this);
private Environment env;
public String getStringValue(String key) {
return env.getProperty(key);
}
public Long getLongValue(String key) {
String value = getStringValue(key);
try {
return Long.parseLong(value);
} catch (Exception e) {
logger.error("字串轉換Long失敗:{} = {}", key, value);
}
return 0L;
}
public int getIntValue(String key) {
return getLongValue(key).intValue();
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
}
新增自動配置類:
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertyResolver;
@Configuration
@ConditionalOnClass(PropertyResolver.class)
public class EnvAutoConfig {
@Bean
public EnvConfig envConfig() {
return new EnvConfig();
}
}
建立META-INF/spring.factories檔案,新增自動配置對映:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.oceanpayment.common.config.env.EnvAutoConfig
這樣就搞定了。
檢視自動配置報告
怎麼檢視自己加的自動配置類有沒有被載入,或者檢視所有自動配置啟用的和未啟用的可以通過以下幾種試檢視。
1、spring-boot:run執行的在對話方塊Enviroment中加入debug=true變數 \
2、java -jar xx.jar –debug\
3、main方法執行,在VM Argumanets加入-Ddebug\
4、直接在application檔案中加入debug=true\
5、如果集成了spring-boot-starter-actuator監控,通過autoconfig端點也可以檢視。
啟動後會在控制檯看到以下自動配置報告資訊:
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
AopAutoConfiguration matched:
- @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
...
EnvAutoConfig matched:
- @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
ErrorMvcAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
ErrorMvcAutoConfiguration#basicErrorController matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)
...
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
Did not match:
- @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)
ArtemisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)
BatchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
...
Positive matches:已經啟用的自動配置\
Negative matches:未啟用的自動配置
從報告中看到自己新增的EnvAutoConfig已經自動配置了。
推薦閱讀
分享Java乾貨,高併發程式設計,熱門技術教程,微服務及分散式技術,架構設計,區塊鏈技術,人工智慧,大資料,Java面試題,以及前沿熱門資訊等。