Spring Boot自动配置

本文详细解析了 Spring Boot 的自动配置原理,包括如何通过 @EnableAutoConfiguration 注解触发自动配置,以及自动配置类是如何被加载和匹配的。此外,还介绍了如何自定义自动配置类并将其添加到 spring.factories 文件中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      1. Spring Boot自动配置原理

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

  1. org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)
  1. public static List<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 = new ArrayList<String>();
  7.         while (urls.hasMoreElements()) {
  8.             URL url = urls.nextElement();
  9.             Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(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.        throw new IllegalArgumentException("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. 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. 自动配置实战

添加配置类:

  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. public class EnvConfig implements EnvironmentAware {
  8.  
  9.     private final Logger logger = LoggerUtils.getLogger(this);
  10.  
  11.    private Environment env;
  12.  
  13.    public String getStringValue(String key) {
  14.        return env.getProperty(key);
  15.    }
  16.  
  17.    public Long getLongValue(String key) {
  18.        String value = getStringValue(key);
  19.        try {
  20.            return Long.parseLong(value);
  21.        } catch (Exception e) {
  22.            logger.error("字符串转换Long失败:{} = {}", key, value);
  23.        }
  24.        return 0L;
  25.    }
  26.  
  27.    public int getIntValue(String key) {
  28.        return getLongValue(key).intValue();
  29.    }
  30.  
  31.    @Override
  32.    public void 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. public class EnvAutoConfig {
  9.  
  10.    @Bean
  11.    public EnvConfig envConfig() {
  12.        return new EnvConfig();
  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变量 
  • java -jar xx.jar --debug
  • main方法运行,在VM Argumanets加入-Ddebug
  • 直接在application文件中加入debug=true

如果集成了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.      Did not match:
  33.         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
  34.  
  35.   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
  36.      Did not match:
  37.         - @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)
  38.  
  39.   ArtemisAutoConfiguration:
  40.      Did not match:
  41.         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)
  42.  
  43.   BatchAutoConfiguration:
  44.      Did not match:
  45.         - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
  46.  
  47.   ...

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

Negative matches:未启用的自动配置

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

 

      1. Auto-configuration

Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, if HSQLDB is on your classpath, and you have not manually configured any database connection beans, then Spring Boot auto-configures an in-memory database.

You need to opt-in to auto-configuration by adding the @EnableAutoConfiguration or @SpringBootApplication annotations to one of your @Configuration classes.

 

You should only ever add one @SpringBootApplication or @EnableAutoConfiguration annotation. We generally recommend that you add one or the other to your primary @Configuration class only.

 

16.1 Gradually Replacing Auto-configuration

Auto-configuration is non-invasive. At any point, you can start to define your own configuration to replace specific parts of the auto-configuration. For example, if you add your own DataSource bean, the default embedded database support backs away.

If you need to find out what auto-configuration is currently being applied, and why, start your application with the --debug switch. Doing so enables debug logs for a selection of core loggers and logs a conditions report to the console.

16.2 Disabling Specific Auto-configuration Classes

If you find that specific auto-configuration classes that you do not want are being applied, you can use the exclude attribute of @EnableAutoConfiguration to disable them, as shown in the following example:

import org.springframework.boot.autoconfigure.*;

import org.springframework.boot.autoconfigure.jdbc.*;

import org.springframework.context.annotation.*;

 

@Configuration

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

public class MyConfiguration {

}

If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead. Finally, you can also control the list of auto-configuration classes to exclude by using the spring.autoconfigure.exclude property.

 

You can define exclusions both at the annotation level and by using the property.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值