SpringIOC控制反转

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

/**
 * QuizMaster.java
 */
package com.vaannila;
 
public interface QuizMaster {
 
    public String popQuestion();
}

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

/**
 * StrutsQuizMaster.java
 */
package com.vaannila;
 
public class StrutsQuizMaster implements QuizMaster {
 
    @Override
    public String popQuestion() {
        return "Are you new to Struts?";
    }
 
}

/**
 * SpringQuizMaster.java
 */
package com.vaannila;
 
public class SpringQuizMaster implements QuizMaster {
 
    @Override
    public String popQuestion() {
        return "Are you new to Spring?";
    }
 
}

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

/**
 * QuizMasterService.java
 */
package com.vaannila;
 
public class QuizMasterService {
 
    private QuizMaster quizMaster = new SpringQuizMaster();
 
    public void askQuestion(){
        System.out.println(quizMaster.popQuestion());
    }
}

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

/**
 * 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的实例,如下所示。

private QuizMaster quizMaster = new SpringQuizMaster();

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

private QuizMaster quizMaster = new StrutsQuizMaster();

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

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

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

/**
 * 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配置:

<?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标签的指向。

<bean id="quizMasterService" class="com.vaannila.QuizMasterService">
    <property name="quizMaster">
 
        <ref local="strutsQuizMaster" />
    </property>
</bean>

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

时间: 2024-10-31 03:19:16

SpringIOC控制反转的相关文章

2-形象理解SpringIOC(控制反转)

通过一个学生选择课程的demo 以3中不同的实现方式理解一下springIOC,体会IOC的好处: 声明一个ICourse接口: package org.ks.newinstance; public interface ICourse { void learn(); //学习.... } 两个ICourse接口的实现类:JavaCourse.java  ,   HtmlCourse.java package org.ks.newinstance; public class JavaCourse

轻松了解Spring中的控制反转和依赖注入(二)

紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类之间的结构图如下 以下是代码 BeanFactor接口:在Spring源码中的定义是:持有对一定数量的Bean的定义,同时每个Bean都被唯一标识的对象(类),需要实现这个接口.根据对Bean的定义,该工厂将会返回一个包含Bean定义的对象的独立实例(原型设计模式),或者单例共享(一个不错的单例设计模式,)范

Spring控制反转(IOC)

SpringIOC Spring的控制反转:把对象的创建.初始化.销毁等工作交给spring容器来做.由spring容器控制对象的生命周期. 步骤:两个步骤,步骤1有两个加载配置文件形式,通过加载配置文件实例化容器 IOC面向接口的强大 Spring容器内部对象 创建对象的方式 无参构造函数 <bean id="personService" class="cn.itcast.bean.impl.PersonServiceImpl"/> 静态工厂 工厂方法

iOS控制反转(IoC)与依赖注入(DI)的实现

背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大的方便,要在OC上较好的实现这两个功能,需要一些小小的技巧. 控制反转和依赖注入 控制反转 简单来说,将一个类对象的创建由手动new方式改为从IOC容器内获取,就是一种控制反转,例如我们现在要创建一个ClassA类,则常规方法为 ClassA *a = [ClassA new]; 如果使用控制反转,

工厂模式、控制反转及依赖注入

在介绍工厂模式与控制反转(Inversion of Control)及依赖注入(Dependency Injection)之前,先介绍下类的调用方法.目前调用方法总共有3种:1.自己创建:2.工厂模式:3.外部注入,其中外部注入即为控制反转/依赖注入模式(IoC/DI).我们可以用3个形象的东西来分别表示它们,就是new.get.set.顾名思义,new表示自己创建,get表示主动去取(即工厂),set表示是被别人送进来的(即注入),其中get和set分别表示了主动去取和等待送来两种截然相反的特

谈谈php里的IOC控制反转,DI依赖注入

理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(Inversion of Control,缩写为IoC):是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度. 依赖注入(Dependency Injection,简称DI):DI是IOC的一种实现,表现为:在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属

浅谈依赖注入与控制反转

前言:设计模式其实是一个很空洞的东西,设计模式有几十种,有些人觉得工厂模式也单例模式已经足够解决大部分问题.而有些人觉得任何设计模式都会让开发变得更“复杂”,更“低效”.所以千万不要太过追求他的实际意义和作用,否则你已经坠入云雾.但是不管怎么样,实际工作中还是要对它们有所了解,下面从php的角度来讲一下依赖注入.控制反转.反射等概念.如有错误之处,还望路过大神多加指点 首先设定场景,假如一个类需要数据库连接,最简单的做法可能是: class example { private $_db; fun

Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)

一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对 象无须关心持久层对象的具体实现,各层对象的调用完全面向接口.当系统需要重构时,代码的改写量将大大减少. 上面所说的一切都得宜于Spring的核心机制,依赖注入.依赖注入让bean与

spring2.5IOC控制反转详解

spring2.5IOC控制反转详解 19. 五 / J2EE / 一条评论 基本的代码结构 1 IOC包下 基本的spring创建对象 将类添加到配置文件中,由容器创建. Source code     <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="