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的。
好了 一眼就懂。告辞了,踢球去了