springboot多模块扫包中的@SpringBootApplication、@ComponentScan和@MapperScan问题
创始人
2024-04-04 02:44:14
0

springboot多模块扫包中的@SpringBootApplication、@ComponentScan和@MapperScan问题

  • 1. 前言
  • 2. 处理swagger扫描多包问题
  • 3. 启动类里获取spring容器
  • 4. 处理上面问题的流程和解决对应的问题
    • 4.1 移动 DogController 和 HelloWorldController 同包
      • 4.1.1 问题1. required a bean of type
        • 4.1.1.1 问题描述
        • 4.1.1.2 问题原因
        • 4.1.1.3 解决问题
      • 4.1.2 问题2->@ComponentScan 与 @SpringBootApplication 问题
      • 4.1.3 问题3->@MapperScan
        • 4.1.3.1 启动类中 @MapperScan
        • 4.1.3.2 配置文件中 @MapperScan
    • 4.2 把 Dogcontroller 移回原包
  • 5. 开发建议

1. 前言

  • 在原有的项目里新增了一个module子模块form-message,但是在新增的子module里的controller里的接口在swagger在线文档里不展示,下面是解决此问题以及发现别问题的各种处理方法
  • 问题如下:
    在这里插入图片描述
    在这里插入图片描述

2. 处理swagger扫描多包问题

  • 这是首先要考虑的,需要在swagger配置文件里配置可扫描多包
    在这里插入图片描述
    关于配置可参考下面文章
    关于前后端分离项目接口文档之Springboot整合knife4的使用.

3. 启动类里获取spring容器

  • 再确保 swagger 配置没问题的情况下,可以试试下面的方法,下面代码添加到启动类里
    • 代码如下:
          @Beanpublic CommandLineRunner appRun(ApplicationContext ac) {return args -> {/*** 通过类名(BeanName)获取已注入对象* 这里 helloWorld 是一个被注入到容器中的helloWorld==》helloWorldController类*/System.out.println("=====================================================");Object helloWorld = ac.getBean("helloWorldController");System.out.println(helloWorld);System.out.println("=====================================================");Object dog = ac.getBean("dogController");System.out.println(dog);};}
      
      在这里插入图片描述
    • 启动看效果:
      在这里插入图片描述
  • 看到这里如果确定了不是swagger配置的问题,那么如果对spring容器以及注解很熟悉的,想必应该已经定位出问题了,下面的几乎可以不用看了,但是为了让大家更明白,所以我这里准备了下面的内容,一步一步来,让阅读的你更明白怎么回事,想继续的往下看吧!

4. 处理上面问题的流程和解决对应的问题

4.1 移动 DogController 和 HelloWorldController 同包

  • 移动到同一个包下,这可能是部分同学为了方便起最爱做的,那我们不妨试试看

4.1.1 问题1. required a bean of type

4.1.1.1 问题描述

  • 如下:
    	Description:Field dogService in com.liu.susu.start.controller.DogController required a bean of type 'com.liu2.susu.message.service.DogService' that could not be found.The injection point has the following annotations:- @org.springframework.beans.factory.annotation.Autowired(required=true)Action:Consider defining a bean of type 'com.liu2.susu.message.service.DogService' in your configuration.
    
    在这里插入图片描述
    在这里插入图片描述
  • 看到这里,应该知道了,很显然这个类没有注入到Spring容器中去,检查实现类
    在这里插入图片描述
  • 很显然,实现类也没问题,@service注解也有,那问题出现在哪里呢?

4.1.1.2 问题原因

  • 每一个Spring项目都有独立的Spring容器去存储自己项目中所注册的bean。

    上面问题出现的原因就是:启动类 StartApplication.java 启动时,模块 form-start 中Spring容器加载时未能将模块form-message中所定义的bean注册进Spring容器中,导致@Autowired注入模块form-message中的bean进行使用时,找不到对应的bean,才会出现上面的问题 Consider defining a bean of type 'com.liu2.susu.message.service.DogService' in your configuration.

4.1.1.3 解决问题

  • 启动类启动时,让模块form-start的Spring容器启动时,去扫描模块form-message包下的所有的组件并注册到模块form-start的Spring容器中即可解决上述问题。解决问题如下继续……

4.1.2 问题2->@ComponentScan 与 @SpringBootApplication 问题

  • 按照上面的分析,需要修改启动类上的注解了,

    这个修改需要注意注解 @ComponentScan 与 注解@SpringBootApplication的使用

    • 首先,springboot默认扫描启动类同级包和同级的子包内容
    • @ComponentScan注解的作用是:扫描标注了@Controller、@Service、@Repository、@Component 的类
    • 先给原启动类里的代码,如下:
      在这里插入图片描述
    • 如果在上面代码的基础上,直接使用 @SpringBootApplication 注解修改如下情况,是不可以的,问题并没有解决,如下:
      @SpringBootApplication(scanBasePackages = {"com.liu.susu","com.liu2.susu"})在这里插入图片描述
    • 为什么还没有扫描到?
      • 原因就是:
        @ComponentScan 和@SpringBootApplication注解的包扫描有冲突,@ComponentScan注解包扫描会覆盖掉@SpringBootApplication的包扫描
      • 要解决,需要把@ComponentScan("com.liu.susu.*")注释掉 或者 @ComponentScan扫描多包即可,如下两种写法都可以:
        //@ComponentScan("com.liu.susu.*")
        @ComponentScan(basePackages = {"com.liu.susu.*", "com.liu2.susu"})
        @SpringBootApplication
        //@SpringBootApplication(scanBasePackages = {"com.liu.susu","com.liu2.susu"})
        
        //@ComponentScan("com.liu.susu.*")
        //@ComponentScan(basePackages = {"com.liu.susu.*", "com.liu2.susu"})
        //@SpringBootApplication
        @SpringBootApplication(scanBasePackages = {"com.liu.susu","com.liu2.susu"})
        
        在这里插入图片描述
        好了,上个问题到这里解决了,开始mapper问题了。
        			Description:Field dogMapper in com.liu2.susu.message.service.DogServiceImpl required a bean of type 'com.liu2.susu.message.mapper.DogMapper' that could not be found.The injection point has the following annotations:- @org.springframework.beans.factory.annotation.Autowired(required=true)Action:Consider defining a bean of type 'com.liu2.susu.message.mapper.DogMapper' in your configuration.
        
        在这里插入图片描述

4.1.3 问题3->@MapperScan

4.1.3.1 启动类中 @MapperScan

  • 上面的原因:
    在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类,但是@ComponentScan不扫描@Mapper
    在这里插入图片描述

  • 所以用注解@MapperScan解决问题
    @MapperScan注解的作用是:指定要编译成接口实现类的包路径,在编译完成后这个包下的所有接口都会生成相应的接口实现类。

    @MapperScan("com.liu2.susu.message.mapper")
    

    在这里插入图片描述

  • 好了,到此就完美解决了!,再看看接口文档
    在这里插入图片描述

4.1.3.2 配置文件中 @MapperScan

  • 上面的扫描mapper包也可以加到配置文件中,去form-start模块中找到mybatis或mybatis-plus的配置类,添加上去即可,如下
    //@MapperScan("com.liu.susu.**.mapper")
    @MapperScan(basePackages={"com.liu.susu.**.mapper","com.liu2.susu.message.mapper"})
    
    或者用**匹配
    @MapperScan("com.**.susu.**.mapper")
    
    在这里插入图片描述

4.2 把 Dogcontroller 移回原包

  • 上面问题解决之后,测试没问题的话,可以移回去,问题也是肯定解决了的,这里我就不演示了。

5. 开发建议

  • 看上面的问题,虽然肯定可以解决,但是毕竟有点麻烦,如果统一包名那就没这么多麻烦事,保持原本的注解配置即可,所以,如果是同一个项目,项目的包名尽量保持一致,约束大于配置,还是要规范些好
    在这里插入图片描述
    好了,完美陈述了!

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...