springboot在可能让我们的配置减到最少,尝试猜测和配置您能需要的bean。根据类路径和定义的bean来应用自动配置类。在我们工程中需要添加功能而引入某些jar包时,比如我们需要配置缓存,数据库,定时任务。这通常需要我们额外的配置,spring boot 通过自动配置这一机制将需要的bean注入到spring的IOC容器中, 这减少了我们的配置。而我们在开发过程中也可以随时覆盖这些自动配置的bean。也可以通过spring.autoconfigure.exclude,注解exclude排除指定的自动配置bean。
spring boot 注册自动配置类通过\META-INF\spring.factories,注册时会根据@ConditionalOnxxx 注解的条件判断是否注册到spring 容器。
# 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.context.ConfigurationPropertiesAutoConfiguration,\
下面拿一个jackson的自动配置类来说
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {
private static final Map<?, Boolean> FEATURE_DEFAULTS;
static {
Map<Object, Boolean> featureDefaults = new HashMap<>();
featureDefaults.put(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
featureDefaults.put(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
FEATURE_DEFAULTS = Collections.unmodifiableMap(featureDefaults);
}
@Bean
public JsonComponentModule jsonComponentModule() {
return new JsonComponentModule();
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperConfiguration {
@Bean
@Primary
@ConditionalOnMissingBean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false).build();
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ParameterNamesModule.class)
static class ParameterNamesModuleConfiguration {
@Bean
@ConditionalOnMissingBean
ParameterNamesModule parameterNamesModule() {
return new ParameterNamesModule(JsonCreator.Mode.DEFAULT);
}
}
在上面的示例中,如果ApplicationContext中不包含ObjectMapper类型的bean,它将创建ObjectMapper bean。另一个注释@ConditionalOnBean与@ConditionalOnMissingBean注释相反。该条件只能匹配到目前为止应用程序上下文已处理的bean。
设置自定义自动配置
定义自动配置类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DataSource.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyService(true);
}
}
...
---------------------------------------
@Data
public class MyService {
boolean autoConfig;
public MyService(boolean autoConfig) {
this.autoConfig=autoConfig;
}
}
在resources\META-INF下创建spring.factories 文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.springboot.config.MyAutoConfiguration
创建测试类,测试成功证明MyService成功注册在容器当中。
public class AutoConfigurationTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class));
@Test
public void serviceNameCanBeConfigured() {
this.contextRunner.withUserConfiguration(MyAutoConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(MyService.class);
assertThat(context.getBean(MyService.class).isAutoConfig()).isTrue();
});
}
}
如果我们将日志配置为logging.level.org.springframework=DEBUG或者使用了spring-boot-starter-actuator ,在启动spring应用时将看到自动配置的类,如下:
分享到: