SpringBoot自动配置原理、实战
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>,ClassLoader)
publicstaticList<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 =newArrayList<String>();
while(urls.hasMoreElements()){
URL url = urls.nextElement();
Properties properties =PropertiesLoaderUtils.loadProperties(newUrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch(IOException ex){
thrownewIllegalArgumentException("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.
*/
publicstaticfinalString 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})
publicclassDataSourceAutoConfiguration{
...
@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
自动配置实战
所以,了解了自动配置的原理,来自己实现一个自动配置的玩意其实很简单。
添加配置类:
import org.slf4j.Logger;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import com.oceanpayment.common.utils.logger.LoggerUtils;
publicclassEnvConfigimplementsEnvironmentAware{
privatefinalLogger logger =LoggerUtils.getLogger(this);
privateEnvironment env;
publicString getStringValue(String key){
return env.getProperty(key);
}
publicLong getLongValue(String key){
String value = getStringValue(key);
try{
returnLong.parseLong(value);
}catch(Exception e){
logger.error("字符串转换Long失败:{} = {}", key, value);
}
return0L;
}
publicint getIntValue(String key){
return getLongValue(key).intValue();
}
@Override
publicvoid 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)
publicclassEnvAutoConfig{
@Bean
publicEnvConfig envConfig(){
returnnewEnvConfig();
}
}
创建META-INF/spring.factories文件,添加自动配置映射:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.oceanpayment.common.config.env.EnvAutoConfig
这样就搞定了。
查看自动配置报告
怎么查看自己加的自动配置类有没有被加载,或者查看所有自动配置激活的和未激活的可以通过以下几种试查看。
spring-boot:run运行的在对话框Enviroment中加入debug=true变量
java -jar xx.jar --debug
main方法运行,在VM Argumanets加入-Ddebug
直接在application文件中加入debug=true
如果集成了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:
Didnot match:
-@ConditionalOnClass did not find required classes "javax.jms.ConnectionFactory","org.apache.activemq.ActiveMQConnectionFactory"(OnClassCondition)
AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
Didnot match:
-@ConditionalOnProperty(spring.aop.proxy-target-class=false) found different value inproperty"proxy-target-class"(OnPropertyCondition)
ArtemisAutoConfiguration:
Didnot match:
-@ConditionalOnClass did not find required classes "javax.jms.ConnectionFactory","org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory"(OnClassCondition)
BatchAutoConfiguration:
Didnot match:
-@ConditionalOnClass did not find required class"org.springframework.batch.core.launch.JobLauncher"(OnClassCondition)
...
Positive matches:已经启用的自动配置
Negative matches:未启用的自动配置
从报告中看到自己添加的EnvAutoConfig已经自动配置了。
以上是 SpringBoot自动配置原理、实战 的全部内容, 来源链接: utcz.com/z/515920.html