在Spring中,依赖注入(DI)模式实现了控制反转(IoC)原理。让我们通过一个例子来帮助理解依赖注入。我们先看到java版的例子,然后在此基础上加上spring的功能。就例子而言,是相当地简单。QuizMater接口暴露了popQuestion()方法。为了保持简单性,QuizMaster将只生成一个问题。

1
2
3
4
5
6
7
8
9
/**
 * QuizMaster.java
 */
package com.vaannila;
 
public interface QuizMaster {
 
    public String popQuestion();
}

StrutsQuizMaster和SpringQuizMaster类实现了QuizMaster接口,它们各自生成struts和spring相关的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * StrutsQuizMaster.java
 */
package com.vaannila;
 
public class StrutsQuizMaster implements QuizMaster {
 
    @Override
    public String popQuestion() {
        return "Are you new to Struts?";
    }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * SpringQuizMaster.java
 */
package com.vaannila;
 
public class SpringQuizMaster implements QuizMaster {
 
    @Override
    public String popQuestion() {
        return "Are you new to Spring?";
    }
 
}

有个QuizMasterService类向用户显示问题。QuizMasterService类关联了QuizMaster接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * QuizMasterService.java
 */
package com.vaannila;
 
public class QuizMasterService {
 
    private QuizMaster quizMaster = new SpringQuizMaster();
 
    public void askQuestion(){
        System.out.println(quizMaster.popQuestion());
    }
}

最后创建QuizProgram类来管理测验。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * QuizProgram.java
 */
package com.vaannila;
 
public class QuizProgram {
 
    public static void main(String[] args) {
        QuizMasterService quizMasterService = new QuizMasterService();
        quizMasterService.askQuestion();
    }
 
}

看上去相当的简单,我们创建了QuizMasterService类的实例,并且调用了askQuestion()方法。当你执行program,期望的“Are you new to Spring?”将从控制台打印出来。

再看看这个例子的类图。绿色箭头表示泛化,蓝色箭头表示关联。

看的出来这种结构是紧密耦合在一起的。在QuizMasterService类中创建了QuizMaster的实例,如下所示。

1
private QuizMaster quizMaster = new SpringQuizMaster();

为了测验精通struts的人,我们需要修改QuizMasterService成这样:

1
private QuizMaster quizMaster = new StrutsQuizMaster();

因此耦合性是非常高的,这就是为什么要使用依赖注入来避免这种耦合。Spring框架提供了非常强大的容器来管理组件。容器就是基于控制反转(IoC)理念并且实现了依赖注入。这些组件仅仅需要选择一种接受资源的方式,容器会自动为组件推送资源。

下面我们替换为QuizMasterService类直接创建QuizMaster对象的方式,让容器来承担这项工作。替换了硬编码,允许容器来注入需要的依赖项。

注入依赖使用setter或构造方法注入。下面看看怎样使用setter来注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * QuizMasterService.java
 */
package com.vaannila;
 
public class QuizMasterService {
 
    private QuizMaster quizMaster;
     
    public void setQuizMaster(QuizMaster quizMaster) {
        this.quizMaster = quizMaster;
    }
 
    public void askQuestion(){
        System.out.println(quizMaster.popQuestion());
    }
}

QuizMaster的值使用setQuizMaster()方法设置。在QuizMasterService类中,QuizMaster对象没有实例化,但仍然来访问它。通常这样做会抛出NullPointerException异常,但是容器已经实例化了这个对象,因此能很好的工作。

再作了这些改变之后,例子的类图就变成这样了。

图中多了容器,它帮助注入依赖项。

在beans.xml文件中的beans配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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.xsd">
 
    <bean id="springQuizMaster" class="com.vaannila.SpringQuizMaster"></bean>
    <bean id="strutsQuizMaster" class="com.vaannila.StrutsQuizMaster"></bean>
    <bean id="quizMasterService" class="com.vaannila.QuizMasterService">
 
        <property name="quizMaster">
            <ref local="springQuizMaster" />
        </property>
    </bean>
</beans>

定义每个bean使用bean标签。bean标签的id属性是获取这个bean的逻辑名,class属性表示了真实的bean类。property标签指向bean的属性。使用setter注入一个bean需要使用ref标签。

SpringQuizMaster的引用被注入到QuizMasterbean。当我们执行这个例子,控制台打印出“Are you new to Spring?”。

为了使QuizMaster问一个struts相关的问题,仅仅需要改变ref标签的指向。

1
2
3
4
5
6
<bean id="quizMasterService" class="com.vaannila.QuizMasterService">
    <property name="quizMaster">
 
        <ref local="strutsQuizMaster" />
    </property>
</bean>

依赖注入降低了组件之间的耦合。

要执行这个例子需要把如下的jar文件加大classpath。

antlr-runtime-3.0 commons-logging-1.0.4 org.springframework.asm-3.0.0.M3 org.springframework.beans-3.0.0.M3 org.springframework.context-3.0.0.M3 org.springframework.context.support-3.0.0.M3 org.springframework.core-3.0.0.M3 org.springframework.expression-3.0.0.M3

Spring IoC 使用详解的更多相关文章

  1. Spring IOC使用详解

    SpringIOC使用详解 一.IOC简介 IOC(Inversion of Control):控制反转,即对象创建的问题.通俗地讲就是把创建对象的代码交给了Spring的配置文件来进行的.这样做的优 ...

  2. Spring ——Spring IoC容器详解(图示)

    1.1 Spring IoC容器 从昨天的例子当中我们已经知道spring IoC容器的作用,它可以容纳我们所开发的各种Bean.并且我们可以从中获取各种发布在Spring IoC容器里的Bean,并 ...

  3. Spring IoC原理详解

    去掌握一门技术的时候,往往很多人都忽略了一点,只是一味地去写代码,原理层面的东西从来就不理会 还有就是学习的过程中,不去想为什么有了当前的写法,却有着这么一门技术可以代替它 一般来说,在写程序的时候, ...

  4. [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。

    一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...

  5. Spring jar包详解

    Spring jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spri ...

  6. Spring——jar包详解(转)

    Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spr ...

  7. spring注入参数详解

    spring注入参数详解 在Spring配置文件中, 用户不但可以将String, int等字面值注入到Bean中, 还可以将集合, Map等类型的数据注入到Bean中, 此外还可以注入配置文件中定义 ...

  8. Spring Boot 配置文件详解

    Spring Boot配置文件详解 Spring Boot提供了两种常用的配置文件,分别是properties文件和yml文件.他们的作用都是修改Spring Boot自动配置的默认值.相对于prop ...

  9. spring原理案例-基本项目搭建 02 spring jar包详解 spring jar包的用途

    Spring4 Jar包详解 SpringJava Spring AOP: Spring的面向切面编程,提供AOP(面向切面编程)的实现 Spring Aspects: Spring提供的对Aspec ...

随机推荐

  1. CHARINDEX函数

    CHARINDEX函数返回字符或者字符串在另一个字符串中的起始位置.CHARINDEX函数调用方法如下:    CHARINDEX ( expression1 , expression2 [ , st ...

  2. html转换成pdf

    指定html转换成pdf 安装插件: npm install --save html2canvas npm install jspdf --save 引入 plugins/ htmlToPdf.js ...

  3. java-静态-单例-继承

    概要图 一.静态 1.1 静态方法 创建对象就是为了产生实例,并进行数据的封装. 而调用功能时,确没有用到这些对象中封装的数据. 该对象的创建有意义吗?虽然可以编译并运行,但是在堆内存中空间较为浪费. ...

  4. Swift 和 Objective-C 混编后对ipa包大小的影响

    https://my.oschina.net/ilrrong/blog/800923 最近用Swift对以前写的一个应用进行重写,使用了Swift和Objective-C的混编,提交审核后发现比以前大 ...

  5. Kibana将语言设置为中文

    6.7以后系统开始支持中文了,修改语言只需要添加一行配置即可. 设置方法 在kibana.yml配置文件中添加一行配置 i18n.locale: "zh-CN" 修改后重启,可以看 ...

  6. meta标签、利用媒体查询 link不同的CSS文件

    利用媒体查询 link不同的CSS文件:<link rel="stylesheet" media="screen and (min-width:1px) and ( ...

  7. nested exception is org.hibernate.MappingException解决方案

    1.可能是因为映射文件( Order.hbm.xm)配置的class路径出错 <hibernate-mapping> <class name="com.web.bean.O ...

  8. 学习笔记(1)---matlab中常见函数解析

    一.fscanf函数 matlab中函数fscanf在文件读取方面的实例如下: 从文件中有格式地读数据 fscanf 语法1:[a,count]=fscanf(fid,format,size) 根据指 ...

  9. Vue源码探究-虚拟DOM的渲染

    Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue ...

  10. Leetcode876.Middle of the Linked List链表的中间节点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5] 输出:此列表中的结点 3 (序列化形式:[3,4 ...