Java手寫簡單的IOC實現

1、IOC定義java

    控制反轉(Inversion of Control,英文縮寫爲IoC)。程序員

定義很難理解,下面說下我我的的理解:ide

一、控制,即對象建立的控制,Java是面向對象的語言,傳統的建立對象都是手動new一個對象,是由程序員本身控制的。測試

二、反轉則是把建立對象的過程交給容器去建立。this

2、思路對象

    既然是把建立對象交給容器去建立,那麼首先咱們必需要知道咱們對哪些類建立對象交給容器去管理。ip

因此就有如下類:ci

①、自定義IOC註解,只有註解的才能被容器管理get

②、要被容器管理的對象那些類源碼

③、容器類,管理對象

④、容器工廠類

⑤、建立對象的類,把建立好的對象交給容器管理

⑥、掃描類,只有被掃描到的類才能被容器管理

⑦、測試類

3、源碼實現

一、註解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;
}

二、被管理對象的類

①、學生類

/**
 * @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;
    }
}

三、容器類

/**
 * @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;
    }
}

四、容器工廠類

/**
 * @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;
    }
}

五、建立對象的類

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;
    }
}

六、掃描類

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();
                            }
                        }
                    }
                }
            }
        }
    }
}

七、測試類

/**
 * @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());
    }
}

4、目的

IOC的主要目的是解耦合。

5、淺談

    這裏只是一個簡單的IOC的實現,主要技術是Java的反射。但願有助於你們對IOC的理解。

實踐是檢驗真理的惟一標準。只有咱們本身多敲代碼多測試才能加深咱們對程序的理解。

相關文章
相關標籤/搜索