從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

相關文章
相關標籤/搜索