6、Spring IoC依赖注入.md 6.7 KB

第六章:Spring IoC依赖注入(Dependency Injection)

依赖注入的模式和类型

  • 手动模式 - 配置或者编程的方式,提前安排注入规则
    • XML 资源配置元信息
    • Java 注解配置元信息
    • API 配置元信息
  • 自动模式 - 实现方提供依赖自动关联的方式,按照內建的注入规则
    • Autowiring(自动绑定)

依赖注入类型

依赖注入类型 配置元数据举例
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 { ... }

自动绑定(Autowiring)模式,Autowiring modes

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

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

setter方法注入

  • 实现方法
    • 手动模式
    • XML资源配置元信息
    • JAVA注解配置元信息
    • API配置元信息
    • 自动模式
    • byName
    • byType

构造器注入

  • 实现方法

    • 手动模式
    • XML资源配置元信息
    • JAVA注解配置元信息
    • API配置元信息

    • 自动模式

    • constructor -- 特殊的bytype

字段注入

方法注入

Aware 系列接口回调

內建接口 说明
BeanFactoryAware 获取 IoC 容器 - BeanFactory
ApplicationContextAware 获取 Spring 应用上下文 - ApplicationContext 对象
EnvironmentAware 获取 Environment 对象
ResourceLoaderAware 获取资源加载器 对象 - ResourceLoader
BeanClassLoaderAware 获取加载当前 Bean Class 的 ClassLoader
BeanNameAware 获取当前 Bean 的名称
MessageSourceAware 获取 MessageSource 对象,用于 Spring 国际化
ApplicationEventPublisherAware 获取 ApplicationEventPublishAware 对象,用于 Spring 事件
EmbeddedValueResolverAware 获取 StringValueResolver 对象,用于占位符处理

依赖注入类型选择

  • 低依赖:构造器注入
  • 多依赖:Setter 方法注入 --- 注入时机没有顺序
  • 便利性:字段注入
  • 声明类:方法注入 --- 不建议使用,建议配置@Bean使用

各种类型注入

  • 基础类型
    • 原生类型(Primitive):boolean、byte、char、short、int、float、long、double
    • 标量类型(Scalar):Number、Character、Boolean、Enum、Locale、Charset、Currency、Properties、UUID
    • 常规类型(General):Object、String、TimeZone、Calendar、Optional 等
    • Spring 类型:Resource、InputSource、Formatter 等
  • 集合类型
    • 数组类型(Array):原生类型、标量类型、常规类型、Spring 类型
    • 集合类型(Collection)
    • Collection:List、Set(SortedSet、NavigableSet、EnumSet)
    • Map:Properties
  • 限定注入
  • 延迟依赖注入

    • 使用API ObjectFactory 延迟注入
    • 单一类型
    • 集合类型

    • 使用API ObjectProvider 延迟注入(推荐)

    • 单一类型

    • 集合类型

  • 使用 API ObjectFactory 延迟注入

    • 单一类型
    • 集合类型
  • 使用 API ObjectProvider 延迟注入(推荐)

    • 单一类型
    • 集合类型

依赖处理过程

  • 入口 - DefaultListableBeanFactory#resolveDependency
  • 依赖描述符 - Dependency Descriptor
  • 自定绑定候选对象处理器 - AutowireCandidateResolver

@autowired注入过程

  • 元信息解析
  • 依赖查找(依赖处理)
  • 依赖注入(字段,方法)

@Autowired@Inject 注入,参考 AutowiredAnnotationBeanPostProcessor

Java通用注解注入原理:

  • CommonAnnotationBeanPostProcessor
  • 注入注解
    • javax.xml.ws.WebServiceRef
    • javax.ejb.EJB
    • javax.annotation.Resource
  • 生命周期注解
    • javax.annotation.PostConstruct
    • javax.annotation.PreDestroy

自定义依赖注入注解

  • 基于 AutowiredAnnotationBeanPostProcessor 实现
  • 自定义实现
    • 生命周期处理
    • InstantiationAwareBeanPostProcessor
    • MergedBeanDefinitionPostProcessor
    • 元数据
    • InjectedElement
    • InjectionMetadata
  • org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
    • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
    • @Autowired
    • @Value
    • @Inject
    • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
    • @PostConstruct
    • @PreDestroy

初始化 Bean 时,AutowiredAnnotationBeanPostProcessor 先解析 Bean 中的依赖(@Autowire@Value),然后 CommonAnnotationBeanPostProcessor 调用初始化方法 @@PostConstruct

@Bean 方法设置为 static ,可以让 Bean 提前初始化。

  • 依赖查找:ApplicationContext#getBean
  • 依赖处理过程:org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency

面试题精选

1、有多少种依赖注入的方式?

image-20221009100805500

2、偏好构造器注入还是setter注入?

image-20221009100904481

3、spring依赖注入的来源有哪些?

image-20221009100952662