注解可以减少xml配置,注释配置相对于 XML 配置具有很多的优势,它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。
1、@SpringBootApplication
这是 Spring Boot 最最最核心的注解,用在 Spring Boot 主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。
其实这个注解就是 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解的组合,也可以用这三个注解来代替 @SpringBootApplication 注解。
springboot中@SpringBootApplication详解_春哥的技术还不行的博客-CSDN博客_springbootapplication
2、@EnableAutoConfiguration
允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。
如:当前类路径下有 Mybatis 这个 JAR 包,MybatisAutoConfiguration 注解就能根据相关参数来配置 Mybatis 的各个 Spring Bean。
4、@SpringBootConfiguration
这个注解就是 @Configuration 注解的变体,只是用来修饰是 Spring Boot 配置而已,或者可利于 Spring Boot 后续的扩展。
6、@Conditional
这是 Spring 4.0 添加的新注解,用来标识一个 Spring Bean 或者 Configuration 配置文件,当满足指定的条件才开启配置。
7、@ConditionalOnBean
组合 @Conditional 注解,当容器中有指定的 Bean 才开启配置。
8、@ConditionalOnMissingBean
组合 @Conditional 注解,和 @ConditionalOnBean 注解相反,当容器中没有指定的 Bean 才开启配置。
9、@ConditionalOnClass
组合 @Conditional 注解,当容器中有指定的 Class 才开启配置。
注解@ConditionalOnClass(X.class),X不存在时的探究:讲的很好,一下就看懂了注解@ConditionalOnClass(X.class),X不存在时的探究_雪落南城的博客-CSDN博客_conditionalonclass
@ConditionalOnClass和@ConditionalOnMissingClass的神秘探索:@ConditionalOnClass和@ConditionalOnMissingClass的神秘探索_a656678879的博客-CSDN博客_conditionalonmissingclass
10、@ConditionalOnMissingClass
组合 @Conditional 注解,和 @ConditionalOnMissingClass 注解相反,当容器中没有指定的 Class 才开启配置。
11、@ConditionalOnWebApplication
组合 @Conditional 注解,当前项目类型是 WEB 项目才开启配置。
当前项目有以下 3 种类型。
enum Type {
/**
* Any web application will match.
*/
ANY,
/**
* Only servlet-based web application will match.
*/
SERVLET,
/**
* Only reactive-based web application will match.
*/
REACTIVE
}
12、@ConditionalOnNotWebApplication
组合 @Conditional 注解,和 @ConditionalOnWebApplication 注解相反,当前项目类型不是 WEB 项目才开启配置。
13、@ConditionalOnProperty
组合 @Conditional 注解,当指定的属性有指定的值时才开启配置。
14、@ConditionalOnExpression
组合 @Conditional 注解,当 SpEL 表达式为 true 时才开启配置。
15、@ConditionalOnJava
组合 @Conditional 注解,当运行的 Java JVM 在指定的版本范围时才开启配置。
16、@ConditionalOnResource
组合 @Conditional 注解,当类路径下有指定的资源才开启配置。
17、@ConditionalOnJndi
组合 @Conditional 注解,当指定的 JNDI 存在时才开启配置。
18、@ConditionalOnCloudPlatform
组合 @Conditional 注解,当指定的云平台激活时才开启配置。
19、@ConditionalOnSingleCandidate
组合 @Conditional 注解,当指定的 class 在容器中只有一个 Bean,或者同时有多个但为首选时才开启配置。
20、@ConfigurationProperties
用来加载额外的配置(如 .properties 文件),可用在 @Configuration 注解类,或者 @Bean 注解方法上面。
关于这个注解的用法可以参考《 Spring Boot读取配置的几种方式》这篇文章。
21、@EnableConfigurationProperties
一般要配合 @ConfigurationProperties 注解使用,用来开启对 @ConfigurationProperties 注解配置 Bean 的支持。
22、@AutoConfigureAfter
用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之后。
如 Mybatis 的自动配置类,需要在数据源自动配置类之后。
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
23、@AutoConfigureBefore
这个和 @AutoConfigureAfter 注解使用相反,表示该自动配置类需要在另外指定的自动配置类配置之前。
24.@ComponentScan
背景
SpringBoot 启动类上,配置扫描包路径有三种方式,最近看到一个应用上三种注解都用上了,代码如下:
@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer
}
那么,疑问来了:SpringBoot 中,这三种注解生效优先级如何、第一种和第二种有没有区别呢?本文来整理下这三个注解的注意事项。
ImportSelector 注解
Spring(32)——ImportSelector介绍_elim168的博客-CSDN博客
SpringBootApplication 注解
这是 SpringBoot 的注解,本质是三个 Spring 注解的和
- @Configuration
- @EnableAutoConfiguration
- @ComponentScan
它默认扫描启动类所在包及其所有子包, 但是不包括第三方的 jar 包的其他目录 ,通过 scanBasePackages
属性可以重新设置扫描包路径。
注意:如果我们需要扫描依赖 jar 包中的注解,而依赖包的路径跟不包含在 SpringBoot 启动类路径中的话,我们就要单独使用 @ComponentScan
注解扫描第三方包。同时必须指定本工程的扫描路径, 因为一旦有这个注解后,它优先,默认扫描包就失效了 。
例如这个工程:
SpringBoot 启动类的工程目录为 cn.com.a.b
,引用的第三方公共包 xxx.common.jar
的目录也是 cn.com.a.b
,那么第三方 jar 包中的注解天然能直接被扫描到。其他的 jar 包中,如果有注解,就无法扫描到了。
ComponentScan注解
这个是 Spring 框架的注解,它用来指定组件扫描路径,如果用这个注解,它的值必须包含整个工程中全部需要扫描的路径。因为它会覆盖 SpringBootApplication
的默认扫描路径,导致其失效。
失效表现有两种:
第一,如果 ComponentScan
只包括一个值且就是默认启动类目录, SpringBootApplication
生效, ComponentScan
注解失效,报错:
第二,如果 ComponentScan
指定多个具体子目录,此时 SpringBootApplication
会失效,Spring 只会扫描 ComponentScan
指定目录下的注解。如果恰好有目录外的 Controller 类,很遗憾,这些控制器将无法访问。
回到开头那段代码:
@SpringBootApplication(scanBasePackages ={})
@ComponentScan(basePackages = {})
这里指定了 ComponentScan
注解后, scanBasePackages
就失效了。因此,如果 ComponentScan
的 basePackages
值不包括 cn.com.a.b
即启动类所在的包,仅指定了第三方 jar 的目录,那么 这个工程下任何的注解都无法被扫描到 。
MapperScan 注解
这个是 MyBatis 的注解,会将指定目录下所有 DAO 类封装成 MyBatis 的 BaseMapper
类,然后注入 Spring 容器中, 不需要额外的注解 ,就可以完成注入。
启示录
SpringBoot 包扫描路径,两个注解的冲突行为,我反复验证了好久确定了现象,但是没有找到合理的解释。这篇文章在草稿箱酝酿了快两周了,一直搁置着。
今天搜到了一篇文章,说二者同时使用时, SpringBootApplication
会失效,至此 SpringBoot 扫描路径的疑惑终于消除了。