记录跟着狂神学Spring的历程(第14集)~
1.开启包扫描
<context:component-scan base-package="com.pojo"/>
开启配置,才能被 Spring 容器识别并扫描,这个包下的注解才会生效。默认情况下,Spring 会自动扫描注解所在包及其子包下的这些类。
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 指定要扫描的包,这个包下的注解就会生效 -->
<context:component-scan base-package="com.pojo"/>
<!-- 开启注解的支持 -->
<context:annotation-config/>
<!-- 无需把user这个bean注册在这里,简化配置文件,直接用注解就可以 -->
</beans>
2.@Component注解
- 加上@Component注解,等价于在配置文件里写
<bean id="user" class="com.pojo.User" />,这个bean注册到Spring里面,被Spring管理了。 - 默认的bean id是类名首字母小写
- 也可以指定bean id
@Component("uuuuser")
Java
@Component
public class User{
public String name = "Zoe";
}
2.1 @Value注解
若不想显式地赋属性值,也可以采用注解的方式,等价于在配置文件里写:
<property name="name" value="Zoe"/>
Java
@Component
public class User{
@Value("Zoe")
public String name;
}
@Value也可以放在set方法上面:
Java
@Component
public class User{
public String name;
@Value("Zoe")
public setName(String name){
this.name = name;
}
}
3.@Component 的衍生注解
@Component 是这三个注解(@Controller/@Service/@Repository)的父注解,后三者是 @Component 在不同业务层的专属细化注解,本质都是将类注册为 Spring 容器中的 Bean。
| 对应架构 | 注解 | 应用场景 | 专属附加功能 |
|---|---|---|---|
| 无特定层级 | @Component | 通用场景 | 无专属附加功能,仅作为基础的 Bean 注册注解,适用于无法归类到其他三层的工具类、公共类 |
| dao | @Repository | 操作数据库,封装数据访问逻辑 | 1. 标识该类为数据访问层,用于封装数据库操作(如 MyBatis 的 Mapper、JPA 的 Repository);2. 自动转换数据库访问异常(将 JDBC/Hibernate 的原生异常转换为 Spring 统一的 DataAccessException 异常体系) |
| service | @Service | 封装业务逻辑,处理核心业务 | 无强制附加功能,但约定俗成用于业务逻辑层,便于团队协作和代码阅读,是业务层的专属标识 |
| controller | @Controller | 接收前端请求,控制请求流转 | 1. 标识该类为 Spring MVC 的控制器,能处理 HTTP 请求(配合 @RequestMapping 等注解);2. 支持请求参数绑定、视图跳转、响应数据封装(JSON / 页面) |
3.1 @Controller
- 专门用于 MVC 架构的控制层,是前端请求的入口,负责接收前端传递的参数、调用服务层方法、返回响应结果(页面或 JSON 数据)。
- 必须配合 Spring MVC 的相关注解(如
@GetMapping、@PostMapping、@ResponseBody)使用,示例:
Java
// 订单控制器,接收订单相关请求
@Controller
@RequestMapping("/order")
public class OrderController {
// 注入服务层 Bean
@Autowired
private OrderService orderService;
// 处理查询订单列表的请求
@GetMapping("/list")
@ResponseBody
public R<List<Order>> getOrderList() {
List<Order> orderList = orderService.listAll();
return R.success(orderList);
}
}
3.2 @Service
专门用于封装业务逻辑,是控制层和持久层的中间层,负责处理复杂的业务逻辑(如数据校验、事务处理、多持久层方法调用)。
Java
// 订单服务类,封装订单相关业务逻辑
@Service
public class OrderService {
// 注入持久层 Bean
@Autowired
private OrderDao orderDao;
// 业务逻辑:查询所有订单
public List<Order> listAll() {
// 可添加业务校验、数据转换等逻辑
return orderRepository.findAll();
}
}
3.3 @Repository
- 专门用于封装数据访问逻辑,负责与数据库交互(如增删改查、分页查询),对应传统的 Dao 层。
- 核心附加功能是「异常转换」,Spring 会自动将该类中抛出的数据库原生异常(如
SQLException)转换为 Spring 统一的DataAccessException异常体系,便于全局异常处理,示例:
Java
// 订单持久层,操作数据库
@Repository
public class OrderRepository {
// 注入 JdbcTemplate 操作数据库
@Autowired
private JdbcTemplate jdbcTemplate;
// 数据访问逻辑:查询所有订单
public List<Order> findAll() {
String sql = "SELECT * FROM t_order";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Order.class));
}
}
4.作用域
@Scope注解可以指定bean作用域:单例模式、原型模式,等价于:
<bean id="user" class="com.pojo.User" scope="singleton" />
使用方式:
Java
@Component
@Scope("singleton")
public class User{
public String name = "Zoe";
}
xml与注解对比
xml更加万能,适用于任何场合,但是较为繁琐。 注解可以简化一些操作,但灵活性较差。