第四章IOC:DI、DL概念 注入的方法

 

 

 

第四章IOC概念

   本章主要介绍了IOC的概念,和通过案例演示这种依赖关系处理的各个阶段的方式来清晰的展现IOC的核心理念。第二是介绍了两种依赖注入的方法:构造器注入、setter和getter注入。

4.1-IOC概念

一、IOC的全称叫做Inversion of Control,中文通常翻译为“控制反转”。是Spring框架的核心。

    (注意:控制反转实现方式一般有两种,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。因为依赖查找使用的相对较少,我也还没有做详细的了解。这里我就只介绍依赖注入的方式)

       在面向对象的开发过程中,我们的项目中的每个类往往都有相互之间的关系,这就是它们之间的依赖。由于依赖关系越来越多所以就会造成相互间耦合程度的不断加深,会引发很多问题。如果我们把这种依赖关系交由第三方单独管理,那就相当于把这种依赖控制的权利交出去了,这中方式就是控制反转(或者叫依赖反转)。

二、下面我们通过代码的形式详细解释控制反转的具体表现形式。

      1,最原始的依赖1.0方式:

      创建一个“天猫”的商场类TMallMarket代码如下。该类提供了一个buy方法,可以从repertory中获取商品。

 

import java.util.HashMap;
import java.util.Map;

public class TMallMarket {
	
	private static Map<String, Object> repertory = new HashMap<String, Object>();
	static{
		repertory.put("IPhone6s", "IPhone6s");
		repertory.put("Mi4", "Mi4");
		repertory.put("Milk", "milks");
	}

	public Object buy(String string) {
		
		Object object = repertory.get(string);
		
		return object;
	}

}

 

         然后在创建一个人的类People代码如下。该类拥有一个TMallMarket 的成员变量。也有一个buy方法,可以通过TMallMarket 的buy方法来获取商品。这里需要注意的是,在People初始化的构造函数中创建了TMallMarket 的对象。

 

public class People {

	private TMallMarket iMarket;

	public People() {
		iMarket = new TMallMarket();
	}

	public Object buy(String goods) {

		Object object = null;
		object = iMarket.buy(goods);

		return object;
	}

}

 

         下面创建我们的测试类MainTest。通过构建People对象,调用buy方法就可以从TMallMarket 商场购买想要的商品了。但是这里我们提出一个问题,如果我现在这个想从京东上买东西,该怎么办呢?这样就会很麻烦了,添加一个京东的商场还不行,还得重新构造People类。这样的话就很麻烦了,下面我们进入接口实现方式的依赖2.0版本。

 

public class MainTest {
	
	public static void main(String[] args) {
		
		/*最原始的方式*/
		People people = new People();
		Object object =  people.buy("Mi4");
		System.out.println(object);
		
	}

}

 

        2,用接口依赖的2.0方式:

        这一次我们先创建一个“商场”的接口代码如下所示。所有集成该接口的类,都必须实现buy方法。

 

public interface IMarket {

	Object buy(String string);

}

 

        然后我们通过继承的方式创建TMallMarket类,实现基本与依赖1.0一样,只是这几集成了IMarket。

 

import java.util.HashMap;
import java.util.Map;

public class TMallMarket implements IMarket{
	
	private static Map<String, Object> repertory = new HashMap<String, Object>();
	static{
		repertory.put("IPhone6s", "IPhone6s");
		repertory.put("Mi4", "Mi4");
		repertory.put("Milk", "milks");
	}

	public Object buy(String string) {
		
		Object object = repertory.get(string);
		
		return object;
	}

}

 

        再看一下我们的People类也做了有些改变代码如下。我们在构造方法那里,将自己构建商场的方式修改为传入接口的实现类。这样在更改商场时就比较方便了。

 

public class People {

	private IMarket iMarket;

	public People(IMarket iMarket) {
		this.iMarket = iMarket;
	}

	public Object buy(String goods) {

		Object object = null;
		object = iMarket.buy(goods);

		return object;
	}

}

 

        下面我们看一下测试类代码。在创建People对象时,传入了一个IMarket接口的实现类。也就是说,如果我们现在要使用京东商场的话,只需要将京东商场的对象传递过去就可以了。这样我们就解决了依赖1.0版本中不方便更换商场的问题。

 

public class MainTest {
	
	public static void main(String[] args) {
		
		/*接口实现依赖方式*/
		IMarket iMarket = new TMallMarket();
		People people = new People(iMarket);
		Object object =  people.buy("Mi4");
		System.out.println(object);
		
	}

}

 

    3,介绍完上面的两种,我们现在进入依赖的3.0模式即IOC:

          在IOC的案例中People、IMarket、TMallMarket 三个类没有改变和依赖2.0版本的一样。首先创建自己的IOC容器代码如下。在MyIOC中有一个people 的成员变量用来存放初始化容器时存放对象。startMyIOC方法相当于启动一个IOC容器,根据转入的name参数来选择为people 对象注入那个市场。getPeoPle获得我们想要好的people 对象。

         (注意:方法中有需要传入一个name参数,这里应该是一个可以灵活配置的文件。根据你的配置来选择为People对象注入那个市场。这里为了演示的简单能够直观的展示IOC的特点,使用转入一个name来替代读入文件的方式)

 

public class MyIOC {	
	public static People people = null;
	
	public void startMyIOC(String name){
		
		if ("TMallMarket".equals(name)) {
			people = new People(new TMallMarket());
		} else if ("JingDongMarket".equals(name)) {
			people = new People(new JingDongMarket());
		}
		
	}
	
	public Object getPeople() {
		return people;
	}

}

 

         接下来在我们的测试类中看一看是如何使用我们自己定义的IOC。很明显,这种方式和我们演示spring的helloworld的时候是很相似的。看起来更加清楚,先初始化容器,在通过容器获取你需要的对象,然后使用对象。

         在这个案例中,我们将People与IMarket匹配的事情,也就是相互依赖的关系完全的交给了MyIOC来处理。这就是IOC控制反转的核心,将相互的依赖(控制)进行了反转。初次看起来好像和依赖2.0的接口没有谁什么区别,是因为我们这里案例比较简单实现的也不完善。当我开始深入接触spring之后就会感受到IOC的强大。

 

public class MainTest {
	
	public static void main(String[] args) {
		
		/*IOC实现的依赖关系*/
		//初始化IOC容器。
		MyIOC myIOC = new MyIOC();
		myIOC.startMyIOC("TMallMarket");
		//通过IOC容器获取对象和使用对象。
		People people = (People) myIOC.getPeople();
		System.out.println(people.buy("Mi4"));
	}

}

 

 

 

4.2-注入的方式

        接着上一节的IOC依赖3.0版本,介绍一下关于注入的方式。

        1,构造方法注入。

        我们看MyIOC的startMyIOC方法是使用的构造器注入,即在创建people 对象时在构造器中注入相应的依赖。

 

	public void startMyIOC(String name){
		
		if ("TMallMarket".equals(name)) {
			people = new People(new TMallMarket());
		} else if ("JingDongMarket".equals(name)) {
			people = new People(new JingDongMarket());
		}
		
	}

 

 

       2,stter和getter方法注入。

 

        首先我们改造一下People类代码如下所示。这里加入了setiMarket和getiMarket方法。提供了一个无参的构造器。接下我们在来为MyIOC添加一个新的启动方法。

 


public class People {

	private IMarket iMarket;
	
	public People() {
		// TODO Auto-generated constructor stub
	}

	public People(IMarket iMarket) {
		this.iMarket = iMarket;
	}

	public IMarket getiMarket() {
		return iMarket;
	}

	public void setiMarket(IMarket iMarket) {
		this.iMarket = iMarket;
	}

	public Object buy(String goods) {

		Object object = null;
		object = iMarket.buy(goods);

		return object;
	}

}

 

        MyIOC新加的方法如下所示。创建people 对象后通过setiMarket方法注入相应的依赖。这里只是简单的介绍了以下两种注入的方式,还有一种接口注入由于其侵入性较强已不怎么使用。

关于构造注入的优点,在于创建对象的同时,所有的依赖都会同时创建完成可以马上使用。但是当依赖较多时构造方法的参数列表可能较长,而且构造方法不能被继承无法设置默认值。

        对于stter和getter注入,其依赖的对象可以延后注入,在创建完对象后不能立即使用。但是stter和getter方法可以被继承,其依赖对象注入的时机也可以灵活选择。综合来说这种方式在一般情况下是最可取的。在spring可以更加清晰的了解这些注入方式的作用和效果这里就不再多讲了。

 

	public void startMyIOCByStter(String name){
		
		if ("TMallMarket".equals(name)) {
			people = new People();
			people.setiMarket(new TMallMarket());
		} else if ("JingDongMarket".equals(name)) {
			people = new People();
			people.setiMarket(new JingDongMarket());
		}
		
	}

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值