每个java应用程序都是由多个类协作才最终生成了终端用户所使用的系统.当编写复杂java应用程序的时,类之间应尽

可能保持独立,因为这样更容易做到代码的重用,也有利于单元测试的开展.spring的依赖注入功能能在保持类相互独立

的同时把他们"粘合"起来.

考虑如下场景:你的应用程序中有个文本编辑器组件,你现在想给你的文本编辑器添加拼写检查的功能.那么你可能写

出如下的代码来:

public class TextEditor {
private SpellChecker spellChecker; public TextEditor() {
spellChecker = new SpellChecker();
}
}

在上述大代码中TextEditor类中聚合了SpellChecker类,这里我们称SpellChecker为TextEditor类的依赖项.而且依

赖项实例化的工作是在TextEditor内部完成的。这种看似理所当然的代码,其实是有相当大的问题的.这里直接实例化

SpellChecker类.而在实际应用中,拼写检查工具会有不同的实现,如果我们想切换TextEditor的SpellChecker的实现

类就必须修改代码。

在使用了控制反转框架之后,写出的代码会是如下这样:

public class TextEditor {
private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}

在这段代码中SpellChecker是通过TextEditor的构造器传入的.TextEditor不必关心SpellChecker的实现.具体的实

现类是由spring容器在实例化的TextEditor的时候注入的.

由于TextEditor对依赖项SpellChecker的控制权从TextEditor转移到了spring容器,即控制权发生了反转.控制权发

生反转的方式是通过依赖注入(原理是Java的反射)来实现的.

spring中依赖注入的方式有两种:

  1. 通过bean的构造器参数进行注入
  2. 通过bean的setter方法进行依赖注入.实例化bean之后,spring容器会反射调用bean的setter方法.

下面我们将分别讲解着两种依赖注入的方式。

构造器参数进行依赖注入

使用构造器参数进行依赖注入,spring容器会在实例化bean的时候把bean的依赖项通过bean的带参的构造函数进行

注入.下面用一个例子进行演示:

1.创建包com.tutorialspoint.di,并在包内新建TextEditor.java和SpellChecker.java,内容分别如下:

TextEditor.java如下:

package com.tutorialspoint.di;

public class TextEditor {

    private SpellChecker spellChecker;

    public TextEditor(SpellChecker spellChecker) {
System.out.println("Inside TextEditor constructor.");
this.spellChecker = spellChecker;
} public void spellCheck() {
spellChecker.checkSpelling();
}
}

SpellChecker.java如下:

package com.tutorialspoint.di;

public class SpellChecker {

    public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
} public void checkSpelling() {
System.out.println("Inside checkSpelling.");
} }

2.在src目录下新建di.xml配置文件,文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="textEditor" class="com.tutorialspoint.di.TextEditor">
<constructor-arg ref="spellChecker"/>
</bean> <bean id="spellChecker" class="com.tutorialspoint.di.SpellChecker"/> </beans>

3.在包com.tutorialspoint.di中新建MainApp.java,内容如下:

package com.tutorialspoint.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("di.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); }
}

4.运行程序,检查结果:

使用构造器参数进行依赖项的注入,有时候会产生歧义.这时候可以使用type属性进行歧义的消除.

set方法依赖注入

spring也可以使用set方法进行依赖注入.当bean实例化以后,spring容器会反射调用bean实例的set方法进行依赖项

的注入.在基于xml的配置文件中可以使用bean元素的property子元素指定需要使用setter进行注入的依赖项.

下面看个例子

1.创建包com.tutorialspoint.di.setter.并在包中新建TextEditor.java和SpellChecker.java,内容分别如下:

TextEditor.java

package com.tutorialspoint.di.setter;

public class TextEditor {

    private SpellChecker spellChecker;

    public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker.");
this.spellChecker = spellChecker;
} public void spellCheck() {
spellChecker.checkSpelling();
}
}

SpellChecker.java

package com.tutorialspoint.di.setter;

public class SpellChecker {

    public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
} public void checkSpelling() {
System.out.println("Inside checkSpelling.");
} }

2.在src目录下新建di_setter.xml配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="textEditor" class="com.tutorialspoint.di.setter.TextEditor">
<property name="spellChecker" ref="spellChecker"/>
</bean> <bean id="spellChecker" class="com.tutorialspoint.di.setter.SpellChecker"/> </beans>

3.在包com.tutorialspoint.di.setter中新建MainApp.java类,内容如下:

package com.tutorialspoint.di.setter;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("di_setter.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck();
}
}

4.运行程序,检查结果:

setter方法进行依赖注入的xml配置方式支持p命名空间,使用p命名空间可以减少配置文件大小,把di_setter.xml

修改成如下内容,继续运行程序,发现结果跟上次完全一样:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="textEditor" class="com.tutorialspoint.di.setter.TextEditor" p:spellChecker-ref="spellChecker">
</bean> <bean id="spellChecker" class="com.tutorialspoint.di.setter.SpellChecker"/> </beans>

[译]12-spring依赖注入的更多相关文章

  1. Spring依赖注入 --- 简单使用说明

    Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...

  2. java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪

    前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...

  3. Spring依赖注入(IOC)那些事

    小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...

  4. Spring依赖注入三种方式详解

    在讲解Spring依赖注入之前的准备工作: 下载包含Spring的工具jar包的压缩包 解压缩下载下来的Spring压缩包文件 解压缩之后我们会看到libs文件夹下有许多jar包,而我们只需要其中的c ...

  5. Spring依赖注入:注解注入总结

    更多11   spring   依赖注入   注解   java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.S ...

  6. Spring 依赖注入,在Main方法中取得Spring控制的实例

    Spring依赖注入机制,在Main方法中通过读取配置文件,获取Spring注入的bean实例.这种应用在实训的时候,老师曾经说过这种方法,而且学Spring入门的时候都会先学会使用如何在普通的jav ...

  7. Spring依赖注入 --- 模拟实现

    Spring依赖注入 --- 模拟实现 面向接口编程,又称面向抽象编程, 数据库如果发生更改,对应的数据访问层也应该改变多写几个实现,需要用谁的时候在service里new谁就可以了面向抽象编程的好处 ...

  8. Java Web系列:Spring依赖注入基础

    一.Spring简介 1.Spring简化Java开发 Spring Framework是一个应用框架,框架一般是半成品,我们在框架的基础上可以不用每个项目自己实现架构.基础设施和常用功能性组件,而是 ...

  9. Spring依赖注入的三种方式

    看过几篇关于Spring依赖注入的文章,自己简单总结了一下,大概有三种方式: 1.自动装配 通过配置applicationContext.xml中的标签的default-autowire属性,或者标签 ...

  10. spring依赖注入源码分析和mongodb自带连接本地mongodb服务逻辑分析

    spring依赖注入本质是一个Map结构,key是beanId,value是bean对应的Object. autowired是怎么将定义的接口与对应的bean类建立联系? <bean name= ...

随机推荐

  1. Linux MySQL单实例源码编译安装5.5.32

    cmake软件 tar -zxvf cmake-2.8.8.tar.gz cd cmake-2.8.8 ./bootstrap make make install cd ../   依赖包 yum i ...

  2. hdu-2609 How many---最小表示法模板+set判重

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2609 题目大意: 有n个有01组成的字符串,每个字符串都代表一个项链,那么该字符串就是一个环状的结构 ...

  3. 木棒,POJ(1011)

    题目链接:http://poj.org/problem?id=1011 解题报告: #include <cstdio> #include <cstring> #include ...

  4. Ubuntu 18.04 一键安装深度截图工具 Deepin Screenshot

    一直在寻找Linux下的截图软件,终于发现了Deepin ScreenShot,其功能齐全,界面美观,唯一的缺点需要自己配置快捷键(后面会讲). 安装 直接在Ubuntu商店搜索“深度截图”,点击“安 ...

  5. python web应用--WSGI接口(二)

    WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求.我们来看一个最简单的Web版本的“Hello, web!”: 1 # server.py 2 # 从wsgiref模 ...

  6. android build.prop详解

    # begin build properties开始设置系统性能 # autogenerated by buildinfo.sh{通过设置形成系统信息} ro.build.id=MIUI(版本ID) ...

  7. svn更改地址怎么办

    开发过程中有时会遇到服务器更换地址的情况,比如之前地址是 svn://www.aaa.com 后来换成了 svn://www.bbb.com 这时候怎么办呢?分客户端和服务器端2种情况处理 客户端: ...

  8. [USACO07FEB]银牛派对Silver Cow Party---最短路模板题

    银牛排队 对于我这种蒟蒻来说,还是不要跑一次单元最短路.跑两次好写呀(- ̄▽ ̄)- 而题目中是有向图.如果如果按照题意进行最短路的话.就会出现一个单终点最短路和一个单起点最短路 对于单起点自然就是套模 ...

  9. 【洛谷P3390】矩阵快速幂

    矩阵快速幂 题目描述 矩阵乘法: A[n*m]*B[m*k]=C[n*k]; C[i][j]=sum(A[i][1~n]+B[1~n][j]) 为了便于赋值和定义,我们定义一个结构体储存矩阵: str ...

  10. SpringBoot学习10:springboot整合mybatis

    需求:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一个对数据库中的 t_user 表的 CRUD 的操作 1.创建maven项目,添加项目所需依赖 <!--spr ...