SpringBoot自动配置原理、实战

编程

 

  1. org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>,ClassLoader)

 

  1. publicstaticList<String> loadFactoryNames(Class<?> factoryClass,ClassLoader classLoader){

  2.    String factoryClassName = factoryClass.getName();

  3.    try{

  4.        Enumeration<URL> urls =(classLoader !=null? classLoader.getResources(FACTORIES_RESOURCE_LOCATION):

  5.                lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

  6.        List<String> result =newArrayList<String>();

  7.        while(urls.hasMoreElements()){

  8.            URL url = urls.nextElement();

  9.            Properties properties =PropertiesLoaderUtils.loadProperties(newUrlResource(url));

  10.            String factoryClassNames = properties.getProperty(factoryClassName);

  11.            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

  12.        }

  13.        return result;

  14.    }

  15.    catch(IOException ex){

  16.        thrownewIllegalArgumentException("Unable to load ["+ factoryClass.getName()+

  17.                "] factories from location ["+ FACTORIES_RESOURCE_LOCATION +"]", ex);

  18.    }

  19. }

这个方法会加载类路径及所有jar包下META-INF/spring.factories配置中映射的自动配置的类。

 

  1. /**

  2. * The location to look for factories.

  3. * <p>Can be present in multiple JAR files.

  4. */

  5. publicstaticfinalString FACTORIES_RESOURCE_LOCATION ="META-INF/spring.factories";

查看Spring Boot自带的自动配置的包: spring-boot-autoconfigure-1.5.6.RELEASE.jar,打开其中的META-INF/spring.factories文件会找到自动配置的映射。

 

  1. # Auto Configure

  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=

  3. org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,

  4. org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,

  5. org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,

  6. org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,

  7. org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,

  8. org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,

  9. org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,

  10. ...

再来看看数据源自动配置的实现注解

 

  1. @Configuration

  2. @ConditionalOnClass({DataSource.class,EmbeddedDatabaseType.class})

  3. @EnableConfigurationProperties(DataSourceProperties.class)

  4. @Import({Registrar.class,DataSourcePoolMetadataProvidersConfiguration.class})

  5. publicclassDataSourceAutoConfiguration{

  6. ...

@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。

自动配置实战

所以,了解了自动配置的原理,来自己实现一个自动配置的玩意其实很简单。

添加配置类:

 

  1. import org.slf4j.Logger;

  2. import org.springframework.context.EnvironmentAware;

  3. import org.springframework.core.env.Environment;

  4.  

  5. import com.oceanpayment.common.utils.logger.LoggerUtils;

  6.  

  7. publicclassEnvConfigimplementsEnvironmentAware{

  8.  

  9.    privatefinalLogger logger =LoggerUtils.getLogger(this);

  10.  

  11.    privateEnvironment env;

  12.  

  13.    publicString getStringValue(String key){

  14.        return env.getProperty(key);

  15.    }

  16.  

  17.    publicLong getLongValue(String key){

  18.        String value = getStringValue(key);

  19.        try{

  20.            returnLong.parseLong(value);

  21.        }catch(Exception e){

  22.            logger.error("字符串转换Long失败:{} = {}", key, value);

  23.        }

  24.        return0L;

  25.    }

  26.  

  27.    publicint getIntValue(String key){

  28.        return getLongValue(key).intValue();

  29.    }

  30.  

  31.    @Override

  32.    publicvoid setEnvironment(Environment environment){

  33.        this.env = environment;

  34.    }

  35.  

  36. }

添加自动配置类:

 

  1. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

  2. import org.springframework.context.annotation.Bean;

  3. import org.springframework.context.annotation.Configuration;

  4. import org.springframework.core.env.PropertyResolver;

  5.  

  6. @Configuration

  7. @ConditionalOnClass(PropertyResolver.class)

  8. publicclassEnvAutoConfig{

  9.  

  10.    @Bean

  11.    publicEnvConfig envConfig(){

  12.        returnnewEnvConfig();

  13.    }

  14.  

  15. }

创建META-INF/spring.factories文件,添加自动配置映射:

 

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

  2. 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端点也可以查看。

启动后会在控制台看到以下自动配置报告信息:

 

  1. =========================

  2. AUTO-CONFIGURATION REPORT

  3. =========================

  4.  

  5.  

  6. Positive matches:

  7. -----------------

  8.  

  9.   AopAutoConfiguration matched:

  10.      -@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)

  11.      -@ConditionalOnProperty(spring.aop.auto=true) matched (OnPropertyCondition)

  12.  

  13.   ...

  14.  

  15.   EnvAutoConfig matched:

  16.      -@ConditionalOnClass found required class"org.springframework.core.env.PropertyResolver";@ConditionalOnMissingClass did not find unwanted class(OnClassCondition)

  17.  

  18.   ErrorMvcAutoConfiguration matched:

  19.      -@ConditionalOnClass found required classes "javax.servlet.Servlet","org.springframework.web.servlet.DispatcherServlet";@ConditionalOnMissingClass did not find unwanted class(OnClassCondition)

  20.      -@ConditionalOnWebApplication(required) found StandardServletEnvironment(OnWebApplicationCondition)

  21.  

  22.   ErrorMvcAutoConfiguration#basicErrorController matched:

  23.      -@ConditionalOnMissingBean(types: org.springframework.boot.autoconfigure.web.ErrorController;SearchStrategy: current) did not find any beans (OnBeanCondition)

  24.  

  25.   ...

  26.  

  27.  

  28. Negative matches:

  29. -----------------

  30.  

  31.   ActiveMQAutoConfiguration:

  32.      Didnot match:

  33.         -@ConditionalOnClass did not find required classes "javax.jms.ConnectionFactory","org.apache.activemq.ActiveMQConnectionFactory"(OnClassCondition)

  34.  

  35.   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:

  36.      Didnot match:

  37.         -@ConditionalOnProperty(spring.aop.proxy-target-class=false) found different value inproperty"proxy-target-class"(OnPropertyCondition)

  38.  

  39.   ArtemisAutoConfiguration:

  40.      Didnot match:

  41.         -@ConditionalOnClass did not find required classes "javax.jms.ConnectionFactory","org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory"(OnClassCondition)

  42.  

  43.   BatchAutoConfiguration:

  44.      Didnot match:

  45.         -@ConditionalOnClass did not find required class"org.springframework.batch.core.launch.JobLauncher"(OnClassCondition)

  46.  

  47.   ...

Positive matches:已经启用的自动配置

Negative matches:未启用的自动配置

从报告中看到自己添加的EnvAutoConfig已经自动配置了。

以上是 SpringBoot自动配置原理、实战 的全部内容, 来源链接: utcz.com/z/515920.html

回到顶部