目录

 

 

基本认识

实例

自己的感悟


 

基本认识

Ioc:Inversion of Control 控制反转、依赖注入

控制:控制对象(Java Bean)的创建以及销毁(生命周期)
反转:将对象的控制权交给IoC容器

 

下面例子围绕这三点:

          1. 所有的Bean的生命周期交由IoC容器管理;

          2. 所有被依赖的Bean通过构造方法执行注入;

          3.  被依赖的Bean需要优先创建;

 

实例

程序的运行截图如下:

Audi是张三开的,Buick是李四开的!

程序结构如下:

源码如下:

Audi.java

package ioc.demo.IocDemo.car;

public class Audi implements Car {

    public void start(){

        System.out.println("Audi. start");
    }

    public void turnLeft(){

        System.out.println("Audi. turnLeft");
    }

    public void turnRight(){

        System.out.println("Audi. turnRight");
    }

    public void stop(){

        System.out.println("Audi. stop");
    }
}

buick.java

package ioc.demo.IocDemo.car;

public class Buick implements Car {

    public void start(){

        System.out.println("Buick. start");
    }

    public void turnLeft(){

        System.out.println("Buick. turnLeft");
    }

    public void turnRight(){

        System.out.println("Buick. turnRight");
    }

    public void stop(){

        System.out.println("Buick. stop");
    }
}

Car.java
 

package ioc.demo.IocDemo.car;

public interface Car {

    public void start();
    public void turnLeft();
    public void turnRight();
    public void stop();
}

Humen.java

package ioc.demo.IocDemo.humen;

public interface Humen {

    public void goHome();
}

HumenWithCar.java

package ioc.demo.IocDemo.humen;

import ioc.demo.IocDemo.car.Car;

public abstract class HumenWithCar implements Humen{

    protected Car car;

    public HumenWithCar(Car car){

        this.car = car;
    }

    public abstract void goHome();
}

LiSi.java
 

package ioc.demo.IocDemo.humen;

import ioc.demo.IocDemo.car.Car;

public class LiSi extends HumenWithCar{
    public LiSi(Car car) {
        super(car);
    }

    @Override
    public void goHome() {

        car.start();
        car.stop();;
    }
}

ZhangSan.java

package ioc.demo.IocDemo.humen;


import ioc.demo.IocDemo.car.Car;

public class ZhangSan extends HumenWithCar{


    public ZhangSan(Car car){

        super(car);
    }

    @Override
    public void goHome() {

        car.start();
        car.turnLeft();
        car.turnRight();
        car.stop();

    }
}

IoCContainer.java

package ioc.demo.IocDemo;

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> 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 setBeans(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 ioc.demo;

import ioc.demo.IocDemo.IoCContainer;
import ioc.demo.IocDemo.car.Audi;
import ioc.demo.IocDemo.car.Buick;
import ioc.demo.IocDemo.humen.Humen;
import ioc.demo.IocDemo.humen.LiSi;
import ioc.demo.IocDemo.humen.ZhangSan;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    private IoCContainer ioCContainer = new IoCContainer();

    @Before
    public void before(){   //创建Bean和使用Bean是两个不同的业务逻辑

        ioCContainer.setBeans(Audi.class, "audi");
        ioCContainer.setBeans(Buick.class, "Buick");
        ioCContainer.setBeans(ZhangSan.class, "ZhangSan", "audi");
        ioCContainer.setBeans(LiSi.class, "LiSi", "Buick");
        ioCContainer.setBeans(Audi.class, "audi");
    }

    @Test
    public void contextLoads() {

        Humen zhangesan = (Humen) ioCContainer.getBean("ZhangSan");
        zhangesan.goHome();
        Humen liSi = (Humen) ioCContainer.getBean("LiSi");
        liSi.goHome();

    }

}

 

自己的感悟

这里发现一个东西,Java因为有反射机制,所以可以使用IoC的思想,实现控制翻转,依赖注入,这个是C++做不到的,在程序的逻辑结构,和设计上,这种方式的确是相当的好!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐