Spring源码系列 - 依赖注入(Dependency Injection)

依赖注入(Dependency Injection)

面试官:请问,Spring 中有几种注入方式?
张三:有两种注入方式,1、按类型注入;2、按名称注入
李四:有三种注入方式,1、构造方法注入;2、setter注入;3、基于注解注入
到i的哪一种是正确的呢?我们先进行剖析

Spring 的自动注入(仅 XML 配置存在自动注入)

  • byType(按类型自动注入):default-autowire="byType"
    • 如果某个类有一个属性,并且提供了 setter 方法,那么就通过这个属性的 类型 去注入
    • 一旦出现两个相同类型的 type,一定会报错
  • byName(按名称自动注入):default-autowire="byName"
    • 如果某个类有一个属性,并且提供了 setter 方法,那么就通过这个属性的 名称 去注入

1、从这里可以看出 在XML中的自动注入,其实是使用了 setter 方式进行了注入
2、property 和 constructor-arg 均输入手动装配模式

// 基于 property 的手动注入方式
<bean id="exampleBean" class="examples.ExampleBean">
    <!-- setter injection using the nested ref element -->
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>
    </property>

    <!-- setter injection using the neater ref attribute -->
    <property name="beanTwo" ref="yetAnotherBean"/>
    <property name="integerProperty" value="1"/>
</bean>
// 基于 constructor 的手动注入方式
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

@Autowired 注解(手动装配)

  • 从原理上来说,还是手动装配(相当于在 XML 中指定 property 的方式)
    • 源码角度:完全没有走 byType 或 byName 的逻辑判断
    • 代码角度:@Autowired 其实已经指定了装配类型
  • 通过反射来注入的
    • 先按 type 进行注入,如果发现有相同的多个类型,会继续按 name 进行注入
  • 实现类
    • @Autowired:AutowiredAnnotationBeanPostProcessor
    • @Resources:CommonAnnotationBeanPostProcessor

Spring 的注入模型(基于自动注入,才会有相应的注入模型概念)

  • 注入模型
    • 查找 Bean,然后注入 Bean,中间经过很多步骤和逻辑
    • 注入模型并不是注入方式,方式是单一的,模型是复杂的
  • 注入模型有 no,byName,byType,constructor 四种模型
  • no
    • 不自动装配(默认)
  • byName
    • 按名称装配,找到就装配,找不到就算
    • 需要提供 setter 方法
  • byType
    • 按类型装配,找到一个就装配,找到多个就报错,找不到就算
    • 需要提供setter 方法
  • constructor
    • 根据构造函数找,找到就装配,找不到就报错
    • 如果存在多个构造方法:根据类的属性个数,查找最长的,最匹配的构造方法

1、从上面四种模型可以看出,除 no 和 constructor 外,无论是 byName 还是 byType 他们使用的还是 基于 setter 的注入方式;
2、我们需要理解 注入模型注入方式 的区别;

Spring 注入方式有几种(基于手动注入,只有手动注入,才会有注入方式的概念)

  • Constructor
    • 如果存在多个构造方法:根据类的属性个数,查找最长的,最匹配的构造方法
  • Setter
    • 无论是 byName 还是 byType 都需要提供相应的 setter 方法

所以 @Autowired 从字面来本身来说并不是一种注入方式,它其实是通过类型或名称来进行判断,最终还是使用了 setter 的注入方式

从我个人的理解 @Autowired 也是一种特殊的注入模型,整合了byType 和 byName


最后我们引入 Spring 官方文档中所描述的内容

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.
翻译:依赖注入有两种主要的变体: 基于构造的依赖注入和基于setter的依赖注入。

那么上面所提出的 Spring 注入方式有几种?其实就是问手动注入有几种方式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>