SpringBoot教程(8) @ComponentScan注解 value basePackageClasses 详细讲解

本文详细介绍Spring框架中@ComponentScan注解的使用方法,包括value和basePackages属性的作用及配置方式,以及basePackageClasses属性如何帮助更精确地指定扫描范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、@ComponentScan用法介绍

@ComponentScan很多人都知道它是用来扫描知道包路径下的组件,并把它们注册到Spring容器中。

@ComponentScan它看着挺简单,但是它有很多参数,功能很强大,其中有很多细节需要注意。

下面我讲由浅入深地介绍@ComponentScan。

1. value和basePackages

value和basePackages的作用是一样的,它们互为别名,给他们设置成某包名路径,这样Spring项目启动时就会加载该包和其子包的带有特定注解的类到Spring容器中。这些注解有@Component、@Bean、@Controller、@Service、@Repository等等。

1.1 创建目录结构

在这里插入图片描述

1.2 config包下配置类SpringConfiguration

注意@ComponentScan({“config”})指定扫描config包

package config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"config"})
public class SpringConfiguration {
}

1.3 server包下业务接口和类

UserService 接口

package service;

public interface UserService {
    void saveUser();
}

UserServiceImpl 实现类
注意给UserServiceImpl加了注解@Service(“userService”)

package service.impl;

import org.springframework.stereotype.Service;
import service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Override
    public void saveUser() {
        System.out.println("保存了用户");
    }
}

1.4 编写测试类

public class ComponentScanTest {
    public static void main(String[] args) {
        //创建容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("config");

        SpringConfiguration bean1 = ac.getBean(SpringConfiguration.class);
        System.out.println(bean1);
        
        Object bean2 = ac.getBean("userService");
        System.out.println(bean2);
    }
}

1.5 运行结果分析

在这里插入图片描述
从运行结果来看,分为2个部分

  • 获取到了SpringConfiguration的Bean
  • 没有获取到userService

因为@ComponentScan({“config”})它扫描的是config包及其子包,而service包和config包是并列的,所以不会扫描到userService。

1.6 对@ComponentScan修改

@ComponentScan的value添加的是数组,所以可以再添加一个"service"

@Configuration
@ComponentScan({"config", "service"})
public class SpringConfiguration {
}

因为value和basePackages 是等同的,所以也可以写成如下

@Configuration
@ComponentScan(basePackages = {"config", "service"})
public class SpringConfiguration {
}

运行结果如下:
可以看出userService这个实力也加载了。

config.SpringConfiguration$$EnhancerBySpringCGLIB$$e3e5d8ab@14dd9eb7
service.impl.UserServiceImpl@52e6fdee

2. basePackageClasses的作用

basePackageClasses 用来指定某个类所在 包 及 其 子 包 下 \color{red}{包及其子包下} 的所有组件。
下面通过例子来说明basePackageClasses 的作用。

2.1 添加几个类

在这里插入图片描述

2.2 添加几个dao类

d a o . e s \color{red}{dao.es} dao.es包下:

@Repository("esDeptDao")
public class DeptDao {
}
@Repository("esUserDao")
public class UserDao {
}

d a o . e s . o l d \color{red}{dao.es.old} dao.es.old包下:

@Repository("oldEsUserDao")
public class UserDao {
}

mysql包下:
d a o . m y s q l \color{red}{dao.mysql} dao.mysql包下:

@Repository("mysqlUserDao")
public class UserDao {
}

2.3 给@ComponentScan添加basePackageClasses

给@ComponentScan添加basePackageClasses = DeptDao.class

注意:这里import的是 d a o . e s . D e p t D a o \color{red}{dao.es.DeptDao} dao.es.DeptDao

dao.es.DeptDao属于dao.es包,那么就会导入dao.es包和其子包dao.es.old包下的所有组件。

package config;

//注意这个import
import dao.es.DeptDao;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Co
nfiguration
@ComponentScan(basePackages = {"config", "service"}, basePackageClasses = DeptDao.class)
public class SpringConfiguration {
}

2.4 验证导入的包

public class ComponentScanTest {
    public static void main(String[] args) {
        //创建容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("config");

        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (int i= 0; i < beanDefinitionNames.length; i++){
            System.out.println(beanDefinitionNames[i]);
        }
    }
}

输出如下:

springConfiguration
userService
esDeptDao
esUserDao
oldEsUserDao

说明basePackageClasses起到作用的是下面红框的几个类
在这里插入图片描述

<think>嗯,用户让我详细讲解Spring Boot中的几个注解,包括@Controller和@RestController,@SpringBootApplication,@ComponentScan,@RequestMapping和@GetMapping,还要举例说明。我需要先回顾这些注解的基本用法和区别,然后组织一个结构清晰的回答。 首先,@Controller和@RestController的区别。记得@Controller是用来标记一个类作为Spring MVC的控制器,处理HTTP请求,通常结合视图解析器返回页面。而@RestController是@Controller和@ResponseBody的组合,直接返回JSON或XML数据,适用于RESTful API。需要举一个返回视图的例子和一个返回JSON的例子。 接下来是@SpringBootApplication,这个注解是Spring Boot的核心,它组合了@Configuration、@EnableAutoConfiguration和@ComponentScan。要解释这三个部分的作用,比如@Configuration表示配置类,@EnableAutoConfiguration开启自动配置,@ComponentScan扫描当前包及其子包的组件。可能需要举例说明主类上的使用。 然后是@ComponentScan,用于指定扫描的包路径。如果用户没有自定义,默认扫描主类所在包及其子包。如果组件不在默认路径下,就需要用@ComponentScan指定。例如,如果有一个配置类在com.example.config包,就需要在@SpringBootApplication后面加上@ComponentScan("com.example.config")。 接下来是@RequestMapping和@GetMapping。@RequestMapping可以处理所有HTTP方法,需要指定method属性,而@GetMapping是@RequestMapping(method = RequestMethod.GET)的简写。需要举例说明两者的用法,比如在类级别和方法级别使用@RequestMapping,以及使用@GetMapping简化代码。 在组织结构时,应该分点讲解每个注解,用例子说明,并注意它们之间的关联。比如@SpringBootApplication包含@ComponentScan,所以如果在主类中已经使用了@SpringBootApplication,通常不需要再单独使用@ComponentScan,除非需要扫描其他包。 另外,需要注意用户可能的疑问点,比如@RestController和@Controller返回数据的区别,自动配置的原理,以及路径映射的优先级等。例子要简单明了,能够帮助用户理解基本用法,避免引入复杂的概念。 最后,检查是否有遗漏的注解或者关联知识点,例如@ResponseBody的作用,或者@PostMapping等其他HTTP方法注解。不过用户只问了@RequestMapping和@GetMapping,所以可以简要提到其他类似注解,但不需要详细展开。 现在把这些整理成结构化的回答,确保每个部分都有示例,语言简洁明了,符合中文表达习惯。</think>以下是Spring Boot核心注解详细说明及示例: 一、@Controller vs @RestController 1. @Controller - 传统MVC控制器,返回视图名称 - 示例: ```java @Controller public class PageController { @GetMapping("/home") public String home() { return "home"; // 返回home.html模板 } } ``` 2. @RestController - 组合注解 = @Controller + @ResponseBody - 直接返回数据(JSON/XML) - 示例: ```java @RestController public class ApiController { @GetMapping("/user") public User getUser() { return new User("Alice", 25); // 自动转为JSON } } ``` 二、@SpringBootApplication(核心注解) - 组合注解 = @Configuration + @EnableAutoConfiguration + @ComponentScan - 必须标注在主启动类 - 示例: ```java @SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } ``` 三、@ComponentScan - 控制组件扫描范围 - 默认扫描主类所在包及其子包 - 自定义示例: ```java @SpringBootApplication @ComponentScan({"com.example.main", "com.example.utils"}) public class MyApp { // ... } ``` 四、请求映射注解 1. @RequestMapping - 基础映射注解,支持所有HTTP方法 - 示例: ```java @RestController @RequestMapping("/api") public class MyController { @RequestMapping(value = "/items", method = RequestMethod.GET) public List<Item> getItems() { // ... } } ``` 2. @GetMapping - 特定GET请求的快捷方式 - 示例: ```java @RestController public class BookController { @GetMapping("/books/{id}") public Book getBook(@PathVariable Long id) { // ... } } ``` 对比表格: | 注解 | 特点 | |--------------------|----------------------------------------------------------------------| | @RequestMapping | 支持所有HTTP方法,需指定method属性 | | @GetMapping | 仅处理GET请求,代码更简洁 | | @PostMapping | 同理适用于POST请求(其他如@PutMapping/@DeleteMapping同理) | 典型应用场景: 1. 传统Web应用:@Controller + 视图模板 2. REST API:@RestController + 映射注解 3. 微服务启动类:@SpringBootApplication 4. 多模块项目:配合@ComponentScan扫描不同模块的组件 注意事项: 1. 路径匹配优先级:精确路径优先于通配符路径 2. 自动配置依赖:确保组件位于@ComponentScan扫描范围内 3. 方法级注解会继承类级@RequestMapping的路径 4. 推荐使用特定方法注解(@GetMapping等)提高代码可读性 示例组合使用: ```java @RestController @RequestMapping("/api/v1") public class ProductController { @GetMapping("/products") public List<Product> listProducts() { // 实际访问路径:/api/v1/products } @PostMapping("/products") public Product createProduct(@RequestBody Product product) { // 处理POST请求 } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值