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


LOGO

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方法

package com.mylifes1110.bean;

import java.util.*;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//Lombok@Data注解提供了Setter方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer             id;
    private String              password;
    private String              sex;
    private Integer             age;
    private Date                bornDate;
    private String[]            hobbys;
    private Set<String>         phones;
    private List<String>        names;
    private Map<String, String> countries;
    private Properties          files;
}
3.1.2 注入各种数据类型

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

<bean id="User" class="com.mylifes1110.bean.User">
    <!--注入基本数据类型-->
    <property name="id" value="1"/>
    <property name="password" value="123456"/>
    <property name="sex" value="male"/>
    <property name="age" value="18"/>
    <!--注入日期类型-->
    <property name="bornDate" value="1999/09/09"/>
    <!--注入数组类型-->
    <property name="hobbys">
        <array>
            <value>Run</value>
            <value>Jump</value>
            <value>Climb</value>
        </array>
    </property>
    <!--注入List集合类型-->
    <property name="names">
        <list>
            <value>Ziph</value>
            <value>Join</value>
            <value>Marry</value>
        </list>
    </property>
    <!--注入Set集合类型-->
    <property name="phones">
        <set>
            <value>110</value>
            <value>119</value>
            <value>120</value>
        </set>
    </property>
    <!--注入Properties类型-->
    <property name="files">
        <props>
            <prop key="first">One</prop>
            <prop key="second">Two</prop>
            <prop key="third">Three</prop>
        </props>
    </property>
    <!--注入Map集合类型-->
    <property name="countries">
        <map>
            <entry key="CHINA" value="中国"/>
            <entry key="USA" value="美国"/>
            <entry key="UK" value="英国"/>
        </map>
    </property>
</bean>
3.1.3 注入自建类型数据

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

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

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

<!--次要bean,被作为属性-->
<bean id="address" class="com.mylifes1110.bean.Address">
    <property name="position" value="上海市" />
    <property name="zipCode" value="100001" />
</bean>

<!--主要bean,操作的主体-->
<bean id="user" class="com.mylifes1110.bean.User">
    <!--address属性引用address对象-->
    <property name="address" ref="address" />
</bean>

3.2 构造方法注入

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

3.2.1 定义JavaBean

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

public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;

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

3.3 自动注入

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

3.3.1 注入场景

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

package com.mylifes1110.service.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserService------");
        return userDao.insertUser(null);
    }
}
3.3.2 自动注入的两种方式

基于名称自动注入值

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

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

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

3.4 注解自动注入

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

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

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

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

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

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

public class User{
    @Value("1")    //注入数字
    private Integer id;
    @Value("Ziph") //注入String
    private String name;
}

SpringDI四种依赖注入方式详解的更多相关文章

  1. 转:深入浅出spring IOC中四种依赖注入方式

    转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...

  2. JAVA中的四种JSON解析方式详解

    JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...

  3. spring四种依赖注入方式(转)

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

  4. thinkphp四种url访问方式详解

    本文实例分析了thinkphp的四种url访问方式.分享给大家供大家参考.具体分析如下: 一.什么是MVC thinkphp的MVC模式非常灵活,即使只有三个中和一个也可以运行. M -Model 编 ...

  5. Spring 依赖注入方式详解(四)

    IoC 简介 平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想 ...

  6. spring IOC中四种依赖注入方式

    在spring ioc中有三种依赖注入,分别是:https://blog.csdn.net/u010800201/article/details/72674420 a.接口注入:b.setter方法注 ...

  7. spring四种依赖注入方式

    一.Set注入 这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringD ...

  8. Spring 依赖注入方式详解

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

  9. spring 四种依赖注入方式以及注解注入方式

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

随机推荐

  1. 1.二进制部署kubernetes

    目录 kubernetes的五个组件 master节点的三个组件 kube-apiserver kube-controller-manager kube-scheduler node节点的两个组件 k ...

  2. PHP丨PHP基础知识之PHP基础入门——函数「理论篇」

    前两天讲过PHP基础知识的判断条件和流程控制,今天来讲讲PHP基础知识之PHP基础入门--函数! 一.函数的声明与使用 1.函数名是标识符之一,只能有数字字母下划线,开头不能是数字. 函数名的命名,须 ...

  3. 并发编程之详解InheritableThreadLocal类原理

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 在Java并发编 ...

  4. 解决React Native安装应用到真机(红米3S)报Execution failed for task ':app:installDebug'的错误

    报错信息如下: :app:installDebug Installing APK 'app-debug.apk' on 'Redmi 3S - 6.0.1'Unable to install D:\R ...

  5. awk 命令使用入门

    Linux 下处理和分析文本文件内容,AWK 命令是一个强有力的工具.特别是文件内容是以行和列的形式排版的时候,AWK 就是命令行界的 Excel 啊! 简单的 awk 命令可以直接在命令行中使用,复 ...

  6. Python3-sys模块-解释器相关参数与函数

    Python3中的sys模块提供了访问由解释器使用和维护的一些变量和与解释器强烈交互的函数 sys.argv 获取传递给Python脚本的参数列表,sys.argv[0]代表脚本本身,sys.argv ...

  7. 在 Spring Boot 中使用 HikariCP 连接池

    上次帮小王解决了如何在 Spring Boot 中使用 JDBC 连接 MySQL 后,我就一直在等,等他问我第三个问题,比如说如何在 Spring Boot 中使用 HikariCP 连接池.但我等 ...

  8. 入门大数据---安装ClouderaManager,CDH和Impala,Hue,oozie等服务

    1.要求和支持的版本 (PS:我使用的环境,都用加粗标识了.) 1.1 支持的操作系统版本 操作系统 版本 RHEL/CentOS/OL with RHCK kernel 7.6, 7.5, 7.4, ...

  9. 并发06--JAVA中的并发工具类

    1.等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作. 使用join也可以完成这个操作,代码示例如下: package com.exam ...

  10. 019.Kubernetes二进制集群存储longhorn

    一 Longhorn存储部署 1.1 Longhorn概述 Longhorn是用于Kubernetes的开源分布式块存储系统. 提示:更多介绍参考:https://github.com/longhor ...