在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。

Spring依赖注入(DI)的三种方式,分别为:

1.  Setter方法注入

2.  构造方法注入

3.  接口注入

下面介绍一下这三种依赖注入在Spring中是怎么样实现的。

Setter方法注入

首先我们需要以下几个类:

接口 Logic.java

接口实现类 LogicImpl.java

一个处理类 LoginAction.java

还有一个测试类 TestMain.java

Logic.java如下:

<span style="font-size:18px;"><span style="font-size:18px;">package DI;
//定义接口
public interface Logic {
public String getName();
}
</span></span>

LogicImpl.java如下:

<span style="font-size:18px;"><span style="font-size:18px;">package DI;

public class LogicImpl implements Logic {
//实现类 public String getName() { return "lishehe";
} }
</span></span>

LoginAction.java 会根据使用不同的注入方法而稍有不同

Setter方法注入:

<span style="font-size:18px;"><span style="font-size:18px;">package DI;

public class LoginAction {
private Logic logic; public void execute() { String name = logic.getName(); System.out.print("My Name Is " + name); } /** * @return the logic */ public Logic getLogic() { return logic; } /** * @param logic * the logic to set */ public void setLogic(Logic logic) { this.logic = logic; }
}
</span></span>

客户端测试类

TestMain.java

<span style="font-size:18px;">package DI;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext; public class TestMain { /** * @param args */ public static void main(String[] args) { // 得到ApplicationContext对象 ApplicationContext ctx = new FileSystemXmlApplicationContext( "applicationContext.xml"); // 得到Bean LoginAction loginAction = (LoginAction) ctx.getBean("loginAction"); loginAction.execute(); }
}
</span>

定义了一个Logic 类型的变量 logic, 在LoginAction并没有对logic 进行实例化,而只有他对应的setter/getter方法,因为我们这里使用的是Spring的依赖注入的方式

applicationContext.xml配置文件如下:

<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>

<!--
- Application context definition for JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="logic" class="DI.LogicImpl"/> <bean id="loginAction" class="DI.LoginAction"> <property name="logic" ref="logic"></property> </bean> </beans>
</span>

运行效果:

构造器注入

顾名思义,构造方法注入,就是我们依靠LoginAction的构造方法来达到DI的目的,如下所示:

<span style="font-size:18px;">package DI;

public class LoginAction {

	 private Logic logic;

	    public LoginAction(Logic logic) {

	       this.logic = logic;

	    }

	    public void execute() {

	       String name = logic.getName();

	       System.out.print("My Name Is " + name);

	    }

}
</span>

里我们添加了一个LoginAction的构造方法

applicationContext.xml配置文件如下:

<span style="font-size:18px;">	<bean id="logic" class="DI.LogicImpl"/>

<bean id="loginAction" class="DI.LoginAction">

 <constructor-arg index="0" ref="logic"></constructor-arg>

</bean></span>

我们使用constructor-arg来进行配置,
index属性是用来表示构造方法中参数的顺序的,如果有多个参数,则按照顺序,从 0,1...来配置

我们现在可以运行testMain.java了,结果跟使用Setter方法注入完全一样.

效果图

其中需要注意一点有:构造函数有多个参数的话,如:参数1,参数2,而参数2依赖于参数1,这中情况则要注意构造函数的顺序,必须将参数1放在参数2之前。

接口注入

下面继续说说我们不常用到的接口注入,还是以LogicAction为例,我们对他进行了修改,如下所示:

LogicAction.java

<span style="font-size:18px;">package DI;

public class LoginAction {

	private Logic logic;

    public void execute() {

       try {

           Object obj = Class.forName("DI.LogicImpl")

                  .newInstance();

           logic = (Logic) obj;

           String name = logic.getName();

           System.out.print("My Name Is " + name);

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

}
</span>

配置文件:

<span style="font-size:18px;"><bean id="logic" class="DI.LogicImpl"/>

<bean id="loginAction" class="DI.LoginAction"></span>

效果图

总结

对于Spring的依赖注入,最重要的就是理解他的,一旦理解了,将会觉得非常的简单。无非就是让容器来给我们实例化那些类,我们要做的就是给容器提供这个接口,这个接口就我们的set方法或者构造函数了。

SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式的更多相关文章

  1. SSH深度历险记(八) 剖析SSH核心原则+Spring依赖注入的三种方式

           于java发育.一类程序猿必须依靠类的其他方法,它是通常new依赖类的方法,然后调用类的实例,这样的发展问题new良好的班统一管理的例子.spring提出了依赖注入的思想,即依赖类不由程 ...

  2. SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

    接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...

  3. SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

    AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...

  4. 30个类手写Spring核心原理之依赖注入功能(3)

    本文节选自<Spring 5核心原理> 在之前的源码分析中我们已经了解到,依赖注入(DI)的入口是getBean()方法,前面的IoC手写部分基本流程已通.先在GPApplicationC ...

  5. java核心知识点----创建线程的第三种方式 Callable 和 Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

  6. (转)编码剖析Spring依赖注入的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...

  7. 【SSH进阶之路】Spring的IOC逐层深入——依赖注入的两种实现类型(四)

    上篇博文,我们介绍了为什么使用IOC容器,和IOC的设计思想以及IOC容器的优缺点,并且给大家转载了一篇介绍IOC原理的博文,我们这篇主要给大家依赖注入的两种方式,以及他们的优缺点. 我们这篇博文还是 ...

  8. SSH深度历险(六) 深入浅出----- Spring事务配置的五种方式

    这对时间在学习SSH中Spring架构,Spring的事务配置做了详细总结,在此之间对Spring的事务配置只是停留在听说的阶段,总结一下,整体把控,通过这次的学习发觉Spring的事务配置只要把思路 ...

  9. Spring、Spring依赖注入与编码剖析Spring依赖注入的原理

    Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...

随机推荐

  1. poj3580 splay树 REVOVLE循环

    SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12795   Accepted: 3989 Case T ...

  2. 07_Linux目录文件操作命令4解压缩,文件查找_我的Linux之路

    这一节还是一样学习操作目录文件的命令 在这一节,我会讲到解压压缩tar以及zip命令,以及文本查找命令grep tar 打包压缩命令 tar命令可以为linux的文件和目录创建档案 首先要弄清两个概念 ...

  3. Nginx+Tomca+Redis实现负载均衡、资源分离、session共享

    目标实现:Nginx作为负载均衡后端多Tomcat实例,通过Redis实现Session共享. 操作系统环境:CentOS 6.8 SSH:SecureCRT 其中 Nginx服务:80端口 Tomc ...

  4. string转换为guid类型 split

    string str = "{"+context.Request["ID"]+"}"; KpiUser.ID = new Guid(str) ...

  5. ASP.NET Core部署到Windows IIS

    网上已经有许多ASP.NET Core关于Widows IIS部署的文章,在部署到服务器时遇到了一些问题,在这里我就不再对原理进行阐释(复制)了,只写下一些关键环节,想看原理的同学请参考官网,此文章作 ...

  6. WebApplicationContext类的作用

    WebApplicationContext是实现ApplicationContext接口的子类.是专门为WEB应用准备的.作用: 1.它允许从相对于Web根目录的路径中加载配置文件完成初始化工作.从W ...

  7. 利用mybatis-generator自动生成数据持久化的代码

    MyBatis生成器简介 MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器.它将生成所有版本的MyBatis的代码,以及版本2.2.0之后的iB ...

  8. 数据库4m10d作业

    Create table student ( Sno char(15) primary key , Sname varchar(10) not null, Sage tinyint , Special ...

  9. 如果将Joomla网站搜索结果显示到一个“干净”页面

    有时候大家会发现Joomla网站自带的或者第三方的搜索功能时,搜索结果会显示在首页,和首页其它的模块如图片橱窗等显示在一起,非常混乱. 在这里教大家一个不需要修改代码的小技巧来解决这个问题,使搜索结果 ...

  10. JS判断PC还是移动端打开网页

    最近在做移动端网站,也需兼容PC端.还没找到更好的方法,只能用javascr判断用户是在PC端打开还是移动端打开. JS判断 var isPC = function (){    var userAg ...