OC(Inversion of Control,控制反转) 是 Spring 的核心思想之一:
- 传统方式:对象自己
new
依赖- Spring 方式:由 Spring 容器创建对象,并自动注入依赖
- 实现方式:依赖注入(DI, Dependency Injection)
而注解是实现 IOC/DI 的最常用方式(相比 XML 配置更简洁)。
Spring IOC 常用注解分类
分类 | 注解 | 作用 |
---|---|---|
组件注册类 | @Component , @Controller , @Service , @Repository |
声明一个类由 Spring 管理 |
依赖注入类 | @Autowired , @Qualifier , @Resource , @Value |
注入属性或依赖 |
配置类相关 | @Configuration , @Bean , @ComponentScan |
替代 XML 配置文件 |
作用域控制 | @Scope |
控制 Bean 的作用域(单例、原型等) |
生命周期 | @PostConstruct , @PreDestroy |
定义初始化和销毁方法 |
条件注册 | @Conditional |
满足条件才注册 Bean |
配置属性绑定 | @ConfigurationProperties , @PropertySource |
绑定配置文件中的属性 |
1. 组件注册类注解
✅ @Component
-
作用:通用注解,标记一个类为 Spring 管理的 Bean
-
使用 :
@Component public class UserService { // 这个类会被 Spring 容器创建和管理 }
✅ @Controller
- 作用 :用于 Web 层(Controller) ,本质是
@Component
的特化 - 场景:Spring MVC 中的请求处理器
@Controller
public class UserController {
@RequestMapping("/user")
public String getUser() {
return "user";
}
}
✅ @Service
- 作用 :用于 业务逻辑层(Service)
- 好处:语义清晰,便于分层管理
@Service
public class UserService {
// 业务逻辑
}
✅ @Repository
- 作用 :用于 数据访问层(DAO/Repository)
- 额外功能 :自动翻译数据库异常(如
SQLException
→DataAccessException
)
@Repository
public class UserDAO {
// 数据库操作
}
🔑 三者关系 :
@Controller
、@Service
、@Repository
都是@Component
的派生注解,功能上都让类被 Spring 扫描并注册为 Bean。
2. 依赖注入类注解
✅ @Autowired
- 作用 :自动按类型(byType) 注入依赖
- 可以放在:字段、构造器、setter、方法参数
@Service
public class UserService {
@Autowired
private UserDAO userDAO; // 自动注入
}
⚠️ 如果有多个同类型 Bean,会报错 → 需配合
@Qualifier
✅ @Qualifier
- 作用 :与
@Autowired
配合,按名称(byName) 指定注入哪个 Bean
@Autowired
@Qualifier("mysqlUserDAO")
private UserDAO userDAO;
✅ @Resource
(JSR-250)
- 作用 :Java 标准注解,默认按名称注入,名称不存在再按类型
@Resource(name = "userDAO")
private UserDAO userDAO;
- 不需要
@Qualifier
,更简洁
✅ @Value
- 作用 :注入基本值 或配置属性
@Value("${app.name}")
private String appName;
@Value("默认用户名")
private String defaultUser;
@Value("#{systemProperties['os.name']}")
private String osName; // SpEL 表达式
3. 配置类相关注解
✅ @Configuration
- 作用 :标记一个类为配置类 ,替代
applicationContext.xml
@Configuration
public class AppConfig {
// 可以定义 @Bean 方法
}
✅ @Bean
- 作用:在配置类中定义一个 Bean(通常用于第三方类)
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new DriverManagerDataSource("jdbc:mysql://...");
}
}
- 默认 Bean 名是方法名,可用
@Bean("myDS")
指定
✅ @ComponentScan
- 作用:指定 Spring 扫描哪些包下的注解类
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig { }
- Spring Boot 中
@SpringBootApplication
已包含此功能
4. 作用域控制
✅ @Scope
- 作用:设置 Bean 的作用域
@Scope("singleton") // 默认,单例
@Scope("prototype") // 每次 getBean 都创建新实例
@Scope("request") // 每个请求一个实例(Web)
@Scope("session") // 每个会话一个实例(Web)
-
使用:
@Component @Scope("prototype") public class UserSession { }
5. 生命周期注解
✅ @PostConstruct
- 作用:标记初始化方法,在 Bean 创建后自动调用
@PostConstruct
public void init() {
System.out.println("Bean 初始化完成");
}
✅ @PreDestroy
- 作用:标记销毁前方法,在容器关闭时调用(需手动关闭容器)
@PreDestroy
public void cleanup() {
System.out.println("资源释放");
}
⚠️ 注意:
@PostConstruct
和@PreDestroy
来自javax.annotation
,Java 9+ 需引入:
xml
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
6. 条件注册
✅ @Conditional
- 作用:根据条件决定是否注册某个 Bean
@Bean
@Conditional(OnLinuxCondition.class)
public Service linuxService() {
return new LinuxService();
}
- Spring Boot 中大量使用
@ConditionalOnClass
,@ConditionalOnMissingBean
等衍生注解
7. 配置属性绑定
✅ @ConfigurationProperties
-
作用:将配置文件中的属性批量绑定到对象
# application.yml
app:
name: myapp
version: 1.0
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String version;
// getter/setter
}
✅ @PropertySource
- 作用 :加载自定义
.properties
文件
@Configuration
@PropertySource("classpath:db.properties")
public class DBConfig { }
🧩 四、常用组合示例
示例 1:Service 注入 DAO
@Repository
public class UserDAO { }
@Service
public class UserService {
@Autowired
private UserDAO userDAO;
}
@Controller
public class UserController {
@Autowired
private UserService userService;
}
示例 2:配置类定义数据源
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
示例 3:读取配置文件
@Component
@ConfigurationProperties("server")
public class ServerConfig {
private int port;
private String address;
// getter/setter
}
✅ 五、总结:核心注解速查表
注解 | 作用 | 使用位置 | 是否必须 |
---|---|---|---|
@Component |
注册 Bean | 类 | ✅ |
@Service |
业务层 Bean | 类 | ✅(语义化) |
@Repository |
数据层 Bean | 类 | ✅(异常翻译) |
@Controller |
控制层 Bean | 类 | ✅(MVC) |
@Autowired |
自动注入 | 字段/方法/构造器 | ✅ |
@Qualifier |
指定 Bean 名 | 字段/参数 | 配合 @Autowired |
@Value |
注入值 | 字段 | ✅ |
@Configuration |
配置类 | 类 | ✅ |
@Bean |
定义 Bean | 方法 | ✅ |
@ComponentScan |
扫描包 | 配置类 | ✅ |
@Scope |
设置作用域 | 类/方法 | 可选 |
@PostConstruct |
初始化 | 方法 | 可选 |
@PreDestroy |
销毁前 | 方法 | 可选 |
@ComponentScan
扫描 →@Component
等注册 →@Autowired
注入 →@Configuration
+@Bean
配置外部组件