1、概述
Spring Boot自动配置的特性使得Spring在配置上很简约。本文中,我们将围绕Spring中两个核心包org.springframework.boot.autoconfigure以及org.springframework.boot.autoconfigure.condition包中的注解展开介绍。
2、@SpringBootApplication
@SpringBootApplication是Spring Boot项目接触到的第一个注解,用与标识应用的启动主类。
@SpringBootApplication class SpringBootAnnotations { public static void main(String[] args) { SpringApplication.run(SpringBootAnnotations.class, args); } }
从根本上讲@SpringBootApplication其实是@Configuration,@EnableAutoConfiguration和@ComponentScan三个注解的缩写,也可以认为@SpringBootApplication封装了上述三个注解。稍有些不同的是,@SpringBootApplication在封装@ComponentScan注解时,加入了一些默认的属性:
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@ComponentScan.Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @ComponentScan.Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} )
也就是说在 Spring Boot项目中,完全可以使用上述注解代码段来代替@SpringBootApplication。当然了,实际的项目中肯定没有人这么做,试想谁又会舍近求远放着方便的不用,非要把简单的事情复杂化呢。
下面,让我们深入的了解一下Spring Boot的核心注解。
3、@EnableAutoConfiguration
@EnableAutoConfiguration的英文原意是:启用自动配置。该注解使得Spring Boot可以根据环境来自动检测并对项目进行一些自动化设置。比如当我们在pom.xml中同时引入Spring Data JPA以及H2数据库时,@EnableAutoConfiguration则会将Spring Data JPA的数据源自动的配置为H2。
需要注意的是该注解必须与@Configuration一起使用:
@Configuration @EnableAutoConfiguration class SpringBootAnnotationsConfig {}
4、条件注入(配置)
通常情况下,我们需要针对不同的环境(条件)来启用不同的配置,这一般被称为条件注入,可以借助本节中的条件注解来实现。
我们可以在使用@Configuration注解的类或使用@Bean注解的方法上放置条件注解,从而达到在特定的情况下使用特定的类或特定的方法的目的。在此,本文仅对其基本的使用方法进行介绍,预了解更多有关于本方面的知识,请访问此文。
4.1. @ConditionalOnClass 以及@ConditionalOnMissingClass注解
@ConditionalOnClass表示:当某些类存在时,启用当前的配置;相反@ConditionalOnMissingClass表示:当某些类不存在时,启用当前配置。
@Configuration @ConditionalOnClass(DataSource.class) class MySQLAutoconfiguration { public MySQLAutoconfiguration() { System.out.println("DataSource.class存在")} }
以下代码实现了:当DataSource.class存在时,Spring将使用该bean。
@Configuration @ConditionalOnMissingClass("club.codedemo.springbootannotations.DataSource") public class MySQLAutoconfiguration { public MySQLAutoconfiguration() { System.out.println("DataSource.class不存在“); } }
以上代码实现了:当DataSource.class不存在时,Spring将使用该bean
4.2. @ConditionalOnBean以及@ConditionalOnMissingBean注解
除了可以基于类存在与否进行条件注入以外,还可以根据Bean是否存在来进行条件注入:
@Bean @ConditionalOnBean(name = "dataSource") LocalContainerEntityManagerFactoryBean entityManagerFactory() { // ... }
以上代码实现了:当名称为dataSource的bean存在时,注入本方法返回的Bean。
@Bean @ConditionalOnMissingBean(name = "dataSource") LocalContainerEntityManagerFactoryBean entityManagerFactory() { // ... }
以上代码实现了:当名称为dataSource的bean不存在时,注入本方法返回的Bean。
具体的验证代码请参阅本文提供的code demo。
4.3. @ConditionalOnProperty
使用@ConditionalOnProperty可以实现依据项目的属性值来进行注入。
@Bean @ConditionalOnProperty( name = "usemysql", havingValue = "local" ) DataSource dataSource() { // ... }
以上代码实现了:只有在项目的配置信息满足usemysql值为local时,注入该Bean。
4.4. @ConditionalOnResource
除根据项目的属性进行条件注入外,还可以根据项目资源文件夹中是否存在某配置文件来进行注入:
@Bean //资源文件夹中存在mysql.properties文件时,该Bean生效 @ConditionalOnResource(resources = "classpath:mysql.properties") Properties additionalProperties() { // ... }
4.5.@ConditionalOnWebApplication以及@ConditionalOnNotWebApplication注解
@ConditionalOnWebApplication以及@ConditionalOnNotWebApplication注解可以基于当前应用程序是否为Web应用程序来进行配置。
@Bean @ConditionalOnWebApplication HealthCheckController healthCheckController() { // ... }
如果当前应用属于Web应用,则上述Bean生效。
4.6. @ConditionalExpression
处理些稍复杂的注入需求,还可以使用@ConditionalExpression结合SpEL表达式来完成:
@Bean @ConditionalOnExpression(${usemysql} && ${mysqlserver == 'local'}) DataSource dataSource() { // ... }
@ConditionalOnExpression注解接收的是SpEL表达式,当该表达式返回true时,该Bean生效;返回false,不生效。
4.7. @Conditional
对于更复杂的条件,还可以通过@Conditional结合创建自定义类的方式来实现:
@Conditional(CustomCondition.class) Properties additionalProperties() { //... }
5. 结论
本从由SpringBootApplication注解入手,对Spring Boot的条件配置进行了讲解。在实际的使用过程中,还需要根据项目的实际情况选择适合的技术。我们说适用的就是最好的,切不可在实际的项目为了实现技术而实现技术。
本文资源: