Spring IOC/DI 核心知识点笔记
一、核心概念
- IOC(控制反转) 对象的创建控制权从程序自身转移到外部 IOC 容器,由容器统一管理对象的创建,这种思想称为控制反转。
- DI(依赖注入) IOC 容器在程序运行时,主动为应用程序提供其依赖的资源(对象),这个过程称为依赖注入。
- Bean 对象由 IOC 容器创建、管理的对象,称之为 Bean。
二、自定义 Bean 的声明(@Component及衍生注解)
通过在类上添加注解,将自定义类交给 IOC 容器管理,共 4 种等价注解(功能一致,语义区分层):
@Component:无法归类到其他层时使用@Controller:控制层类专用@Service:服务层类专用@Repository:数据访问层类专用(实际开发中使用较少)
补充说明
@RestController = @Controller + @ResponseBody(控制层返回 JSON 时用)- 上述注解生效的前提:被
@ComponentScan(组件扫描)覆盖 @ComponentScan默认包含在@SpringBootApplication中,默认扫描范围是启动类所在包及其子包- 注意:
@ComponentScan是覆盖配置,不是追加配置
三、第三方 Bean 的声明(@Bean)
1. 适用场景
当要管理的 Bean 来自第三方(如框架、工具类)时,因第三方类无法修改源码添加@Component,需用@Bean声明。
2. 核心规则
-
功能:将方法的返回值对象交给 IOC 容器管理,成为容器中的 Bean。
-
Bean 名称规则:
- 通过
@Bean(name/value)指定名称; - 未指定时,默认以方法名作为 Bean 名称。
- 通过
3. 第三方 Bean 的依赖注入
若第三方 Bean 依赖其他 Bean,直接在@Bean方法中加形参即可,容器会自动按类型注入依赖:
@Configuration
public class CommonConfig {
// 第三方Bean(SAXReader)依赖自定义Bean(DeptService)
@Bean
public SAXReader reader(DeptService deptService) {
System.out.println(deptService); // 依赖的Bean由容器自动注入
return new SAXReader();
}
}
4. 推荐配置方式(配置类集中管理)
为保证启动类纯粹性,建议用@Configuration声明配置类,集中管理第三方 Bean:
@Configuration // 标识为配置类
public class CommonConfig {
// 示例1:默认以方法名“saxReader”为Bean名
@Bean
public SAXReader saxReader() {
return new SAXReader();
}
// 示例2:通过name指定Bean名为“myHttpClient”
@Bean(name = "myHttpClient")
public HttpClient httpClient() {
return HttpClientBuilder.create().build();
}
}
5. 不推荐的方式(但是可行)
不要直接在启动类中声明@Bean(会导致启动类职责混乱):
@SpringBootApplication
public class SpringbootWebConfig2Application {
// 不推荐!破坏启动类纯粹性
@Bean
public SAXReader saxReader() {
return new SAXReader();
}
}
四、IOC 容器中主动获取 Bean 的方式
1. 先获取 IOC 容器对象
通过@Autowired注入ApplicationContext(代表 IOC 容器):
@Autowired
private ApplicationContext applicationContext; // IOC容器对象
2. 三种获取 Bean 的方法
通过applicationContext调用以下方法:
- 根据名称获取方法:
Object getBean(String name)说明:返回 Object 类型,需手动强转。 - 根据类型获取方法:
<T> T getBean(Class<T> requiredType)说明:直接返回对应类型,但容器中同类型 Bean 只能有一个。 - 根据名称 + 类型获取(带转换) 方法:
<T> T getBean(String name, Class<T> requiredType)说明:指定名称 + 类型,直接返回对应类型,无需强转。
五、Bean 的作用域与懒加载
1. 作用域分类
Spring 支持 5 种作用域,后 3 种仅在 Web 环境生效:
| 作用域 | 说明 |
|---|---|
| singleton | 容器内同名称 Bean 仅 1 个实例(单例)默认 |
| prototype | 每次使用时创建新实例(非单例) |
| request | 每个 HTTP 请求内创建新实例(Web 环境) |
| session | 每个会话内创建新实例(Web 环境) |
| application | 每个应用内创建新实例(Web 环境) |
2. 作用域配置
通过@Scope注解配置,例如:
@Component
@Scope("prototype") // 设置为非单例
public class UserService {}
3. 懒加载(@Lazy)
- 作用:默认
singletonBean 在容器启动时创建,加@Lazy后第一次使用时才创建。 - 适用场景:配合
singleton使用。 prototype本身是懒加载的。
六、@Component与@Bean的使用场景区分
| 注解类型 | 使用场景 |
|---|---|
@Component及衍生注解 | 项目中自定义的类 |
@Bean注解 | 项目中引入第三方的类 |