依赖注入
程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。
依赖注入的方式
-
构造器注入(1xml中使用
<constructor-arg>
标签定义构造函数的参数,以调用构造函数,用到ref。2或者@autowire加到构造函数上) -
setter方式注入(1xml中使用
<property>
标签调用setter方法,用到ref。2或者@autowire加到setter方法上) -
属性注入(用@Autowired标记字段,不会调用setter方法,而是通过反射调用Field.set方法直接注入。具体见这篇文章,我们来谈一谈Spring中的属性注入-CSDN博客的“字段的属性注入”部分)
-
接口注入(需要被注入类实现一个接口,并实现该接口的方法,该方法的入参类型为依赖对象的类型,方法中对被注入类的依赖属性进行赋值。这要求被注入类实现一个接口,带有侵入性,过于耦合,不推荐。具体见《Spring揭秘》2.2.3和2.2.4部分)
接口注入的用例(继承了Spring的一个BeanFactoryAware接口,进行BeanFactory的注入,不推荐):
public class MyBean implements BeanFactoryAware { private BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } // 其他业务逻辑... }
-
自动装配注入(自动装配根据xml中autowire属性的不同,会属于构造器注入或者setter方式注入。xml中autowire属性设置byType,byName,constructor,no或者autodetect,其中byType和byName实则是setter方式注入,constructor实则是构造器注入,autodetect会尝试构造器注入,否则setter方式注入,no需要用ref进行setter方式注入。具体见Spring系列之依赖注入的方式 - 平凡希 - 博客园 (cnblogs.com)的“二、依赖注入——自动装配”部分)
构造器注入和setter方式注入的使用,xml版可见这6种 Spring 依赖注入方式,你都会吗? - 掘金 (juejin.cn)的“1. 构造器注入”和“2. Setter方法注入”部分,注解版即@Autowire,可见Spring IOC最全详解(定义原理及注入方式) – mikechen的“依赖注入方式”部分。
@Autowired和构造方法执行的顺序值得研究,具体见 @Autowired和构造方法执行的顺序解析_被autowired注解的变量的执行顺序优先于构造方法嘛-CSDN博客
总结
依赖注入方式的分类分为构造器注入,setter方式注入,属性注入和接口注入四种,自动装配中根据autowire属性的不同,会属于构造器注入或者setter方式注入。
在确定依赖注入方式的过程中翻阅博客,有些博客的分类不是很准确(比如这6种 Spring 依赖注入方式,你都会吗? - 掘金 (juejin.cn)),导致需要翻阅大量的博客来进行对比验证,好在最终总结出一个相对比较合理的分类。这样的分类根据这篇文章,我们来谈一谈Spring中的属性注入-CSDN博客的源码解析中,也能得出,即byConstructor注入(即构造器注入),Field.set方法调用,setter方法调用 这三类。
通过大量博客的对比,得出的分类结论基本上比较合理,但没有亲自读过Spring IOC源码,这样的分类结论终归是基于二手资料(大量博客)总结来的,基于一手资料(源码)的结论才是最有说服力的。以后有机会阅读一下Spring IOC源码,以完成上述分类结论的最后验证。
参考
这6种 Spring 依赖注入方式,你都会吗? - 掘金 (juejin.cn)
Spring IOC最全详解(定义原理及注入方式) – mikechen
这篇文章,我们来谈一谈Spring中的属性注入-CSDN博客
《Spring揭秘》2.2.3和2.2.4部分