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