@ComponentScan 注解其实很简单,它主要就是定义扫描的包路径,然后从中找出标识了需要装配的类自动装配到Spring的Bean容器。
如果你做过 Web开发,一定都有用过 @Controller,@Service,@Repository 等注解,查看这些注解的源码你会发现,他们中都有一个共同的注解 @Component。没错 @ComponentScan 注解默认就会装配标识了 @Controller、@Service、@Repository 和 @Component 注解的类到 Spring 容器中。
下面将逐一查看 @Controller、@Service 和 @Repository 注解的源码:
(1)@Controller 注解源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}(2)@Service 注解源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}(3)@Repository 注解源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(annotation = Component.class)
String value() default "";
}上面上个源码中均有 @Component 注解。
假如我们创建了一个 Spring Boot 项目,该项目的启动类位于 com.huangx.springboot.springboot_componentscan_demo1 包下面。但是,我们创建的 controller 位于 com.huangx.springboot.controller 包下面。因此,Spring Boot 默认是不会去扫描的,我们也是不能正常访问。为了解决这个问题,我们可以使用 @ComponentScan 注解指定扫描位置,如下:
(1)项目结构图如下

(2)IndexController 控制器的源代码如下:
package com.huangx.springboot.controller;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping("/")
public String index(){
return "Welcome Spring Boot";
}
}(3)在Spring Boot 启动类添加 @ComponentScan 注释,源码如下:
package com.huangx.springboot.springboot_componentscan_demo1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {"com.huangx.springboot.controller"})
@SpringBootApplication
public class SpringbootComponentscanDemo1Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootComponentscanDemo1Application.class, args);
}
}启动 Spring Boot 项目,访问 http://localhost:8080/ 地址。
当然,你也可以配置多个扫描路径。如下例:
@ComponentScan(basePackages = {
"com.huangx.springboot.controller",
"com.huangx.springboot.controller2"
})
@SpringBootApplication
public class SpringbootComponentscanDemo1Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootComponentscanDemo1Application.class, args);
}
}上面实例,将分别扫描 com.huangx.springboot.controller 和 com.huangx.springboot.controller2 包下的类和子包下面的类。