上一章,我们写了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。
下一篇终于轮到重头戏——实现依赖注入了。