简单代码实现IOC

IOC:Inversion of Control,控制反转 ,依赖注入。

什么是IOC:

1.控制什么?
控制对象的创建及销毁(生命周期)
2.反转什么?
将对象的控制权交给IOC容器

假如有一个人张三 有一辆车
他要回家 他对这辆车参数依赖关系(所以有以下三步)
1.创建一辆车
2.控制车辆启动,直行,左右转
3.销毁车辆(垃圾回收)

这样代码耦合性太高,会导致牵一发而动全身的问题,稍加改动,代码结构就会很大的改动。
所以提出了ioc容器这一概念

ioc容器的四个功能:

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

我们这里假设一个任务场景,某个人要开车。

实现ioc

先建Car这个接口,这个接口表明的汽车的几个操作

package com.springioc.car;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:22
 */
public interface Car {
    public void start();
    public void turnLeft();
    public void turnRight();
    public void stop();
}

创建Audi,Buick并实现Car接口

package com.springioc.car;

public class Audi implements Car{
    @Override
    public void start(){
        System.out.println("Audi.start");
    }
    @Override
    public void turnLeft(){
        System.out.println("Audi.turnLeft");
    }
    @Override
    public void turnRight(){
        System.out.println("Audi.turnRight");
    }
    @Override
    public void stop(){
        System.out.println("Audi.stop");
    }
}
package com.springioc.car;

public class Buick implements Car{
    @Override
    public void start(){
        System.out.println("Buick.start");
    }
    @Override
    public void turnLeft(){
        System.out.println("Buick.turnLeft");
    }
    @Override
    public void turnRight(){
        System.out.println("Buick.turnRight");
    }
    @Override
    public void stop(){
        System.out.println("Buick.stop");
    }
}

接下来实现Humen接口

package com.springioc.humen;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:24
 */
public interface Humen {
    public void goHome();
}

HumenWithCar抽象类(目的是实现Humen接口)

package com.springioc.humen;

import com.springioc.car.Car;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:24
 */
public abstract class HumenWithCar implements Humen{
    protected Car car;

    public HumenWithCar(Car car) {
        this.car = car;
    }

    @Override
    public abstract void goHome();
}

分别实现张三 李四

package com.springioc.humen;

import com.springioc.car.Car;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:26
 */
public class ZhangSan extends HumenWithCar {
    public ZhangSan(Car car) {
        super(car);
    }

    @Override
    public void goHome() {
        car.start();
        car.turnLeft();
        car.turnRight();
        car.start();
    }
}
package com.springioc.humen;

import com.springioc.car.Car;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:27
 */
public class LiSi extends HumenWithCar {
    public LiSi(Car car) {
        super(car);
    }

    @Override
    public void goHome() {
        car.start();
        car.stop();
    }
}

重点 编写ioc容器(要用到反射中的知识)

package com.springioc;

/**
 * @Author: zty
 * @Date: 2020/3/17 13:28
 */

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 {
    //保存bean
    private Map<String,Object> beans = new ConcurrentHashMap<String, Object>();

    /**
     * 根据beanId获取一个bean
     * @param beanId
     * @return 返回bean
     */
    public Object getBean(String beanId){
        return beans.get(beanId);
    }

    /**
     * 委托ioc容器创建一个bean
     * @param clazz 要创建的bean的class
     * @param beanId beanId
     * @param paramBeanIds 要创建的bean的class的构造方法所需要的参数的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] = beans.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 (InvocationTargetException e) {
            }
        }
        if(bean == null){
            throw new RuntimeException("找不到合适的构造方法去实例化bean");
        }
        //3.将实例化的bean放入beans
        beans.put(beanId,bean);
    }
}

测试

package com.springioc;

import com.springioc.car.Audi;
import com.springioc.car.Buick;
import com.springioc.humen.Humen;
import com.springioc.humen.LiSi;
import com.springioc.humen.ZhangSan;
import org.junit.Before;
import org.junit.Test;

public class IocApplicationTests {

    private IoCContainer ioCContainer = new IoCContainer();

   
    @Before
    public void before(){
        ioCContainer.setBean(Audi.class,"audi");
        ioCContainer.setBean(Buick.class,"buick");
        ioCContainer.setBean(ZhangSan.class,"zhangsan","audi");
        ioCContainer.setBean(LiSi.class,"lisi","buick");
    }
    @Test
    public void contextLoads() {
        Humen zhangsan = (Humen) ioCContainer.getBean("zhangsan");
        zhangsan.goHome();
        Humen lisi = (Humen) ioCContainer.getBean("lisi");
        lisi.goHome();
    }

}

IOC的优点

 *  所有的依赖关系都被集中统一的管理起来,清晰明了

 *  每个类只需要关注于自己的业务逻辑

 *  修改依赖关系是很容易的
发布了22 篇原创文章 · 获赞 28 · 访问量 2650

猜你喜欢

转载自blog.csdn.net/qq_43561507/article/details/104930888
今日推荐