Bean 声明与依赖注入注解
Spring 的核心是 IoC 容器:对象(Bean)的创建和依赖关系由容器管理,而不是代码里 new 出来。本篇梳理两类注解——把类交给容器、从容器取依赖。
声明 Bean 的注解
| 注解 | 语义 | 典型用途 |
|---|---|---|
@Component | 通用组件 | 不便归类的工具类、通用组件 |
@Service | 业务层组件 | Service 实现类 |
@Repository | 数据访问层组件 | DAO/Mapper,附带异常转换功能 |
@Controller | 控制层(返回视图) | 传统 MVC 页面控制器 |
@RestController | 控制层(返回 JSON) | REST 接口,等于 @Controller + @ResponseBody |
@Configuration | 配置类 | 内部用 @Bean 方法注册 Bean |
四个 stereotype 注解功能上等价,区别只在语义分层和部分附加能力(如 @Repository 的持久化异常转换)。
@Service
public class UserService {
public User getById(Long id) {
// ...
}
}
Bean 默认名为类名首字母小写(userService),也可指定:@Service("myUserService")。
依赖注入的注解
@Autowired(byType)
按类型注入,由 Spring 提供:
@Service
public class OrderService {
private final UserService userService;
// 构造器注入(官方推荐):字段可声明为 final,天然支持单元测试
public OrderService(UserService userService) {
this.userService = userService;
}
}
三种注入方式对比:
| 方式 | 写法 | 评价 |
|---|---|---|
| 构造器注入 | 构造方法传参 | 推荐:依赖不可变、必依赖显式、易测试 |
| Setter 注入 | @Autowired 标注 setter | 适合可选依赖 |
| 字段注入 | @Autowired 直接标字段 | 简洁但隐藏依赖、不利于测试,不推荐 |
@Resource(byName)
JDK 提供,默认按名称注入,找不到再按类型:
@Resource(name = "myUserService")
private UserService userService;
@Qualifier
同类型有多个 Bean 时,配合 @Autowired 指定名称:
@Autowired
@Qualifier("alipayService")
private PayService payService;
Bean 的作用域
@Scope("prototype")
@Component
public class TaskBean { }
| 作用域 | 说明 |
|---|---|
singleton(默认) | 容器中仅一个实例 |
prototype | 每次注入都创建新实例 |
request / session | Web 环境下每请求/每会话一个实例 |
生命周期回调
@Component
public class CacheManager {
@PostConstruct
public void init() {
// Bean 初始化后执行:加载缓存、初始化连接
}
@PreDestroy
public void destroy() {
// 容器关闭前执行:释放资源
}
}