依赖注入(Dependency Injection,DI)和控制反转含义相同,它们是从两个角度描述的同一个概念。
当某个 Java 实例需要另一个 Java 实例时,传统的方法是由调用者创建被调用者的实例(例如,使用 new 关键字获得被调用者实例),而使用 Spring 框架后,被调用者的实例不再由调用者创建,而是由 Spring 容器创建,这称为控制反转。
Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring 容器获得被调用者实例,这称为依赖注入。
依赖注入主要有两种实现方式,分别是属性 setter 注入和构造方法注入。具体介绍如下。
1)属性 setter 注入
指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。
2)构造方法注入
指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。
下面通过属性 setter 注入的案例演示 Spring 容器是如何实现依赖注入的。具体步骤如下。
1. 创建 PersonService 接口
在 springDemo01 项目的 com.mengma.ioc 包下创建一个名为 PersonService 的接口,该接口中包含一个 addPerson() 方法,如下所示。
package com.mengma.ioc;
public interface PersonService {
public void addPerson();
}
2. 创建接口实现类 PersonServiceImpl
在 com.mengma.ioc 包下创建一个名为 PersonServiceImpl 的类,该类实现了 PersonService 接口,如下所示。
package com.mengma.ioc;
public class PersonServiceImpl implements PersonService {
// 定义接口声明
private PersonDao personDao;
// 提供set()方法,用于依赖注入
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
// 实现PersonService接口的方法
@Override
public void addPerson() {
personDao.add(); // 调用PersonDao中的add()方法
System.out.println("addPerson()执行了...");
}
}
首先声明了 personDao 对象,并为其添加 setter 方法,用于依赖注入,然后实现了 PersonDao 接口的 addPerson() 方法,并在方法中调用 save() 方法和输出一条语句。
3. 在 applicationContext.xml 中添加配置信息
在 applicationContext.xml 配置文件中添加一个 <bean> 元素,用于实例化 PersonServiceImpl 类,并将 personDao 的实例注入到 personService 中,其实现代码如下所示:
<bean id="personService" class="com.mengma.ioc.PersonServiceImpl">
<!-- 将personDao实例注入personService实例中 -->
<property name="personDao" ref="personDao"/>
</bean>
4. 编写测试方法
在 FirstTest 类中创建一个名为 test2() 的方法,编辑后如下所示:
@Test
public void test2() {
// 定义Spring配置文件的路径
String xmlPath = "applicationContext.xml";
// 初始化Spring容器,加载配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
xmlPath);
// 通过容器获取personService实例
PersonService personService = (PersonService) applicationContext
.getBean("personService");
// 调用personService的addPerson()方法
personService.addPerson();
}
5. 运行项目并查看结果
使用 JUnit 测试运行 test2() 方法,运行成功后,控制台的输出结果如图 。

可以看出,使用 Spring 容器获取 userService 的实例后,调用了该实例的 addPerson() 方法,在该方法中又调用了 PersonDao 实现类中的 add() 方法,并输出了结果。这就是 Spring 容器属性 setter 注入的方式,也是实际开发中较为常用的一种方式。

吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring DI(依赖注入)的实现方式属性注入和构造注入的更多相关文章

  1. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:继承的应用

    class Array{ // 表示数组 private int temp[] ; // 整型数组 private int foot ; // 定义添加位置 public Array(int len) ...

  2. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:匿名内部类

    interface A{ public void printInfo() ; // } class B implements A{ // 实现接口 public void printInfo(){ S ...

  3. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:包装类

    public class WrapperDemo01{ public static void main(String args[]){ int x = 30 ; // 基本数据类型 Integer i ...

  4. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:Object类

    class Demo{ // 定义Demo类,实际上就是继承了Object类 }; public class ObjectDemo01{ public static void main(String ...

  5. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:宠物商店实例分析

    interface Pet{ // 定义宠物接口 public String getName() ; public String getColor() ; public int getAge() ; ...

  6. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:抽象类与接口的应用

    abstract class A{ // 定义抽象类A public abstract void print() ; // 定义抽象方法print() }; class B extends A { / ...

  7. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:instanceof关键字

    class A{ // 定义类A public void fun1(){ // 定义fun1()方法 System.out.println("A --> public void fun ...

  8. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:对象的多态性

    class A{ // 定义类A public void fun1(){ // 定义fun1()方法 System.out.println("A --> public void fun ...

  9. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:接口的基本实现

    interface A{ // 定义接口A public static final String AUTHOR = "李兴华" ; // 全局常量 public abstract ...

  10. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:final关键字

    final class A{ // 使用final定义类,不能有子类 }; class B extends A{ // 错误,不能被继承 }; class A{ public final void p ...

随机推荐

  1. SQLSERVER|CDC 日志变更捕获机制

    先说一下什么是cdc ,cdc 变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入.更新和删除活动.SQLServer的操作会写日志,这也是CD ...

  2. blog编辑技巧

    blog里添加目录 添加版权声明 其他 更新日志: 20190719, 添加目录,增加章节:[添加版权声明] blog里添加目录 https://szosoft.blogspot.com/需要使用绝对 ...

  3. docker安装centos7镜像

    拉取centos7镜像[root@localhost ~]# docker pull centos:71启动镜像centos7,如果不指定 /bin/bash,容器运行后会自动停止[root@loca ...

  4. DIV 透明度 设置

    filter:alpha(opacity=70); -moz-opacity:0.70;-khtml-opacity: 0.70;   opacity: 0.70;

  5. Kafka--生产者

    一个应用程序在很多情况下需要往Kafka写入消息:记录用户的活动(用于审计和分析),记录度量指标,保存日志消息,记录智能家电的信息,与其他应用程序进行异步通信,缓冲即将写入到数据库的数据,等等. 多样 ...

  6. Node.js 加载静态资源css,js等不显示问题的解决方法

    一,原因 1,没有响应到css等文件 2,响应类型是由文件的后缀名决定 (1)html的请求头 Content-Type : text/html ; charset=utf-8 (2) CSS的请求头 ...

  7. jquery实现常用UI布局

    tab html <div class="tab"> <ul class="tab-title"> <li class=" ...

  8. 75.Python中ORM聚合函数详解:Sum

    Sum:某个字段的总和. 1. 求图书的销售总额,示例代码如下: from django.http import HttpResponse from django.db import connecti ...

  9. React 学习笔记(2) 路由和UI组件使用

    安装依赖 cnpm install react-router-dom -S // 或 yarn add react-router-dom 导入 // index.js import React fro ...

  10. webapi------宿主程序

    业务场景: 公司的容器程序需要给前端暴露接口但是代码里面又不想写webapi项目工程就用到了宿主可以达到webapi的效果 1.owin实现 2.其他实现 测试实现如下 1.新建一个控制台程序 2.新 ...