`

Spring基本用法1——Spring的核心机制:IOC、DI

阅读更多

        前言:一直想写一个关于Spring的系列文章,但是构思许久却不知道以什么方式阐述,毕竟要把一个复杂框架说清楚并不是那么容易的,我也只能尽力而为了。Spring系列文章打算以这样的顺序展开:以思维导图的方式统筹介绍Spring -> 介绍Spring基本用法 -> 深入使用Spring -> 窥探Spring源码 -> 如有必要以思维导图总结概述Spring。本文介绍Spring基本用法,目的更多的是入门Spring的使用方法,demo、附件项目更是快速查询Spring基本用法的工具。

本篇文章重点关注以下问题:

  • 概述Spring核心功能
  • IOC、DI基本概念
  • 两种依赖注入的方式

1. Spring核心功能

        Spring是一个非常活跃的开源框架,它以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”,甚至在项目开发过程中,你完全没感到Spring在发挥作用。

       Spring框架的核心功能有两个

  • 一是Spring容器作为超级工厂,负责创建、管理所有的java对象,这些java对象称为Bean。(IOC实现)
  • 二是Spring容器管理Bean之间的依赖关系。(DI实现)

2. IOC、DI基本概念

        IOC:即控制反转,把对象的创建、初始化、销毁等工作交给spring容器来做,由spring容器控制对象的生命周期。

* 控制:就是指对对象的创建、维护、销毁等生命周期的控制,这个过程一般是由我    
        们的程序去主动控制的,如使用new关键字去创建一个对象(创建),在使  
        用过程中保持引用(维护),在失去全部引用后由GC去回收对象(销  
        毁)。   
* 反转:就是指对对象的创建、维护、销毁等生命周期的控制由程序控制改为由IOC  
        容器控制,需要某个对象时就直接通过名字去IOC容器中获取。  

         

         DI:即依赖注入,是IOC的一种重要实现,与IOC描述的是同一个概念。

        一个对象的创建往往会涉及到其他对象的创建,比如一个对象A的成员变量持有着另一个对象B的引用,这就是依赖,A依赖于B。IOC机制既然负责了对象的创建,那么这个依赖关系也就必须由IOC容器负责起来。负责的方式就是DI——依赖注入,通过将依赖关系写入配置文件,然后在创建有依赖关系的对象时,由IOC容器注入依赖的对象,如在创建A时,检查到有依赖关系,IOC容器就把A依赖的对象B创建后注入到A中(组装,通过反射机制实现),然后把A返回给对象请求者,完成工作。

       其工作过程如下图所示:


        对应于Spring的两个核心功能,程序员所要做的工作就两点:

  • 一是开发Bean:Spring建议面向接口编程,java对象间的耦合仅在接口层面,无需关心服务的具体实现;
  • 二是配置Bean:通过xml配置文件或注解的方式告知Spring,需要Spring管理哪些Bean,以及Bean之间的依赖关系;

        在需要使用Bean时,直接从容器中去拿即可。

3. 依赖注入的方式

         依赖注入(DI)通常有如下两种方式:

  • 设值注入:IOC容器使用成员变量的setter方法来注入被依赖对象;
  • 构造注入:IOC容器使用构造器来注入被依赖对象。

3.1 设值注入

       设值注入:IOC容器使用成员变量的setter方法来注入被依赖对象。

     开发过程如下:(此处以xml配置文件的形式说明)

步骤一:开发Bean
       定义服务类接口:

            * Pen.java:用于实现签名功能;

            * Person.java:需要使用Pen来签名,即Person.java依赖于Pen.java

       实现服务类功能:

            * BallpointPen.java:提供用圆珠笔实现签名的功能;

            * Pencil.java:提供用铅笔实现签名的功能;

            * Chinese.java:Person的子类,表示中国人来签名;

 

          Chinese.java代码如下,类中需要定义Pen接口对象的成员变量pen,并提供其setter方法,用于设值注入: 

package com.wj.chapter1.ioc.setter.xml.Service;  
  
import com.wj.chapter1.ioc.setter.xml.IService.Pen;  
import com.wj.chapter1.ioc.setter.xml.IService.Person;  
  
public class Chinese implements Person {  
  
    private Pen pen;    /** 代码耦合的层次仅限于接口层次. */  
      
    // 设值需要的setter方法  
    public void setPen(Pen pen) {  
        this.pen = pen;  
    }  
  
    @Override  
    public void signOwnName() {  
        pen.signName("中国人");  
    }  
  
}  

  步骤二:配置Bean

 

        通过xml配置文件的方式告知Spring,需要Spring管理哪些Bean,以及Bean之间的依赖关系。

 

<?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-4.3.xsd">  
      
    <!-- 设值注入(XML方式):通过成员变量的setter方法注入被依赖对象. -->  
    <!-- 属性id    : Bean在Spring容器中的唯一标识.      -->  
    <!-- 属性class : 指定该Bean的具体实现类,而不能是接口.  -->  
    <bean id="chinese"      class="com.wj.chapter1.ioc.setter.xml.Service.Chinese">  
        <!-- 驱动调用chinese的setPen()方法,将容器中pencil(或ballpointPen)作为传入参数 -->  
        <!-- property子节点指明依赖关系 -->  
        <property name="pen" ref="pencil"></property>  
    </bean>  
      
    <!-- 定义Pen.class的两个实现类Bean. -->  
    <bean id="pencil"       class="com.wj.chapter1.ioc.setter.xml.Service.Pencil"></bean>  
    <bean id="ballpointPen" class="com.wj.chapter1.ioc.setter.xml.Service.BallpointPen"></bean>  
</beans> 

         xml配置文件中,每个Bean对应Spring容器里的一个java实例,property节点元素指明Bean之间的依赖关系。

 

步骤三:调用Bean

      使用前面定义的服务,实现中国人用铅笔签名的功能:

 

package com.wj.chapter1.ioc.setter.xml.main;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
import com.wj.chapter1.ioc.setter.xml.IService.Person;  
  
public class Main {  
      
    // 1.指明xml配置文件位置,便于Spring读取,从而知道Bean的相关信息  
    private static final String PATH_XML = "com/wj/chapter1/ioc/setter/xml/applicationContext-setter.xml";  
  
    @SuppressWarnings("resource")  
    public static void main(String[] args) {  
        // 2.根据xml配置文件,创建Spring IOC容器的上下文  
        ApplicationContext cxt     = new ClassPathXmlApplicationContext(PATH_XML);  
          
        // 3.在需要使用服务的时候,直接从Spring容器中获取  
        Person             chinese = cxt.getBean("chinese", Person.class);  
          
        // 4.获取提供服务的对象后,调用Bean的服务  
        chinese.signOwnName();  
    }  
}  

  步骤四:查看调用结果

3.2 构造注入

       构造注入:IOC容器使用构造器来注入被依赖对象。

     开发过程如下:(此处以xml配置文件的形式说明)

步骤一:开发Bean

      定义服务类接口:

            * Pen.java:用于实现签名功能;

            * Person.java:需要使用Pen来签名,即Person.java依赖于Pen.java

      实现服务类功能:

            * BallpointPen.java:提供用圆珠笔实现签名的功能;

            * Pencil.java:提供用铅笔实现签名的功能;

            * Chinese.java:Person的子类,表示中国人来签名;

 

      Chinese.java代码如下,类中需要定义Pen接口对象的成员变量pen,并提供带参数的构造函数,用于构造注入:

 

package com.wj.chapter1.ioc.constructor.xml.Service;  
  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Pen;  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Person;  
  
public class Chinese implements Person {  
  
    private Pen pen;    /** 代码耦合的层次仅限于接口层次. */  
      
    // 构造注入所需的带参数的构造器  
    public Chinese(Pen pen) {  
        this.pen = pen;  
    }  
  
    @Override  
    public void signOwnName() {  
        pen.signName("中国人");  
    }  
} 

 步骤二:配置Bean

 

        通过xml配置文件的方式告知Spring,需要Spring管理哪些Bean,以及Bean之间的依赖关系。

 

<?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-4.3.xsd">  
      
    <!-- 构造注入(XML方式):通过调用构造函数注入被依赖对象. -->  
    <!-- 属性id    : Bean在Spring容器中的唯一标识.      -->  
    <!-- 属性class : 指定该Bean的具体实现类,而不能是接口.  -->  
    <bean id="chinese"      class="com.wj.chapter1.ioc.constructor.xml.Service.Chinese">  
        <!-- 下面只有一个constructor-arg子元素,驱动Spring调用Chinese带一个参数的构造器来创建对象 -->  
        <constructor-arg name="pen" ref="ballpointPen" index="0"></constructor-arg>  
    </bean>  
    <bean id="pencil"       class="com.wj.chapter1.ioc.constructor.xml.Service.Pencil"></bean>  
    <bean id="ballpointPen" class="com.wj.chapter1.ioc.constructor.xml.Service.BallpointPen"></bean>  
      
</beans>

 步骤三:调用Bean

        使用前面定义的服务,实现中国人用圆珠笔签名的功能:

package com.wj.chapter1.ioc.constructor.xml.main;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
import com.wj.chapter1.ioc.constructor.xml.Iservice.Person;  
  
public class Main {  
      
    // 1.指明xml配置文件位置,便于Spring读取,从而知道Bean的相关信息  
    private static final String PATH_XML = "com/wj/chapter1/ioc/constructor/xml/applicationContext-constructor.xml";  
  
    @SuppressWarnings("resource")  
    public static void main(String[] args) {  
        // 2.根据xml配置文件,创建Spring IOC容器的上下文  
        ApplicationContext cxt     = new ClassPathXmlApplicationContext(PATH_XML);  
          
        // 3.在需要使用服务的时候,直接从Spring容器中获取  
        Person             chinese = cxt.getBean("chinese", Person.class);  
          
        // 4.获取提供服务的对象后,调用Bean的服务  
        chinese.signOwnName();  
    }  
}  

 步骤四:查看调用结果

3.3 两种注入方式的对比

      建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,可以考虑采用构造注入,其他依赖关系的注入,则尽量用设值注入。

  • 大小: 13.7 KB
  • 大小: 29.1 KB
  • 大小: 12.3 KB
  • 大小: 22.3 KB
  • 大小: 13 KB
分享到:
评论

相关推荐

    springIOC核心组件分析.vsdx

    spring-core:核心模块 依赖注入IOC和DI的最基本实现 spring-beans:Bean工厂与装配 spring-context:上下文,即IOC容器 spring-context-support:对IOC的扩展,以及IOC子容器 spring-context-indexer:类管理组件和...

    Spring——DI和通过注解实现IOC和DI

    DI(依赖注入) – 问题的提出: 之前所说的IOC,其中没有提到,如果当spring保存的类中有其他属性需要赋值的话怎么办(其实可以用工厂模式来完成),所以今天我们...– 注入方法1——set注入 注入普通属性: 配置文件

    springIOC和DI

    什么是spring,spring核心,spring优点,spring体系结构, 入门案例,DI基础,核心API,文档内附代码

    使用Java的xml API、Java反射技术演示Spring的DI或者IoC原理

    环境:windowx XP professional、 JDk 1.6、 Eclipse 3.3 ...4. 看一下testDemoSpringDI()方法,完成模拟Srping的DI机制与IoC容器。 学习对象:给学习Spring技术学员,并且想知道DI与IoC原理的人。

    spring核心IOC以及DI

    1.spring入门学习 2.spring的ioc容器原理

    Spring——IOC(控制反转)与DI(依赖注入).docx

    IOC与DI的理解及使用 控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IOC的一种方法 。... 在Spring中实现控制反转的是IOC容器 ,其 实现方法是依赖注入 (Dependency Injection,DI)

    跟我学spring3(1-7)

    【第二章】 IoC 之 2.2 IoC 容器基本原理 ——跟我学Spring3 【第二章】 IoC 之 2.3 IoC的配置使用——跟我学Spring3 【第三章】 DI 之 3.1 DI的配置使用 ——跟我学spring3 【第三章】 DI 之 3.2 循环依赖 ——跟我...

    spring ioc di aop详解

    spring ioc di aop详解

    Springioc注入Demo

    详细讲解了springioc的各种注入方式以及对应的java方式。讲解了springioc和DI的区别,以及注入特殊复杂的属性

    什么是Ioc和DI

    什么是Ioc和DI

    简洁版的spring ioc自行实现 研究spring 加载机制

    简洁版的spring ioc自行实现,不到10个类,描述了加载机制,是研究IOC DI的好材料,能够了解IOC原理。目标是了解基本原理,所以没考虑循环引用的情况 完整的ECLIPSE工程,直接导入就可使用。 里面有测试例子,单步...

    Spring从入门到入土——依赖注入(DI)

    Spring从入门到入土——概述以及IOC理论推导 Spring从入门到入土——快速上手Spring Spring从入门到入土——依赖注入(DI) Spring从入门到入土——Bean的作用域 Dependency Injection 概念 依赖注入(DI) 依赖:指...

    spring-struts1-strust2-hibernate 核心包介绍

    这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。 (2) spring-beans.jar 这个jar文件是所有应用...

    Spring IOC AOP MVC 简单例子

    Spring IOC AOP MVC 简单例子

    关于spring的AOP ,IOC,DI的理解

    帮助初学者理解spring框架,有助于提高代码能力java.sql.SQLException: Duplicate entry '2' for key 'PRIMARY' Query: insert into transaction values(?,?,?,?,?) Parameters: [2, 6212999999999, 转出, 6000000, ...

    springioc和spring aop

    控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找...

    Spring相关设计思想解析IOC DI DL DP.doc

    Java Spring相关设计思想解析IOC DI DL DP

    手写IOC项目,学习理解Spring IOC原理

    我们都知道,Spring框架的IOC是基于Java的反射机制实现,实现IOC,...IOC和DI是Spring里面最核心的东西,,资源中会写出这两个模块。资源内容包括Java反射机制的实践,使用反射机制实现IOC(包括依赖注入和对象创建)。

    SpringIOC,DI+dynamic proxy 实现盗版AOP

    SpringIOC,DI+dynamic proxy 实现盗版AOP的源代码

    Spring从入门到入土——Bean的作用域

    Spring从入门到入土——依赖注入(DI) Spring从入门到入土——Bean的作用域 Bean的作用域 ​ 在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始...

Global site tag (gtag.js) - Google Analytics