SpringBoot使用@ComponentScan的Controller失效原因分析

环境背景 在搭建整个架构过程中,启动类正常放在controller包外 启动类的注解如下:

@SpringBootApplication
@Slf4j
@EnableTransactionManagement
@EnableKafka
@ComponentScan("com.seconds.dao")
public class SecondsApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecondsApplication.class, args);
    }

}

造成项目启动后,controller包下的路径无法访问

@ComponentScan 默认扫描使用该注解的类所在的包,包括这个包下的类和子包, 所以如果没有配置basepackages,并且类都放在子包中,是可以正常访问的 * 如果配置了@ComponentScn中的basepackages,那么就要把所有需要扫描的包都配置. * 这种情况下,@ComponentScan是不会再去扫描当前类所在的包的. * 之前我之所以以为@ComponentScan对启动类之外的包无能为力, * 这里没有配置controller类的包,导致程序无法访问. * 这里必须配置扫描当前启动类的包,不然当前启动类对应的控制器将失效 修改成一下:

@SpringBootApplication
@Slf4j
@EnableTransactionManagement
@EnableKafka
//@ComponentScan("com.seconds")
@MapperScan(annotationClass = Repository.class, basePackages = "com.seconds.dao")
public class SecondsApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecondsApplication.class, args);
    }

}
//或者将当前的controller包也扫描到注解中

@SpringBootApplication
@MapperScan(annotationClass = Repository.class, basePackages = "com.graduationproject.model.mapper")

public class ServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }

}

项目中解决@ComponentScan导致controller包没有被扫描的方案

  1. 单体架构中,可以采用上面的的方式,在启动类用户使用@MapperScan(annotationClass = Repository.class, basePackages = “com.seconds.dao”)代替@ComponentScan
  2. 在分布式的项目中,mapper、service、controller肯定是在不同的模块下,可以在service层使用@MapperScan注解将mapper注入到service;在controller模块,采用@ComponentScan注解,但是一定得把当前controller的包也给注入到扫描的配置中;如下代码展示。

    service--模块注入mapper接口
    
    /**
    * @author fyzn12
    */
    @SpringBootApplication
    @MapperScan(annotationClass = Repository.class, basePackages = "com.graduationproject.model.mapper")
    public class ServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }
    
    }
    
    controller--模块输入service
    
    @SpringBootApplication
    @ComponentScan(basePackages = {"com.graduationproject.service","com.graduationproject.controller"})
    public class ControllerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ControllerApplication.class, args);
    }
    }

总结:@ComponentScan注解只会扫描指定的包及包下的子类。