spring第二个特性是依赖注入。

学习依赖注入,首先应该明白两个问题:1,谁依赖谁;2,谁注入,注入什么?

首先还是看代码:

还是这个bean:

package testSpring.business.bean;

import org.springframework.stereotype.Repository;

import testSpring.business.iface.IPrint;

/**
 *  UserBean :
 * @author xuejupo  jpxue@travelsky.com
 * create in 2016-2-16 上午9:22:39
 */
public class UserBean implements IPrint{
    @Override
    public String printObject() {
        // TODO Auto-generated method stub
        System.out.println("打印对象UserBean:");
        return "abc";
    }

}

然后,我的业务逻辑需要在这个bean里使用上边那个bean:

package testSpring.business.impl;

import testSpring.business.iface.IPrint;

/**
 *  Print :
 * @author xuejupo  jpxue@travelsky.com
 * create in 2016-2-16 上午10:23:37
 */

public class Print {
    //需要打印的bean,注入的入口(需要注入的对象)
    private IPrint printBean;
    private String name;
    public void print(){
        System.out.println("注入的name:"+name);
        this.printBean.printObject();
    }

    /**
    * setPrintBean: set方法,set注入必备方法
    * @param printBean
    * void  返回类型
    */
    public void setPrintBean(IPrint printBean){
        this.printBean = printBean;
    }

    /**
    * setName: set方法,set注入必备方法
    * @param name
    * void  返回类型
    */
    public void setName(String name){
        this.name = name;
    }
}

普通的使用print类的客户端代码:

Print p = new Print();
p.setPrintBean(new UserBean());
print.print();

也是挺简单的代码,但是,客户端代码就和具体的类print和userbean的代码强耦合在一块了,不符合开闭原则,所以就需要利用依赖注入往客户端代码中注入Pring对象,往Print类中注入Userbean对象。

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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    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.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <context:annotation-config/>
    <!-- 注册javabean -->
    <bean id="userBean" class="testSpring.business.bean.MyBean" />

    <!-- 注册javabean -->
    <bean id="printBean" class="testSpring.business.impl.Print" >
    <!-- 注入javabean中的参数 -->
        <property name = "printBean" ref = "userBean"></property>
        <property name = "name" value = "haha"></property>
    </bean>
</beans>

客户端代码:

//读取配置文件(将配置文件中的bean加载进内存)
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/testSpring/resources/applicationContext.xml");
        //获取的实例
        Print bean=(Print)ctx.getBean("printBean");
        //调用方法
        bean.print();

打印结果:

注入的name:haha
打印对象MyBean:

可以看到,利用xml的配置信息,在客户端代码中不用具体new任何的java对象了,java对象的创建工作,和对象中元素的赋值工作可以交给xml(spring)处理。

回答文中开头两个问题:1.客户端代码中,具体对象的创建依赖于xml文件(spring,即IOC容器);2.是IOC容器注入,在运行期,根据xml的配置信息,将具体的对象注入到相应的bean中。

说一下自己理解中的IOC容器: 网上搜过,没有什么让我满意的回答,只能自己理解一下。我理解的IOC容器,其实就是web服务启动后,tomcat(或其他的web服务器)加载applicationContext.xml(注册bean的spring配置文件),会在内存中开辟一块内存区域专门存储在xml文件中加载的bean,并且是以map映射的形式存储的,key是id,value就是具体的bean。这块内存区域,用于存储bean的容器,就叫IOC容器(其实更应该叫spring的bean容器)(个人理解,实在找不到对这个定义比较好的解释,只能先这么理解了)。

如果看过我前一篇博客的,肯定会说依赖注入和控制反转这不一样嘛。。。。他俩确实是一回事。。。依赖注入也可以叫控制反转,就是将控制权交给配置文件。。   不过我个人喜欢这样理解:对bean的注册叫控制反转,对bean中参数的初始化叫依赖注入。个人觉得,知道是一回事就行,怎么容易让你理解怎么来。

说一下依赖注入的好处:

最主要的还是解耦。便于数据源的切换:比如我想在print类里打印另一个bean,只需要修改xml文件即可。

这说的还是有点虚,可能真实环境更能说明问题:   公司最近遇到一个需求,需要两拨人共同开发:一波开发公司内网接口---A组,一波开发公司对外实现(相当于客户端)---B组。客户端开发是依赖于内网功能的,但是又不能等待内网的同学先开发完,所以领导决定:A组的人,先把需要实现的功能,以接口(interface)的方式暴漏给B组的同学,然后两组各自为政,开发完以后合并就行了。

假设A组暴漏了一个接口如下:

public interface MyInterface{
        void myMethod();
}

但是A组这个接口的实现还没写,所以我B组的人想用这个接口编程,两个办法(我是菜鸟,可能有别的办法,可以指点):

第一:

MyInterface  bean = null;//这里需要后期填充具体接口实现

然后,当A组的把实现给我们之后,我们再通过全局搜索,把bean全都赋值给具体的实现。这时候,万一A组的人脑子一抽,说哎呀,我给你的实现不对,是应该给C组的,你用另一个,那我又要全局修改所有的代码。。。。(这就是强耦合,A组修改代码,会导致B组人代码必须修改)

然后,第二种是酱:

用一个配置文件:

<bean id="myInterface" class="xxx.xxx.xxx.xxxx" />
<!-- 注册我的javabean -->
    <bean id="printBean" class="testSpring.business.impl.Print" >
    <!-- 注入接口实现 -->
        <property name = "myInterface" ref = "myInterface"></property>
    </bean>

然后在我已经注册的javaBean里只需要这样:

private MyInterface myInterface;

就可以使用接口的具体实现了,而且无论你A组怎么改,我B组的代码不用修改,只改配置文件就行(当然,前提是A组的接口不能变),这就是弱耦合,也是设计原则里面著名的依赖倒置原则(依赖接口而不依赖于具体实现)。

spring学习(二)---依赖注入的更多相关文章

  1. Spring 学习之依赖注入

    什么是依赖关系? 纵观所有的Java 应用,从基于Applet的小应用到多层次结构的企业级别的应用,他们都是一种典型的依赖性应用,也就是由一些互相协作的对象构成的,Spring把这种互相协作的关系称之 ...

  2. spring学习之依赖注入DI与控制反转IOC

    一 Ioc基础 1.什么是Ioc? Ioc(Inversion of Control)既控制反转,Ioc不是一种技术,而是一种思想,在Java开发中意味着将设计好的对象交给容器来进行控制,并不是像传统 ...

  3. Spring 学习笔记 ----依赖注入

    依赖注入 有三种方式,本文只学习下属性注入. 属性注入       属性注入即通过 setXxx方法()注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入方式是 ...

  4. Spring学习笔记--依赖注入

    依赖注入和控制反转:http://baitai.iteye.com/blog/792980出自李刚<轻量级 Java EE 企业应用实战> Java应用是一种典型的依赖型应用,它就是由一些 ...

  5. Spring学习(一)---依赖注入和控制反转

    Spring Spring是一个从实际开发中抽出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率. Spring为企业应用的开发提供 ...

  6. spring学习 五 依赖注入的方式

    依赖注入有两种方式: 1 构造注入,如果<bean>标签下使用<contructor-arg>,则是构造注入 2 setter注入,就是调用setter方法注入,如果<b ...

  7. Spring学习——DI(依赖注入)

    IOC容器,处理对象依赖关系 IOC与DI: IOC :是一个容器,创建对象的容器 DI :在容器创建对象后,处理对象的依赖关系,也叫依赖注入! 方式1:通过set方法注入值 可以给普通属性.集合属性 ...

  8. Spring学习--泛型依赖注入

    暂时没有搞懂.

  9. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  10. Spring学习(一)——Spring中的依赖注入简介【转】

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

随机推荐

  1. tomcat 配置细节

    1.对于url中文乱码问题: (有时进行url编码也不能能够解决,找到server.xml添加URIEncoding="UTF-8",就可以了) tomcat配置编码:      ...

  2. sublime_text3代码自动补全

    因为项目需要用sublime_text3编辑器,安装之后代码自动补全功能没有,这比较苦恼. 其实蛮简单的 英文界面:menu->Preferences->Setting-User-> ...

  3. jquery中checkbox的选中,反选,全不选 注意1.6版本以上将attr改成prop

    <script type="text/javascript"> $(function () { // 全选 $("#btnCheckAll").bi ...

  4. 深入理解C++11【3】

    [深入理解C++11[3]] 1.POD类型 Plain Old Data. Plain 表示 了POD是个普通的类型.C++11将POD划分为两个基本概念的合集: 1)平凡的(trivial) 2) ...

  5. ajax请求aspx.cs后台方法

    前台jquery代码 $(function () { $("#btnfix").click(function () { $.ajax({ type: "post" ...

  6. 解题(DirGraCheckPath--有向图的遍历(深度搜索))

    题目描述 对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径. 给定图中的两个结点的指针DirectedGraphNode* a, DirectedGraphNode* b(请不要在意数据类 ...

  7. 既然还看不到未来之光,那就从骄阳开始的地方--IT携行

    对于还没真正踏入IT的小白菜来说,哪有资格把刚学到的鸡毛蒜皮儿,三脚猫都不算的东西逮出来献丑,献丑都不算,还不如我们来谈谈人生,练练脸皮...... 我出发的起点肯定不同,多方限制,可能缺乏时光;那正 ...

  8. hibernate多生成一个外键以及映射文件中含有<list-index>标签

    (原文地址: http://blog.csdn.net/xiaoxian8023/article/details/15380529) 一.Inverse是hibernate双向关系中的基本概念.inv ...

  9. select简单循环嵌套

    访问学生的物理最高成绩,并且打印出来,单个要打印出所有的信息 在添加几个 and 就可以啦. select  student.gender,student.sname from student whe ...

  10. java Graphics2D drawString()内容换行问题

    //字符串总宽度 private int getStringLength(Graphics g,String str) { char[] strcha=str.toCharArray(); int s ...