【從零寫javaweb框架】(四)實現Bean容器

上一章,我們寫了ClassUtil類,用於提供與類操作相關的方法,然後又寫了Controller/Service註解來標識框架要加載的類,Action用於標識Controller裏的方法,Inject用於實現依賴注入,最後再寫了一個ClassHelper來實行Bean類的加載和存取。【從零寫javaweb框架】(三)開發一個類加載器

本章我們會寫一個Bean的容器,用來實例化和保存Bean。


本篇操作都在框架項目中

首先,爲了方便實例化,我們先寫一個反射工具類ReflectionUtil:

package org.smart4j.framework.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * desc : 反射工具類
 * Created by Lon on 2018/1/24.
 */
public final class ReflectionUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ReflectionUtil.class);

    /**
     * 創建實例
     */
    public static Object newInstance(Class<?> cls){
        Object instance;
        try {
            instance = cls.newInstance();
        } catch (Exception e){
            LOGGER.error("new instance failure", e);
            throw new RuntimeException(e);
        }
        return instance;
    }

    /**
     * 調用方法
     */
    public static Object invokeMethod(Object obj, Method method, Object... args){
        Object result;
        try {
            //設置成可調用私有方法
            method.setAccessible(true);
            result = method.invoke(obj, args);
        } catch (Exception e){
            LOGGER.error("invoke method failure", e);
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 設置成員變量的值
     */
    public static void setField(Object obj, Field field, Object value){
        try {
            //設置成可訪問私有成員變量
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e){
            LOGGER.error("set field failure", e);
            throw new RuntimeException(e);
        }
    }

}


然後,再寫一個真正用來實例化Bean和管理Bean的類BeanHelper:

package org.smart4j.framework.helper;

import org.smart4j.framework.util.ReflectionUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * desc : Bean助手類
 * Created by Lon on 2018/1/25.
 */
public final class BeanHelper {

    /**
     * 定義Bean映射,用於維護和保存Bean類與Bean實例的關係
     */
    private static final Map<Class<?>, Object> BEAN_MAP = new HashMap<Class<?>, Object>();

    static {
        Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet();
        for (Class<?> beanClass : beanClassSet){
            Object obj = ReflectionUtil.newInstance(beanClass);
            BEAN_MAP.put(beanClass, obj);
        }
    }

    /**
     * 獲取Bean映射
     */
    public static Map<Class<?>, Object> getBeanMap(){
        return BEAN_MAP;
    }

    /**
     * 獲取Bean實例
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> cls){
        if (!BEAN_MAP.containsKey(cls)){
            throw new RuntimeException("can not get bean by class " + cls);
        }
        return (T)BEAN_MAP.get(cls);
    }

}


最後附上框架結構圖:



總結:

這篇篇幅比較少,主要寫了一個方便反射的工具類ReflectionUtil,和一個用來實例化和保存Bean的容器BeanHelper。

下一篇終於輪到重頭戲——實現依賴注入了。

【從零寫javaweb框架】(五)實現依賴注入功能



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章