从0开始写JavaWeb框架系列(3)从0开始写SamrtFrameWork:实现Bean容器

1、实现Bean实例容器。java

    1.一、编写一个ClassHelper类能够获取全部加载的类,可是没法经过类来实例化对象。所以,须要提供一个反射工具类,封装反射的API,提供更便捷的工具方法。就叫作ReflectionUtil.java。工具

package org.smart4j.framework.util;


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

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

/**
 * 反射工具类 
 * @author Admin
 *
 */
public final class ReflectionUtil {

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

	/**
	 * 建立实例
	 * @param cls
	 * @return
	 */
	public static Object getInstance(Class<?> cls){
		Object instance;
		try {
			instance = cls.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			LOGGER.error("new instance failure",e);
			throw new RuntimeException(e);
		}
		return instance;
	}

	/**
	 * 调用方法
	 * @param obj
	 * @param method
	 * @param args
	 * @return
	 */
	public static Object invokeMethod(Object obj,Method method,Object ...args){
		Object result;
		try {
			method.setAccessible(true);
			result = method.invoke(obj, args);
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			LOGGER.error("invoke method failure",e);
			throw new RuntimeException(e);
		}

		return result;

	}


	/**
	 * 设置成员变量的值
	 * @param obj
	 * @param field
	 * @param value
	 */
	public static void setField(Object obj,Field field,Object value){
		field.setAccessible(true);
		try {
			field.set(obj, value);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			LOGGER.error("set field failure",e);
			throw new RuntimeException(e);
		}
	}


}

    1.二、完成反射工具类以后,就要经过ClassHelper类的getBeanClassSet方法,而后经过ReflectionUtil类的newInstance方法,根据类来实例化对象,最后将每次建立的对象放在一个静态Map<Class<?>,Object>中。 因此须要建立一个BeanHelper类来存储Bean实例。code

package org.smart4j.framework.helper;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.smart4j.framework.util.ReflectionUtil;

/**
 * Bean助手类:实例化加载的Class对象Bean
 * @author TS
 *
 */
public class BeanHelper {
	
	/**
	 * 定义Bean映射 (用于存放Bean的Class对象与Bean实例的映射关系)
	 */
	private static final Map<Class<?>,Object> BEAN_MAP = new HashMap<Class<?>,Object>();
	
	
	static{
		
		Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet();	//获取标注@Controller,@Service注解下的全部Class对象
		for (Class<?> cls : beanClassSet) {
			Object obj = ReflectionUtil.getInstance(cls);
			BEAN_MAP.put(cls, obj);
		}
	}
	
	/**
	 * 获取bean映射
	 * @return
	 */
	public static Map<Class<?>,Object> getBeanMap(){
		return BEAN_MAP;
	}
	
	
	/**
	 * 经过传入的Class对象获取Bean容器的实例对象
	 * @param cls
	 * @return
	 */
	@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);
	}
}

    1.三、编写完成以后BeanHelper就至关于一个Bean容器了,由于BEAN_MAP存放了Bean类和Bean实例的映射关系,咱们只需经过getBean方法,传入一个Bean类,就能获取Bean实例了。对象

---------------------------------------summarize(总结):至此Bean容器已经实现了,就能够经过getBean方法来从容器中获取实例Bean对象了(既然已经能够获得全部的实例化对象了,接下来就利用@Inject来实现依赖注入吧)-----------------------------------------get

相关文章
相关标签/搜索