Spring Boot自动配置原理、实战 - Java技术栈


Spring Boot自动配置原理

Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射。

  1. org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)
  2. public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
  3. String factoryClassName = factoryClass.getName();
  4. try {
  5. Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
  6. lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
  7. List<String> result = new ArrayList<String>();
  8. while (urls.hasMoreElements()) {
  9. URL url = urls.nextElement();
  10. Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
  11. String factoryClassNames = properties.getProperty(factoryClassName);
  12. result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
  13. }
  14. return result;
  15. }
  16. catch (IOException ex) {
  17. throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
  18. "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
  19. }
  20. }

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

  1. /**
  2. * The location to look for factories.
  3. * <p>Can be present in multiple JAR files.
  4. */
  5. 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文件会找到自动配置的映射。

  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. public class DataSourceAutoConfiguration {
  6. ...

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

自动配置实战

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

添加配置类:

  1. import org.slf4j.Logger;
  2. import org.springframework.context.EnvironmentAware;
  3. import org.springframework.core.env.Environment;
  4. import com.oceanpayment.common.utils.logger.LoggerUtils;
  5. public class EnvConfig implements EnvironmentAware {
  6. private final Logger logger = LoggerUtils.getLogger(this);
  7. private Environment env;
  8. public String getStringValue(String key) {
  9. return env.getProperty(key);
  10. }
  11. public Long getLongValue(String key) {
  12. String value = getStringValue(key);
  13. try {
  14. return Long.parseLong(value);
  15. } catch (Exception e) {
  16. logger.error("字符串转换Long失败:{} = {}", key, value);
  17. }
  18. return 0L;
  19. }
  20. public int getIntValue(String key) {
  21. return getLongValue(key).intValue();
  22. }
  23. @Override
  24. public void setEnvironment(Environment environment) {
  25. this.env = environment;
  26. }
  27. }

添加自动配置类:

  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. @Configuration
  6. @ConditionalOnClass(PropertyResolver.class)
  7. public class EnvAutoConfig {
  8. @Bean
  9. public EnvConfig envConfig() {
  10. return new EnvConfig();
  11. }
  12. }

创建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. Positive matches:
  5. -----------------
  6. AopAutoConfiguration matched:
  7. - @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)
  8. - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
  9. ...
  10. EnvAutoConfig matched:
  11. - @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
  12. ErrorMvcAutoConfiguration matched:
  13. - @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
  14. - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
  15. ErrorMvcAutoConfiguration#basicErrorController matched:
  16. - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)
  17. ...
  18. Negative matches:
  19. -----------------
  20. ActiveMQAutoConfiguration:
  21. Did not match:
  22. - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
  23. AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
  24. Did not match:
  25. - @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)
  26. ArtemisAutoConfiguration:
  27. Did not match:
  28. - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)
  29. BatchAutoConfiguration:
  30. Did not match:
  31. - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
  32. ...

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

Negative matches:未启用的自动配置

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

看完是否收获良多?

分享到朋友圈给更多的人吧。

    • *


原网址: 访问
创建于: 2019-03-24 04:00:46
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论