上一章,我們寫了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。
下一篇終於輪到重頭戲——實現依賴注入了。