Spring IoC的实现方案

  • 1. IoC的定义
  • 2. IoC的作用
  • 3. 实现IOC的思路
  • 4. 实现代码
  • 4.1 代码层级
  • 4.2 工厂的实现 - BeanFactory
  • 4.3 配置文件 - beans.yml
  • 4.4 测试类
  • 4.5 其他补充
  • 5. 总结


1. IoC的定义

inversion of control,控制反转,是一种思想。控制反转思想的两种实现类型:依赖注入(Depedency Injection)和依赖查找(Dependency Lookup)。

2. IoC的作用

消减计算机程序的耦合程度。

3. 实现IOC的思路

使用反射+配置文件,确定最终的实现类。
使用工厂模式,降低程序耦合度。

4. 实现代码

4.1 代码层级

Ioc实现方式java 实现ioc的方式_Ioc实现方式java

4.2 工厂的实现 - BeanFactory

package com.fftest.spring;

import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Set;

public class BeanFactory {

    private static HashMap<String, Object> beanMap = new HashMap<String, Object>();

    static {
        try {
            // 获取yml配置文件
            YamlReader beansYaml = new YamlReader(new FileReader(System.getProperty("beanspath") + "beans.yml"));
            // 读取yml配置文件的内容并转换成Map
            HashMap<String, String> beansMap = (HashMap<String, String>) beansYaml.read();

            // 遍历Map的内容并反射创建对象,将创建好的对象存入全局变量beanMap中
            Set<String> keys = beansMap.keySet();
            for (String key : keys) {
                String clazz = beansMap.get(key);
                Object newInstance = Class.forName(clazz).newInstance();
                beanMap.put(key, newInstance);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (YamlException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    public static Object getBeanImplName(String bean) {
        return beanMap.get(bean);
    }
}

4.3 配置文件 - beans.yml

Car:
  com.fftest.spring.impl.BMW
Customer:
  com.fftest.spring.impl.RichMan

4.4 测试类

package com.fftest.spring.testcase;

import com.fftest.spring.BeanFactory;
import com.fftest.spring.Car;
import com.fftest.spring.Customer;
import org.junit.Test;

public class BeanFactoryTest {

    @Test
    public void getBeanImplNameTest() {
        System.setProperty("beanspath", "/Users/faye/IdeaProjects/hello-spring/target/classes/");

        Car car = (Car) BeanFactory.getBeanImplName("Car");
        Customer customer = (Customer) BeanFactory.getBeanImplName("Customer");

        System.out.println("Car model: " + car.getModel());
        System.out.println("Car price: " + car.getPrice());

        System.out.println("Customer name: " + customer.getName());
        System.out.println("Customer is VIP: " + customer.isVIP());
    }
}

打印结果

Car model: BMW
Car price: 520000
Customer name: Mr Lee
Customer is VIP: true

4.5 其他补充

引入依赖

<dependency>
            <groupId>com.esotericsoftware.yamlbeans</groupId>
            <artifactId>yamlbeans</artifactId>
            <version>1.08</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

BMW的实现

package com.fftest.spring.impl;

import com.fftest.spring.Car;

public class BMW implements Car {

    public String getModel() {
        return this.getClass().getSimpleName();
    }

    public int getPrice() {
        return 520000;
    }
}

RichMan的实现

package com.fftest.spring.impl;

import com.fftest.spring.Customer;

public class RichMan implements Customer {

    public String getName() {
        return "Mr Lee";
    }

    public boolean isVIP() {
        return true;
    }
}

5. 总结

IoC的作用是解耦,解耦的思路有 2 个问题需要解决:

  • bean存在哪里?

分析:由于我们一个项目中有很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。到底选 Map 还是 List 就看我们有没有查找需求。有查找需求(因为Map是key-value结构,可以很方便通过key来获取值,也就是方便查找),选 Map。所以我们的答案就是在应用加载时,创建一个 Map,用于存放对象。我们把这个 map 称之为容器。

  • 怎么去获取对象?

需要提供一个方法,根据不同的内容创建对象,考虑用工厂模式。
工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:我们在获取对象时,都是采用 new 的方式。 是主动的。
现在:我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。 是被动的。
以这种被动接收的方式获取对象的思想就是控制反转。