这个注解其实是下面三个注解的缩写:
它用于标记main方法所在的类:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
} 复制代码
这个注解开启全局的自动配置,标上这个注解后,Spring Boot会处理jar包下面的META-INF/spring.factories文件,这个文件中的内容可能如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration 复制代码
可以看出,这个文件中指定了哪些配置类应该被自动加载。
这个注解与@Configuration注解的作用是一样的,它用于把一个类标记为Spring Boot的配置类。
如果我们不想使用@EnableAutoConfiguration启用全局的自动配置,有时候我们只想使用其中的一部分配置,那么使用注解@ImportAutoConfiguration可以导入给定的配置类:
@ComponentScan("path.to.your.controllers") @ImportAutoConfiguration({WebMvcAutoConfiguration.class
,DispatcherServletAutoConfiguration.class
,EmbeddedServletContainerAutoConfiguration.class
,ServerPropertiesAutoConfiguration.class
,HttpMessageConvertersAutoConfiguration.class}) public class App { public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
} 复制代码
如果我们的配置需要依赖其它的配置,那么可以使用下面三个注解用于指定配置的加载顺序:
示例:使用@AutoConfigureAfter
@Configuration @AutoConfigureAfter(CacheAutoConfiguration.class) @ConditionalOnBean(CacheManager.class) @ConditionalOnClass(CacheStatisticsProvider.class) public class RedissonCacheStatisticsAutoConfiguration { @Bean public RedissonCacheStatisticsProvider redissonCacheStatisticsProvider(){ return new RedissonCacheStatisticsProvider();
}
} 复制代码
在上面的代码中,只有在CacheAutoConfiguration加载完成后才会加载RedissonCacheStatisticsAutoConfiguration。
Spring Boot的自动配置功能主要通过加载被@Configuration注解的配置类来实现。为了提供更高的扩展性,因此Spring Boot中提供了一系列的@Conditional注解用于约束配置的加载时机。
它们可以接受一个Bean的名称或者Class作为参数。
示例:使用@ConditionalOnMissingBean
@Configuration public class MyAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService() { ... }
} 复制代码
在上面的代码中,当Spring容器中不存在MyService类型的Bean时才会将其注入。
它们可以接受一个Class或者字符串类型的类路径作为参数。
示例:使用@ConditionalOnClass
@Configuration // Some conditions public class MyAutoConfiguration { // Auto-configured beans @Configuration @ConditionalOnClass(EmbeddedAcmeService.class) static class EmbeddedConfiguration { @Bean @ConditionalOnMissingBean public EmbeddedAcmeService embeddedAcmeService() { ... }
}
} 复制代码
在上面的代码中,只有当类EmbeddedAcmeService存在,而且它在Spring容器中不存在时才会加载它。
需要注意的是,由于Spring使用ASM进行动态加载,所以就算这两个注解指定了一个在程序运行时不存在的类型它们也能正常工作。
但是,在下面三个条件同时出现时,JVM将会抛出一个ClassNotFoundException异常:
Spring Boot认定一个应用是Web应用,需要下面三个条件中至少有一个成立:
注解@ConditionalOnProperty可以检测Spring环境变量的值,只有条件成立时才会加载配置。
示例:使用@ConditionalOnProperty
@Configuration public class DataSourceConfiguration { @Bean @ConditionalOnProperty(name = "env", havingValue = "local") DataSource localDataSource() { // ... } @Bean @ConditionalOnProperty(name = "env", havingValue = "prod") DataSource prodDataSource() { // ... }
} 复制代码
上面这段代码演示了DataSource的动态加载,它会通过检测application.properties文件中env选项的值动态加载一个DataSource到Spring容器中。
注解@ConditionalOnResource可以根据所指定的资源是否存在来加载相应配置。
示例:使用@ConditionalOnResource
@Configuration public class VendorConfiguration { @ConditionalOnResource(resources = "classpath:vendor.properties") Properties additionalProperties() { // 对vendor.properties进行一些处理 // ... }
} 复制代码
在上面的代码中只有当文件classpath:vendor.properties存在时才会对它进行处理。
注解@ConditionalOnExpression可以检测SpEL表达式的结果,只有表达式的值为真时才会加载相应配置。
示例:使用@ConditionalOnExpression替换@ConditionalOnProperty
@Configuration public class DataSourceConfiguration { @Bean @ConditionalOnExpression("${env} && ${havingValue == 'local'}") DataSource localDataSource() { // ... } @Bean @ConditionalOnExpression("${env} && ${havingValue == 'prod'}") DataSource prodDataSource() { // ... }
} 复制代码
上面这段代码使用@ConditionalOnExpression替换了@ConditionalOnProperty,这样也能实现DataSource的动态加载。
注解@ConditionalOnCloudPlatform能够检测承载Spring Boot应用的云平台,当应用运行在所指定的云平台上面时才会加载对应的配置,这个注解支持下面这些常用的云平台:
示例:使用@ConditionalOnCloudPlatform
@Configuration @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) public class CloudConfigurationExample { @Bean public MyBean myBean(MyProperties properties) { return new MyBean(properties.getParam);
}
} 复制代码
在上面的代码中,只有当我们的Spring Boot程序运行在K8S平台上面时才会加载MyBean到Spring容器中。
另外,枚举CloudPlatform中存在四个枚举值:
参考资料: