Java手写简单的IOC实现

一、IOC定义

    控制反转(Inversion of Control,英文缩写为IoC)。

定义很难理解,下面说下我个人的理解:

1、控制,即对象创建的控制,Java是面向对象的语言,传统的创建对象都是手动new一个对象,是由程序员自己控制的。

2、反转则是把创建对象的过程交给容器去创建。

二、思路

    既然是把创建对象交给容器去创建,那么首先我们必须要知道我们对哪些类创建对象交给容器去管理。

所以就有以下类:

①、自定义IOC注解,只有注解的才能被容器管理

②、要被容器管理的对象那些类

③、容器类,管理对象

④、容器工厂类

⑤、创建对象的类,把创建好的对象交给容器管理

⑥、扫描类,只有被扫描到的类才能被容器管理

⑦、测试类

三、源码实现

1、注解Ioc类

import java.lang.annotation.*;

/**
 * @Author: liudq
 * @Description: 自定义IOC注解
 * @Date: create in 2017/10/29 14:22
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
public @interface Ioc {
    boolean isCreate() default true;
}

2、被管理对象的类

①、学生类

/**
 * @Author: liudq
 * @Description: 学生
 * @Date: create in 2017/10/29 14:22
 */
@Ioc
public class Student<T> {

    private long id;
    private String name;
    private int age;
    private boolean sex;
    @Ioc
    private Address address;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

②、地址类

/**
 * @Author: liudq
 * @Description: 地址类
 * @Date: create in 2017/10/29 14:22
 */
@Ioc
public class Address {

    private long id;
    @Ioc
    private Province province;
    @Ioc
    private City city;
    private String detail;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Province getProvince() {
        return province;
    }

    public void setProvince(Province province) {
        this.province = province;
    }

    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }
}

③、省类

/**
 * @Author: liudq
 * @Description: 省
 * @Date: create in 2017/10/29 14:22
 */
@Ioc
public class Province {

    private long id;
    private String name;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

④、市类

/**
 * @Author: liudq
 * @Description: 市
 * @Date: create in 2017/10/29 14:22
 */
@Ioc
public class City {

    private long id;
    private String name;
    @Ioc
    private Province province;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Province getProvince() {
        return province;
    }

    public void setProvince(Province province) {
        this.province = province;
    }
}

3、容器类

/**
 * @Author: liudq
 * @Description: Bean容器
 * @Date: create in 2017/10/29 14:22
 */
public interface BeanContext {

    <T> T getBean(String name) throws Exception;

    <T> T getBean(Class<T> clz);

    <T> void addBean(Class<T> clz);

    void addBean(String clz);
}
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: liudq
 * @Description: 默认Bean容器类
 * @Date: create in 2017/10/29 14:22
 */
public class DefaultBeanContext implements BeanContext {

    private Map context = new HashMap();
    private Bean instance = new Bean();

    @Override
    public<T> T getBean(String name) {
        name = analysisName(name);
        return (T) context.get(name);
    }

    @Override
    public <T> T getBean(Class<T> clz) {
        return getBean(clz.getName());
    }

    @Override
    public <T> void addBean(Class<T> clz) {
        addBean(clz.getName());

    }

    @Override
    public void addBean(String name) {
        String key = analysisName(name);
        Object bean = context.get(key);
        if (bean == null){
            bean = instance.createObject(name);
            context.put(key,bean);
        }
    }

    public static String analysisName(String name){
        if (name == null || "".equals(name)){
            throw new NullPointerException("类名称不能为空!");
        }
        String[] split = name.split("\\.");
        if (split != null && split.length > 0){
            String s = split[split.length - 1];
            String first = s.substring(0,1).toLowerCase();
            String end = s.substring(1,s.length());
            return first+end;
        }
        String first = name.substring(0,1).toLowerCase();
        String end = name.substring(1,name.length());
        return first+end;
    }
}

4、容器工厂类

/**
 * @Author: liudq
 * @Description: Bean容器工厂类
 * @Date: create in 2017/10/29 14:22
 */
public class BeanContextFactory {

    private static BeanContext beanContext = new DefaultBeanContext();

    public static BeanContext createBeanContext(){
        return beanContext;
    }
}

5、创建对象的类

import java.lang.reflect.Constructor;
import java.util.*;

/**
 * @Author: liudq
 * @Description: 创建bean
 * @Date: create in 2017/10/29 14:22
 */
public class Bean {

    public <T> T createObject(Class<T> clz){
        return createObject(clz,null,null);
    }

    public <T> T createObject(Class<T> clz, List<Class<?>> constructTypes, List<Object> constructArgs){
        Class<?> aClass = resolveInterface(clz);
        return (T)instance(aClass, constructTypes, constructArgs);
    }

    public Object createObject(String name) {
        Object o = null;
        try {
            Class<?> aClass = Class.forName(name);
            o = aClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

    protected <T> T instance(Class<T> clz, List<Class<?>> constructTypes, List constructArgs) {
        try {
            Constructor<T> constructor;
            if (constructTypes == null || constructArgs == null){
                constructor = clz.getDeclaredConstructor();
                return constructor.newInstance();
            }
            constructor = clz.getDeclaredConstructor(constructTypes.toArray(new Class[constructArgs.size()]));
            return constructor.newInstance(constructArgs.toArray(new Object[constructArgs.size()]));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建对象异常");
        }
    }

    protected Class<?> resolveInterface(Class<?> type) {
        Class<?> classToCreate;
        if (type == List.class || type == Collection.class || type == Iterable.class) {
            classToCreate = ArrayList.class;
        } else if (type == Map.class) {
            classToCreate = HashMap.class;
        } else if (type == SortedSet.class) { 
            classToCreate = TreeSet.class;
        } else if (type == Set.class) {
            classToCreate = HashSet.class;
        } else {
            classToCreate = type;
        }
        return classToCreate;
    }
}

6、扫描类

import java.lang.reflect.Field;

/**
 * @Author: liudq
 * @Description: 扫描Bean
 * @Date: create in 2017/10/29 14:22
 */
public class Scan {

    private BeanContext beanContext;

    public Scan(BeanContext beanContext){
        this.beanContext = beanContext;
    }

    public BeanContext getBeanContext() {
        return beanContext;
    }

    public void setBeanContext(BeanContext beanContext) {
        this.beanContext = beanContext;
    }

    public void scan(Class<?> clz ){
        scan(new Class[]{clz});
    }

    public void scan(Class<?>[] clzs){
        for (Class clz : clzs){
            Ioc ioc = (Ioc) clz.getAnnotation(Ioc.class);
            if (ioc != null){
                if (ioc.isCreate()){
                    beanContext.addBean(clz);
                    System.out.println("类"+clz.getName()+" 被注册");
                }
            }
            Field[] declaredFields = clz.getDeclaredFields();
            if (declaredFields != null){
                for (Field field : declaredFields){
                    Ioc annotation = field.getAnnotation(Ioc.class);
                    if (annotation != null){
                        if (annotation.isCreate()){
                            Class<?> fieldType = field.getType();
                            beanContext.addBean(fieldType);
                            System.out.println(clz.getName()+"里的"+field.getName()+"字段的类型"+fieldType.getName()+" 被注册");
                            try {
                                field.setAccessible(true);
                                field.set(beanContext.getBean(clz),beanContext.getBean(fieldType));
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }
}

7、测试类

/**
 * @Author: liudq
 * @Description: 测试
 * @Date: create in 2017/10/29 14:22
 */
public class App {

    public static void main(String[] args) {
        BeanContext beanContext = BeanContextFactory.createBeanContext();
        Scan scan = new Scan(beanContext);
        scan.scan(new Class[]{Student.class,Address.class,Province.class,City.class});
        Student student = beanContext.getBean(Student.class);
        System.out.println(student.getAddress().getProvince().getName());
    }
}

四、目的

IOC的主要目的是解耦合。

五、浅谈

    这里只是一个简单的IOC的实现,主要技术是Java的反射。希望有助于大家对IOC的理解。

实践是检验真理的唯一标准。只有我们自己多敲代码多测试才能加深我们对程序的理解。

 

转载于:https://my.oschina.net/u/920156/blog/1557833

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值