详解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.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 就失效了。因此,如果 ComponentScanbasePackages 值不包括 cn.com.a.b 即启动类所在的包,仅指定了第三方 jar 的目录,那么 这个工程下任何的注解都无法被扫描到

MapperScan 注解

这个是 MyBatis 的注解,会将指定目录下所有 DAO 类封装成 MyBatis 的 BaseMapper 类,然后注入 Spring 容器中, 不需要额外的注解 ,就可以完成注入。

启示录

SpringBoot 包扫描路径,两个注解的冲突行为,我反复验证了好久确定了现象,但是没有找到合理的解释。这篇文章在草稿箱酝酿了快两周了,一直搁置着。

今天搜到了一篇文章,说二者同时使用时, SpringBootApplication 会失效,至此 SpringBoot 扫描路径的疑惑终于消除了。

到此这篇关于详解SpringBoot启动类的扫描注解的用法及冲突原则的文章就介绍到这了,更多相关SpringBoot启动类扫描注解内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot启动类@SpringBootApplication注解背后的秘密

    在用SpringBoot的项目的时候,会发现不管干什么都离不开启动类,他是程序唯一的入口,那么他究竟为我们做了什么?本篇文章主要解析@SpringBootApplication. 一.启动类 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } } 二.@SpringBoo

  • springBoot项目启动类启动无法访问的解决方法

    网上也查了一些资料,我这里总结.下不来虚的,也不废话. 解决办法: 1.若是maven项目,则找到右边Maven Projects --->Plugins--->run(利用maven启动)则可以加载到webapp资源 2.上面方法治标不治本.在项目的pom文件中添加<bulid>标签标注路径即可,pom.xml后部分代码如下: 刷新maven加载,重启项目.若还是无法访问,重新导入项目 <dependencies> xxxxxxxxxxxx </dependen

  • SpringBoot为啥不用配置启动类的实现

    前言 在学习SparkJava.Vert.x等轻量级Web框架的时候,都遇到过打包问题,这两个框架打包的时候都需要添加额外的Maven配置,并指定启动类才能得到可执行的JAR包: 而springboot项目,似乎都不需要额外的配置,直接package就可以得到可执行的JAR包,这是怎么回事呢? Vert.x要怎么配? 我们先来看看,Vert.x打包做哪些配置 1)引入maven-shade-plugin插件 2)在插件中指定在package完成时触发shade操作 3)指定启动类 <plugin

  • 详解SpringBoot启动类的扫描注解的用法及冲突原则

    背景 SpringBoot 启动类上,配置扫描包路径有三种方式,最近看到一个应用上三种注解都用上了,代码如下: @SpringBootApplication(scanBasePackages ={"a","b"}) @ComponentScan(basePackages = {"a","b","c"}) @MapperScan({"XXX"}) public class XXApplic

  • 详解springBoot启动时找不到或无法加载主类解决办法

    1.jar包错误 第一步:首先鼠标键右击你的项目,点击run as-->maven clean 第二步:鼠标键右击你的项目,run as--->maven install:在eclipse控制台你可以看见报错的jar包: 第三步:去maven仓库删除对应的jar,右击你的项目,maven-->update project(重新下载jar包): 第四步:重复一,二步骤,找到你的启动类,run as java application;问题解决 2.jdk报错 打开你的项目结构,找到libra

  • 详解springboot启动时是如何加载配置文件application.yml文件

    今天启动springboot时,明明在resources目录下面配置了application.yml的文件,但是却读不出来,无奈看了下源码,总结一下springboot查找配置文件路径的过程,能力有限,欢迎各位大牛指导!!! spring加载配置文件是通过listener监视器实现的,在springboot启动时: 在容器启动完成后会广播一个SpringApplicationEvent事件,而SpringApplicationEvent事件是继承自ApplicationEvent时间的,代码如下

  • 详解springboot测试类注解

    目录 创建一个TextHello类 注解 主启动类 配置文件格式 区别 创建一个TextHello类 TextHello类的代码如下 @Controller @RequestMapping("/hello") public class TextHello { @GetMapping("/hello") @ResponseBody public String hello(){ return "hello,程程呀"; } } 我是在pom.xml文件

  • 详解SpringBoot启动代码和自动装配源码分析

    目录 一.SpringBoot启动代码主线分析 二.SpringBoot自动装配原理分析 1.自动装配的前置知识@Import 2.@SpringApplication注解分析 2.1@SpringBootConfiguration 2.2@EnableAutoConfiguration ​随着互联网的快速发展,各种组件层出不穷,需要框架集成的组件越来越多.每一种组件与Spring容器整合需要实现相关代码.SpringMVC框架配置由于太过于繁琐和依赖XML文件:为了方便快速集成第三方组件和减少

  • 详解SpringBoot中添加@ResponseBody注解会发生什么

    SpringBoot版本2.2.4.RELEASE. [1]SpringBoot接收到请求 ① springboot接收到一个请求返回json格式的列表,方法参数为JSONObject 格式,使用了注解@RequestBody 为什么这里要说明返回格式.方法参数.参数注解?因为方法参数与参数注解会影响你使用不同的参数解析器与后置处理器!通常使用WebDataBinder进行参数数据绑定结果也不同. 将要调用的目标方法如下: @ApiOperation(value="分页查询") @Re

  • 详解SpringBoot配置文件启动时动态配置参数方法

    序言 当我们要同时启用多个项目而又要使用不同端口或者变换配置属性时,我们可以在配置文件中设置${变量名}的变量来获取启动时传入的参数,从而实现了动态配置参数,使启用项目更加灵活 例子 server: port: ${PORT:50101} #服务端口 spring: application: name: xc‐govern‐center #指定服务名 eureka: client: registerWithEureka: true #服务注册,是否将自己注册到Eureka服务中 fetchReg

  • 详解SpringBoot中@ConditionalOnClass注解的使用

    目录 一.@ConditionalOnClass注解初始 二.@ConditionalOnClass注解用法 1.使用value属性 2.使用name属性 三.@ConditionalOnClass是怎么实现的 四.总结 今天给大家带来的是springboot中的@ConditionalOnClass注解的用法.上次的@ConditionalOnBean注解还记得吗? 一.@ConditionalOnClass注解初始 看下@CodidtionalOnClass注解的定义, 需要注意的有两点,

  • 详解SpringBoot定制@ResponseBody注解返回的Json格式

     1.引言 在SpringMVC的使用中,后端与前端的交互一般是使用Json格式进行数据传输,SpringMVC的@ResponseBody注解可以很好的帮助我们进行转换,但是后端返回数据给前端往往都有约定固定的格式,这时候我们在后端返回的时候都要组拼成固定的格式,每次重复的操作非常麻烦. 2.SpringMVC对@ResponseBody的处理 SpringMVC处理@ResponseBody注解声明的Controller是使用默认的.RequestResponseBodyMethodProc

随机推荐