详解SpringBoot启动类的扫描注解的⽤法及冲突原则
背景
SpringBoot 启动类上,配置扫描包路径有三种⽅式,最近看到⼀个应⽤上三种注解都⽤上了,代码如下:
@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer
}
那么,疑问来了:SpringBoot 中,这三种注解⽣效优先级如何、第⼀种和第⼆种有没有区别呢?本⽂来整理下这三个注解的注意事项。
SpringBootApplication 注解
这是 SpringBoot 的注解,本质是三个 Spring 注解的和
@Configuration
@EnableAutoConfiguration
@ComponentScan
它默认扫描启动类所在包及其所有⼦包,但是不包括第三⽅的 jar 包的其他⽬录,通过scanBasePackages属性可以重新设置扫描包路径。
注意:如果我们需要扫描依赖 jar 包中的注解,⽽依赖包的路径跟不包含在 SpringBoot 启动类路径中的话,我们就要单独使⽤@ComponentScan注解扫描第三⽅包。同时必须指定本⼯程的扫描路径,因为⼀旦有这个注解后,它优先,默认扫描包就失效了。
例如这个⼯程:
SpringBoot 启动类的⼯程⽬录为cn.a.b,引⽤的第三⽅公共包xxxmon.jar的⽬录也是cn.a.b,那么第三⽅ jar 包中的注解天然能直接被扫描到。其他的 jar 包中,如果有注解,就⽆法扫描到了。
ComponentScan注解
这个是 Spring 框架的注解,它⽤来指定组件扫描路径,如果⽤这个注解,它的值必须包含整个⼯程中全部需要扫描的路径。因为它会覆盖SpringBootApplication的默认扫描路径,导致其失效。
失效表现有两种:
第⼀,如果ComponentScan只包括⼀个值且就是默认启动类⽬录,SpringBootApplication⽣效,ComponentScan注解失效,报错:
第⼆,如果ComponentScan指定多个具体⼦⽬录,此时SpringBootApplication会失效,Spring 只会扫描ComponentScan指定⽬录下
的注解。如果恰好有⽬录外的 Controller 类,很遗憾,这些控制器将⽆法访问。
回到开头那段代码:
@SpringBootApplication(scanBasePackages ={})
@ComponentScan(basePackages = {})
这⾥指定了ComponentScan注解后,scanBasePackages就失效了。因此,如果ComponentScan的b
asePackages值不包括cn.a.b 即启动类所在的包,仅指定了第三⽅ jar 的⽬录,那么这个⼯程下任何的注解都⽆法被扫描到。
MapperScan 注解
这个是 MyBatis 的注解,会将指定⽬录下所有 DAO 类封装成 MyBatis 的BaseMapper类,然后注⼊ Spring 容器中,不需要额外的注解,就可以完成注⼊。
启⽰录
SpringBoot 包扫描路径,两个注解的冲突⾏为,我反复验证了好久确定了现象,但是没有到合理的解释。这篇⽂章在草稿箱酝酿了快两周了,⼀直搁置着。
今天搜到了⼀篇⽂章,说⼆者同时使⽤时,SpringBootApplication会失效,⾄此 SpringBoot 扫描路径的疑惑终于消除了。
springboot框架的作用到此这篇关于详解SpringBoot启动类的扫描注解的⽤法及冲突原则的⽂章就介绍到这了,更多相关SpringBoot启动类扫描注解内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论