IoC 容器
IoC 容器和 Bean 简介
IoC 也被称为 DI,其是一个过程:对象通过构造函数参数、工厂方法参数、被构造或从工厂方法返回后为对象实例设置的属性来定义它们的依赖关系,然后容器在创建 bean 时注入这些依赖项。这个过程与 bean 通过直接构造或 Service Locator pattern 机制来控制依赖项的构建或位置相反,故称 IoC。
org.springframework.beans
和 org.springframework.context
包是 Spring 框架 IoC 容器的基础。BeanFactory 接口提供了管理任何类型对象的高级配置机制。ApplicationContext 额外支持:
- 对 Spring AOP 简易集成
- 国际化处理
- 事件发布机制
- 应用层上下文,如 WebApplicationContext
在 Spring 中,构成应用骨架并由 Spring IoC 容器管理的对象称为bean。其由 Spring IoC 容器实例化、装配和管理。bean 及其之间的依赖关系反映在容器使用的配置元信息中。
IoC 容器概述
org.springframework.context.ApplicationContext
可以代表 Spring IoC 容器,其负责实例化、配置和组装 bean。容器通过读取配置元数据获取关于要实例化、配置和组装哪些对象的信息。配置元数据用 XML、Java 注释 或 Java 代码表示。
- 配置元数据 —— 指导 Spring IoC 容器实例化、配置和组装 bean
Bean 概述
在 Spring IoC 容器内部,bean 定义被表示为 BeanDefinition,其包含以下元数据:
- 全限定的类名
- bean 行为配置(作用域、生命周期回调等)
- 依赖项
- 其他初始化设置
实例化 Bean
- 基于构造函数实例化 —— 通过反射机制调用 Bean 的构造函数来实例化
- 基于静态工厂方法实例化 —— 通过 factory-method 制定的静态方法来 new 一个实例
- 基于实例工厂方法实例化
依赖项
依赖注入
简洁:去除了实例化操作的大量代码,解耦:基于面向接口编程,使得程序更具灵活性
- 基于构造函数的依赖注入
- 基于 Setter 的依赖注入 —— 实例化bean之后,通过容器调用 bean 上的 setter 方法来实现
1 选择:基于构造函数还是基于 Setter
2 解决:循环依赖
Bean 作用域
- Singleton —— 每个容器只有一份对象实例
- Prototype —— 每次请求都返回全新对象实例
自定义 Bean 行为
生命周期回调
初始化回调
org.springframework.beans.factory.InitializingBean
允许在容器已经设值了必要属性后执行 Bean 初始化工作(afterPropertiesSet)。推荐使用 @PostConstruct 注解或者指定 POJO 初始化方法。对于基于 xml 的配置元数据,可以使用init-method 属性。对于使用Java配置,可以使用 @Bean 的 initMethod 属性。
销毁回调
org.springframework.beans.factory.DisposableBean
让 Bean 在容器销毁后获得回调(destroy)。推荐使用 @PreDestroy 注解或指定 bean 定义支持的泛型方法。对于基于 xml 的配置元数据,可以在 上使用 destroy-method 属性。对于使用 Java 配置,可以使用 @Bean 的 destroyMethod 属性。
Aware
这种回调在设置普通 bean 属性之后,在初始化回调之前。
- ApplicationContextAware
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- ApplicationEventPublisherAware
- ResourceLoaderAware
- ServletConfigAware
- ServletContextAware
IoC 容器扩展点
ApplicationContext 自动检测 bean 定义中的 BeanPostProcessor bean,并将它们应用于随后创建的任何 bean。
ApplicationContext 自动检测 bean 定义中的 BeanFactoryPostProcessor bean,并在创建任何其他 bean 之前应用它们。
使用 BeanPostProcessor 自定义 Bean
作用:用于提供自定义的实例化逻辑、依赖项解析逻辑,与 Bean 实例交互
- postProcessBeforeInitialization —— 在任何 bean 初始化回调之前
-
postProcessAfterInitialization —— 在任何 bean 初始化回调之后
- 对于 FactoryBean ,这个回调将同时被 FactoryBean 实例和 FactoryBean 创建的对象调用
使用 BeanFactoryPostProcessor 自定义配置元信息
作用:修改配置元数据,与 Bean 定义交互
- postProcessBeanFactory —— 在 ApplicationContext 的标准初始化之后修改其内部 BeanFactory
使用 FactoryBean 自定义实例化逻辑
作用:FactoryBean 用于 Spring IoC 容器实例化逻辑
org.springframework.aop.framework.ProxyFactoryBean
org.springframework.jndi.JndiObjectFactoryBean
基于注解的容器配置
-
Spring 2.0 提供了 @Required 注解,实际工作者 RequiredAnnotationBeanPostProcessor
- 语意:必须在配置时通过 bean 定义中的显式属性值或自动装配设置属性
- 位置:setter 方法上
-
Spring 2.5 提供了 @Autowired 注解,实际工作者 AutowiredAnnotationBeanPostProcessor
- 语意:由 Spring 的依赖注入套件自动装配
- 位置:构造函数、属性、setter 方法、普通方法上
- 搭配:@Primary 从按类型自动装配的多个候选项选择一个,用在类型和方法上
- 搭配:@Qualifier 与特定的参数关联,缩小类型匹配集,用在属性、方法、类型、参数上
-
Spring 2.5 还添加了对 JSR-250 注解的支持,如 @Resource 、@PostConstruct 和 @PreDestroy 注解
- @Resource 与 @Autowired 作用类似,按名称装配
- @PostConstruct 和 @PreDestroy 注解属于生命周期回调注解
- 实际工作者 CommonAnnotationBeanPostProcessor
-
Spring 3.0 提供了 @Configuration 、 @Bean 和 @Import 注解
-
@Configuration 类比于
<beans/>
,@Bean 类比于<bean/>
- @Bean 返回的 Bean 名称是方法名
- @Import 用于组合 @Configuration
-
@Configuration 类比于
-
Spring 3.0 还添加了对 JSR-330 注解的支持,如 @Inject 和 @Named 注解
类路径扫描和待管组件
@Component 系列
- @Controller 用于表示层
- @Service 用于服务层
- @Repository 用于持久层
@ComponentScan 自动检测注册 Bean
- 类似于
<context:component-scan/>
,在 @Configuration 类上配置,指定basePackages
环境抽象
Profile
PropertySource
ApplicationContext 额外功效
- 国际化,MessageSource
- 资源访问,ResourceLoader
- 事件发布,ApplicationListener 和 ApplicationEventPublisher
- 多层次上下文,HierarchicalBeanFactory
ApplicationContext VS BeanFactory
特性 | ApplicationContext | BeanFactory |
---|---|---|
Bean 实例化/装配 | Yes | Yes |
集成生命周期管理 | Yes | No |
自动 BeanPostProcessor 注册 | Yes | No |
自动 BeanFactoryPostProcessor 注册 | Yes | No |
国际化 | Yes | No |
内置事件发布机制 | Yes | No |