Spring 学习记录 - IoC
老李 Lv4

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
2
3
org.springframework.beans.factory.BeanFactory#getBean(java.lang.String)

Object getBean(String name) throws BeansException;
1
2
3
org.springframework.beans.factory.BeanFactory#getBean(java.lang.String, java.lang.Object...)

Object getBean(String name, Object... args) throws BeansException;

扩展:实现通过名称延迟查找 bean

  1. 定义需要延迟查找的 bean
  2. 定义一个 org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean bean ,设置 targetBeanName 属性为需要查找的 bean 名称
  3. ObjectFactory objectFactory = (ObjectFactory) beanFactory.getBean("objectFactory")
  4. objectFactory.getObject()

根据类型查找

可分为实时查找和延迟查找

实时查找

1
2
3
org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class<T>)

<T> T getBean(Class<T> requiredType) throws BeansException;
1
2
3
org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class<T>, java.lang.Object...)

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
1
2
3
org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(java.lang.Class<T>)

<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
1
2
3
org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(java.lang.Class<T>, boolean, boolean)

<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;

延迟查找

1
2
3
org.springframework.beans.factory.BeanFactory#getBeanProvider(java.lang.Class<T>)

<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
1
2
3
org.springframework.beans.factory.BeanFactory#getBeanProvider(org.springframework.core.ResolvableType)

<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

根据名称 + 类型查找

1
2
3
org.springframework.beans.factory.BeanFactory#getBean(java.lang.String, java.lang.Class<T>)

<T> T getBean(String name, Class<T> requiredType) throws BeansException;

根据注解查找

1
2
3
org.springframework.beans.factory.ListableBeanFactory#getBeansWithAnnotation

Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

依赖注入

依赖注入类型

  1. Setter 方法 <proeprty name="user" ref="userBean"/>
  2. 构造器 <constructor-arg name="user" ref="userBean" />
  3. 字段 @Autowired User user;
  4. 方法 @Autowired public void user(User user) { ... }
  5. 接口回调 class MyBean implements BeanFactoryAware { ... }

依赖注入模式

手动模式: 配置或者编程的方式,提前安排注入规则

  1. XML 资源配置元信息
  2. Java 注解配置元信息
  3. API 配置元信息

自动模式: 实现方提供依赖自动关联的方式,按照內建的注入规则

  1. Autowiring(自动绑定)

自动绑定模式

  1. no, 默认值,未激活 Autowiring ,需要手动指定依赖注入对象
  2. byName, 根据被注入属性的名称作为 Bean 名称进行依赖查找,并将对象设置到该属性
  3. byType, 根据被注入属性的类型作为依赖类型进行查找,并将对象设置到该属性
  4. constructor, 特殊 byType 类型,用于构造器参数

参考: org.springframework.beans.factory.annotation.Autowire

接口回调注入

  1. BeanFactoryAware 获取 IoC 容器 - BeanFactory
  2. ApplicationContextAware 获取 Spring 应用上下文 - ApplicationContext 对象
  3. EnvironmentAware 获取 Environment 对象
  4. ResourceLoaderAware 获取资源加载器 对象 - ResourceLoader
  5. BeanClassLoaderAware 获取加载当前 Bean Class 的 ClassLoader
  6. BeanNameAware 获取当前 Bean 的名称
  7. MessageSourceAware 获取 MessageSource 对象,用于 Spring 国际化
  8. ApplicationEventPublisherAware 获取 ApplicationEventPublishAware 对象,用于 Spring 事件
  9. EmbeddedValueResolverAware 获取 StringValueResolver 对象,用于占位符处理

根据 bean 名称注入

autowire="byName"

根据 bean 类型注入

autowire="byType"

注入容器内建 bean 对象

注入非 bean 对象

注入类型

依赖来源

  1. 自定义 bean
  2. 容器内建 bean
    1. AbstractApplicationContext 内建依赖
      1. messageSource org.springframework.context.MessageSource
      2. systemProperties java.util.Properties
      3. systemEnvironment java.util.Map
      4. environment org.springframework.core.env.Environment
      5. lifecycleProcessor org.springframework.context.LifecycleProcessor
      6. applicationEventMulticaster org.springframework.context.event.ApplicationEventMulticaster
    2. org.springframework.context.annotation.AnnotationConfigApplicationContext (见 org.springframework.context.annotation.AnnotationConfigUtils)
      1. org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor
      2. org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
      3. org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
      4. org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.EventListenerMethodProcessor
      5. org.springframework.context.event.internalEventListenerFactory org.springframework.context.event.DefaultEventListenerFactory
      6. org.springframework.context.annotation.internalPersistenceAnnotationProcessor PersistenceAnnotationBeanPostProcessor
  3. 容器内建依赖
    1. org.springframework.beans.factory.BeanFactory
    2. org.springframework.core.io.ResourceLoader
    3. org.springframework.context.ApplicationEventPublisher
    4. org.springframework.context.ApplicationContext

ApplicationContext 与 BeanFactory 的区别

ApplicationContext 是 BeanFactory 的超级,除了提供 IoC 容器功能之外,还提供了如下功能:

  1. 面向切面
  2. 配置元信息
  3. 资源管理
  4. 事件
  5. 国际化
  6. 注解
  7. 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