手写Ioc容器

Ioc:Inversion of Control的缩写,控制反转、依赖注入。

1.控制的是:java bean的创建与销毁,也就是 生命周期

2.反转的是:将对象的控制权交给了Ioc容器。

 

下面我将通过一个demo,简单实现ioc。场景:我有2辆车,我要开车回家。车的功能有启动、左转、右转、停车。

1.首先有一个人类接口:他有回家这个方法定义。

package com.lengyao.human;

public interface Human {
	public void gohome();
}

2.然后是有车一族的:

package com.lengyao.human;

import com.lengyao.ioc.Car;

public abstract  class HumanWithCar implements Human{

	protected Car car;
	
	public  HumanWithCar(Car car) {
		this.car = car;
	}
	
	@Override
	public abstract void gohome();
	
}

3.然后是我的:

package com.lengyao.human;

import com.lengyao.ioc.Car;

public class Lengyao extends HumanWithCar{
	
	public Lengyao(Car car) {
		super(car);
	}
	@Override
	public void gohome() {
		car.start();
		car.turnLeft();
		car.turnRight();
		car.stop();
	}

}

4:car接口,他有启动、左转、右转、停车

package com.lengyao.ioc;

public interface Car {
	public void start();
	public void turnLeft();
	public void turnRight();
	public void stop();
}

5:有一辆宝马

package com.lengyao.ioc;

public class Bmw implements Car {
	@Override
	public void start() {
		System.out.println("BMW启动");
		
	}

	@Override
	public void turnLeft() {
		System.out.println("BMW左转");
		
	}

	@Override
	public void turnRight() {
		System.out.println("BMW右转");
		
	}

	@Override
	public void stop() {
		System.out.println("BMW停车");
		
	}
}

6:有一辆奔驰

package com.lengyao.ioc;

public class Benz implements Car {

	@Override
	public void start() {
		System.out.println("奔驰启动");
		
	}

	@Override
	public void turnLeft() {
		System.out.println("奔驰左转");
		
	}

	@Override
	public void turnRight() {
		System.out.println("奔驰右转");
		
	}

	@Override
	public void stop() {
		System.out.println("奔驰停车");
		
	}

	

}

7:开始写ioc容器:

( 1.实例化bean
 2。保存bean
 3.提供bean
 4.每一个bean要产生一个唯一的id与之对应)

package com.lengyao.ioc;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 1.实例化bean
 2。保存bean
 3.提供bean
 4.每一个bean要产生一个唯一的id与之对应
 */
public class Ioccontainer {
   private Map<String,Object> beanMap = new ConcurrentHashMap<>();
   
   //1.获取一个bean
   public Object getBean(String beanId) {
	   return beanMap.get(beanId);
   }
   /**
    * 2.委托ioc 容器创建一个bean
    * @param clazz 需要船舰bean的class
    * @param beanId 
    * @param paramBeanIds bean构造方法所需要的参数beanId
    */
   public void setBean(Class<?> clazz,String beanId,String... paramBeanIds) {
	   //1,组装构造方法的参数值
	   Object [] paramValues = new Object[paramBeanIds.length];
	   for(int i=0;i<paramBeanIds.length;i++) {
		   paramValues[i] = beanMap.get(paramBeanIds[i]);
	   }
	   //2.调用构造方法实例化bean
	   Object bean =null;
	   for(Constructor<?> constructor:clazz.getConstructors()) {
		   try {
			bean = constructor.newInstance(paramValues);
		} catch (InstantiationException e) {
		} catch (IllegalAccessException e) {
		} catch (IllegalArgumentException e) {
		} catch (InvocationTargetException e) {
		}
	   }
	   
	   if(bean == null) {
		   throw new RuntimeException("找不到合适的构造方法");
	   }
	   //3.将实例化的bean放入beanMap
	   beanMap.put(beanId, bean);
	   
   }
   
}

8:测试一下

package com.lengyao;

import javax.management.MXBean;

import com.lengyao.human.Human;
import com.lengyao.human.Lengyao;
import com.lengyao.ioc.Benz;
import com.lengyao.ioc.Bmw;
import com.lengyao.ioc.Ioccontainer;

public class Test {

	
	
	public static void main(String [] args) {
		Ioccontainer ioccontainer = new Ioccontainer();
		ioccontainer.setBean(Benz.class, "benz");
		ioccontainer.setBean(Bmw.class, "bmw");
		ioccontainer.setBean(Lengyao.class, "lengyao", "benz");
		
		Human lengyao = (Human) ioccontainer.getBean("lengyao");
		lengyao.gohome();
	}
}

运行结果:

如果我把测试类的奔驰换成宝马  

都是ok的。

好了  一眼就懂。告辞了,踢球去了

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值