SpringDI四种依赖注入方式详解

谁践踏了优雅 2023-02-28 01:20 32阅读 0赞

文章目录

  • SpringDI(依赖注入)
      • 一、DI概述
      • 二、什么是DI
        • 2.1 了解DI的思想
        • 2.2 依赖
        • 2.3 注入
      • 三、注入方式
        • 3.1 Setter方法注入
          • 3.1.1 定义JavaBean
          • 3.1.2 注入各种数据类型
          • 3.1.3 注入自建类型数据
        • 3.2 构造方法注入
          • 3.2.1 定义JavaBean
          • 3.2.2 构造方法注入
        • 3.3 自动注入
          • 3.3.1 注入场景
          • 3.3.2 自动注入的两种方式
        • 3.4 注解自动注入

LOGO
文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star!
搜索关注微信公众号 【码出Offer】 领取各种学习资料!

SpringDI(依赖注入)


一、DI概述

Dependency Injection即为依赖注入,简称DI

简单来说,在Spring创建对象的同时,为其属性赋值,称之为依赖注入。

形象来说,组件之间依赖关系由容器在运行期决定的,即由容器动态的将某个依赖关系注入到组件之中。

二、什么是DI

2.1 了解DI的思想

简单了解了DI(依赖注入),在看依赖注入这个词,我们也可以将依赖注入以IOC(控制反转)的形式拆分它。

顾名思义,依赖注入是由“依赖”和“注入”两个词汇组合而成,那么我们再一次顺藤摸瓜,分别分析这两个词语!

2.2 依赖

依赖一词,可以拆分成很多元素。比如说,达成依赖条件必须是两个对象谁依赖谁某一个对象依赖另一个对象的什么 。这里我们可以根据这几个条件列举出这几种情况:

  1. 关于谁依赖与谁,当然是应用程序依赖于IOC容器。因为应用程序依赖于IOC容器提供的对象所需外部资源,所以就产生了这种依赖关系。(可以理解为入口,虽然不是这么严谨吧!)

2.3 注入

注入一次,可以也可以拆分成很多元素。比如说,注入可以分解成谁注入谁注入了什么 。这里我们也可以根据这两个条件来列举出这几种情况:

  1. 关于谁注入谁,身为容器的IOC肯定是被注入的对象,也就是说我们将所需要的对象注入到IOC容器中。至于注入了什么,很明显,就是我们项目中所需要的对象、资源、数据等等。简单来说,我们需要外部的资源既可以注入到IOC容器中,并由IOC容器来实现注入对象的控制反转!
  2. IOC的是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。

三、注入方式

3.1 Setter方法注入

Setter方法注入,它只需要提供对应的Setter方法接口实现注入,由于JavaBean一般都实现了Setter方法,所以Setter方法注入也成为了我们常用的注入方法之一。

3.1.1 定义JavaBean

定义一个JavaBean并赋予其Setter方法

  1. package com.mylifes1110.bean;
  2. import java.util.*;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. //Lombok@Data注解提供了Setter方法
  7. @Data
  8. @AllArgsConstructor
  9. @NoArgsConstructor
  10. public class User {
  11. private Integer id;
  12. private String password;
  13. private String sex;
  14. private Integer age;
  15. private Date bornDate;
  16. private String[] hobbys;
  17. private Set<String> phones;
  18. private List<String> names;
  19. private Map<String, String> countries;
  20. private Properties files;
  21. }
3.1.2 注入各种数据类型

注意:Spring底层对Date日期类型做了处理,默认处理格式为“yyyy/MM/dd”

  1. <bean id="User" class="com.mylifes1110.bean.User">
  2. <!--注入基本数据类型-->
  3. <property name="id" value="1"/>
  4. <property name="password" value="123456"/>
  5. <property name="sex" value="male"/>
  6. <property name="age" value="18"/>
  7. <!--注入日期类型-->
  8. <property name="bornDate" value="1999/09/09"/>
  9. <!--注入数组类型-->
  10. <property name="hobbys">
  11. <array>
  12. <value>Run</value>
  13. <value>Jump</value>
  14. <value>Climb</value>
  15. </array>
  16. </property>
  17. <!--注入List集合类型-->
  18. <property name="names">
  19. <list>
  20. <value>Ziph</value>
  21. <value>Join</value>
  22. <value>Marry</value>
  23. </list>
  24. </property>
  25. <!--注入Set集合类型-->
  26. <property name="phones">
  27. <set>
  28. <value>110</value>
  29. <value>119</value>
  30. <value>120</value>
  31. </set>
  32. </property>
  33. <!--注入Properties类型-->
  34. <property name="files">
  35. <props>
  36. <prop key="first">One</prop>
  37. <prop key="second">Two</prop>
  38. <prop key="third">Three</prop>
  39. </props>
  40. </property>
  41. <!--注入Map集合类型-->
  42. <property name="countries">
  43. <map>
  44. <entry key="CHINA" value="中国"/>
  45. <entry key="USA" value="美国"/>
  46. <entry key="UK" value="英国"/>
  47. </map>
  48. </property>
  49. </bean>
3.1.3 注入自建类型数据

将Service层需要一个Dao层实现类对象,我们可以使用注入方式来实现对Service层和Dao层的对象关联

  1. <bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
  2. <bean id="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
  3. <property name="userDao" ref="UserDao"/>
  4. </bean>

将创建的Bean对象注入到另一个对象中,比如一个JavaBean对象中作为了另一个JavaBean对象的属性

  1. <!--次要bean,被作为属性-->
  2. <bean id="address" class="com.mylifes1110.bean.Address">
  3. <property name="position" value="上海市" />
  4. <property name="zipCode" value="100001" />
  5. </bean>
  6. <!--主要bean,操作的主体-->
  7. <bean id="user" class="com.mylifes1110.bean.User">
  8. <!--address属性引用address对象-->
  9. <property name="address" ref="address" />
  10. </bean>

3.2 构造方法注入

创建对象时,Spring工厂会通过构造方法为对象的属性赋值。由于某些框架或者项目中并没有为JavaBean提供Setter方法,我们就可以利用其构造方法来注入。不要和我说,没有提供构造方法哈!(开个玩笑!)

3.2.1 定义JavaBean

定义一个JavaBean对象,为其提供构造方法

  1. public class Student {
  2. private Integer id;
  3. private String name;
  4. private String sex;
  5. private Integer age;
  6. //Constructors
  7. public Student(Integer id , String name , String sex , Integer age){
  8. this.id = id;
  9. this.name = name;
  10. this.sex = sex;
  11. this.age = age;
  12. }
  13. }
3.2.2 构造方法注入
  1. <!--构造注入-->
  2. <bean id="u3" class="com.mylifes1110.bean.Student">
  3. <!-- 除标签名称有变化,其他均和Set注入一致 -->
  4. <constructor-arg name="id" value="1234" />
  5. <constructor-arg name="name" value="tom" />
  6. <constructor-arg name="age" value="20" />
  7. <constructor-arg name="sex" value="male" />
  8. </bean>

3.3 自动注入

不用在配置中 指定为哪个属性赋值,及赋什么值。由spring自动根据某个 “原则” ,在工厂中查找一个bean,为属性注入属性值。

3.3.1 注入场景

将Dao层实现类对象注入到Service层并调用方法得以测试

  1. package com.mylifes1110.service.impl;
  2. import com.mylifes1110.bean.User;
  3. import com.mylifes1110.dao.UserDao;
  4. import com.mylifes1110.service.UserService;
  5. public class UserServiceImpl implements UserService {
  6. private UserDao userDao;
  7. public void setUserDao(UserDao userDao) {
  8. this.userDao = userDao;
  9. }
  10. @Override
  11. public int insertUser(User user) {
  12. System.out.println("------insertUser and UserService------");
  13. return userDao.insertUser(null);
  14. }
  15. }
3.3.2 自动注入的两种方式

基于名称自动注入值

  1. <bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
  2. <!--为UserServiceImpl中的属性基于名称自动注入值-->
  3. <bean id="userService" class="com.mylifes1110.service.impl.userServiceImpl" autowire="byName"/>
  4. </beans>

基于类型自动注入值,根据实现的接口来判断并自动注入值,如果实现此接口的实现类太多,它会在很多实现此接口的实现类中选择名字相同的实现类进行注入。(现根据判断,如果不成功,则根据名称注入)

  1. <bean id="userDao" class="com.mylifes1110.dao.UserDaoImpl" />
  2. <!--为UserServiceImpl中的属性基于类型自动注入值-->
  3. <bean id="userService" class="com.mylifes1110.service.impl.UserServiceImpl" autowire="byType"/>
  4. </beans>

3.4 注解自动注入


























注解名称 描述
@Autowired 基于类型自动注入
@Resource 基于名称自动注入
@Qualifier(“userDAO”) 限定要自动注入的bean的id,一般和@Autowired联用
@Value 注入简单类型数据 (jdk8种基本数据类型+String类型)

使用基于类型自动注入,将Dao层注入到Service层

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired //注入类型为UserDao的bean
  4. @Qualifier("userDao") //如果有多个类型为UserDao的bean,可以用此注解从中指定一个
  5. private UserDao userDao;
  6. }

使用基于名称自动注入,将Dao层注入到Serivce层

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Resource("userDao") //注入id=“userDao”的bean
  4. private UserDao userDao;
  5. }

使用注入简单类型数据注解来完成简单注入JavaBean

  1. public class User{
  2. @Value("1") //注入数字
  3. private Integer id;
  4. @Value("Ziph") //注入String
  5. private String name;
  6. }

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,32人围观)

还没有评论,来说两句吧...

相关阅读

    相关 spring依赖注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注

    相关 spring依赖注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理。 spring提出了依赖