Spring 学习记录 - IoC
什么是 IoC ?
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度。
其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。
Spring Framework implementation of the Inversion of Control (IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.
依赖查找
单一类型依赖查找接口: BeanFactory
集合类型依赖查找接口: ListableBeanFactory
层次性依赖查找接口: HierarchicalBeanFactory
工具类: BeanFactoryUtils
根据名称查找
1 | org.springframework.beans.factory.BeanFactory#getBean(java.lang.String) |
1 | org.springframework.beans.factory.BeanFactory#getBean(java.lang.String, java.lang.Object...) |
扩展:实现通过名称延迟查找 bean
- 定义需要延迟查找的 bean
- 定义一个
org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBeanbean ,设置targetBeanName属性为需要查找的 bean 名称ObjectFactory objectFactory = (ObjectFactory) beanFactory.getBean("objectFactory")objectFactory.getObject()
根据类型查找
可分为实时查找和延迟查找
实时查找
1 | org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class<T>) |
1 | org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class<T>, java.lang.Object...) |
1 | org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(java.lang.Class<T>) |
1 | org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(java.lang.Class<T>, boolean, boolean) |
延迟查找
1 | org.springframework.beans.factory.BeanFactory#getBeanProvider(java.lang.Class<T>) |
1 | org.springframework.beans.factory.BeanFactory#getBeanProvider(org.springframework.core.ResolvableType) |
根据名称 + 类型查找
1 | org.springframework.beans.factory.BeanFactory#getBean(java.lang.String, java.lang.Class<T>) |
根据注解查找
1 | org.springframework.beans.factory.ListableBeanFactory#getBeansWithAnnotation |
依赖注入
依赖注入类型
- Setter 方法
<proeprty name="user" ref="userBean"/> - 构造器
<constructor-arg name="user" ref="userBean" /> - 字段
@Autowired User user; - 方法
@Autowired public void user(User user) { ... } - 接口回调
class MyBean implements BeanFactoryAware { ... }
依赖注入模式
手动模式: 配置或者编程的方式,提前安排注入规则
- XML 资源配置元信息
- Java 注解配置元信息
- API 配置元信息
自动模式: 实现方提供依赖自动关联的方式,按照內建的注入规则
- Autowiring(自动绑定)
自动绑定模式
- no, 默认值,未激活 Autowiring ,需要手动指定依赖注入对象
- byName, 根据被注入属性的名称作为 Bean 名称进行依赖查找,并将对象设置到该属性
- byType, 根据被注入属性的类型作为依赖类型进行查找,并将对象设置到该属性
- constructor, 特殊 byType 类型,用于构造器参数
参考: org.springframework.beans.factory.annotation.Autowire
接口回调注入
- BeanFactoryAware 获取 IoC 容器 - BeanFactory
- ApplicationContextAware 获取 Spring 应用上下文 - ApplicationContext 对象
- EnvironmentAware 获取 Environment 对象
- ResourceLoaderAware 获取资源加载器 对象 - ResourceLoader
- BeanClassLoaderAware 获取加载当前 Bean Class 的 ClassLoader
- BeanNameAware 获取当前 Bean 的名称
- MessageSourceAware 获取 MessageSource 对象,用于 Spring 国际化
- ApplicationEventPublisherAware 获取 ApplicationEventPublishAware 对象,用于 Spring 事件
- EmbeddedValueResolverAware 获取 StringValueResolver 对象,用于占位符处理
根据 bean 名称注入
autowire="byName"
根据 bean 类型注入
autowire="byType"
注入容器内建 bean 对象
注入非 bean 对象
注入类型
依赖来源
- 自定义 bean
- 容器内建 bean
- AbstractApplicationContext 内建依赖
- messageSource org.springframework.context.MessageSource
- systemProperties java.util.Properties
- systemEnvironment java.util.Map
- environment org.springframework.core.env.Environment
- lifecycleProcessor org.springframework.context.LifecycleProcessor
- applicationEventMulticaster org.springframework.context.event.ApplicationEventMulticaster
- org.springframework.context.annotation.AnnotationConfigApplicationContext (见 org.springframework.context.annotation.AnnotationConfigUtils)
- org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor
- org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
- org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.EventListenerMethodProcessor
- org.springframework.context.event.internalEventListenerFactory org.springframework.context.event.DefaultEventListenerFactory
- org.springframework.context.annotation.internalPersistenceAnnotationProcessor PersistenceAnnotationBeanPostProcessor
- AbstractApplicationContext 内建依赖
- 容器内建依赖
- org.springframework.beans.factory.BeanFactory
- org.springframework.core.io.ResourceLoader
- org.springframework.context.ApplicationEventPublisher
- org.springframework.context.ApplicationContext
ApplicationContext 与 BeanFactory 的区别
ApplicationContext 是 BeanFactory 的超级,除了提供 IoC 容器功能之外,还提供了如下功能:
- 面向切面
- 配置元信息
- 资源管理
- 事件
- 国际化
- 注解
- Environment 抽象
面试题
BeanFactory 与 FactoryBean 的区别
BeanFactory 是 IoC 底层容器。
FactoryBean 是创建 Bean 的一种方式,帮助实现复杂的初始化逻辑。在查找 Bean 的时候,如果该 Bean 是 FactoryBean ,将会调用 org.springframework.beans.factory.FactoryBean#getObject 方法获取 Bean 。
ObjectFactory 与 BeanFactory 的区别
ObjectFactory 与 BeanFactory 均提供依赖查找的能力。
不过 ObjectFactory 仅关注一个或一种类型的 Bean 依赖查找,并且自身不具备依赖查找的能力,能力则由 BeanFactory 输出。
BeanFactory 则提供了单一类型、集合类型以及层次性等多种依赖查找方式。
TODO
ObjectFactory
ObjectProvider