手写web框架之实现Bean容器
Posted duan2
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写web框架之实现Bean容器相关的知识,希望对你有一定的参考价值。
实现Bean容器
使用ClassHelper可以获取所加载的类,但无法通过类来实例化对象,因此我们需要提供一个反射工具类,让它封装java反射相关的API,对外提供更好用的工具方法。将该类命名为ReflectionUtil,代码如下:
1 package org.smart4j.framework.org.smart4j.framework.util; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import java.lang.reflect.Field; 6 import java.lang.reflect.Method; 7 8 /** 9 * Created by jack on 2017/5/23. 10 * 放射工具类 11 */ 12 public class ReflectionUtil { 13 private static final Logger LOGGER = LoggerFactory.getLogger(ReflectionUtil.class); 14 15 /** 16 * 创建实例 17 */ 18 public static Object newInstance(Class<?> cls) { 19 Object instance; 20 try { 21 instance = cls.newInstance(); 22 } catch (Exception e) { 23 LOGGER.error("new instance failue", e); 24 throw new RuntimeException(e); 25 } 26 return instance; 27 } 28 29 /** 30 * 调用方法 31 */ 32 public static Object invokeMethod(Object obj, Method method, Object... args) { 33 Object result; 34 method.setAccessible(true); 35 try { 36 result = method.invoke(obj,args); 37 } catch (Exception e) { 38 LOGGER.error("invoke method failure",e); 39 throw new RuntimeException(e); 40 } 41 return result; 42 } 43 44 /** 45 * 设置成员变量的值 46 */ 47 public static void setField(Object obj, Field field,Object value){ 48 49 try { 50 field.setAccessible(true); 51 field.set(obj,value); 52 } catch (IllegalAccessException e) { 53 LOGGER.error("set field failue",e); 54 throw new RuntimeException(e); 55 } 56 } 57 }
我们需要获取所有被smart框架管理的bean类,此时需要调用ClassHelper类的getBeanClassSet方法,随后需要循环调用ReflectionUtil的newInstance方法,根据类来实例化对象,最后将每次创建的对象保存在一个静态的Map<Class<?>,Object>中,我们需要随时获取该Map,还需要根据该Map的key(类名)去获取对应的value
(bean对象),BeanHelper类代码如下:
1 package org.smart4j.framework.helper; 2 3 import org.smart4j.framework.org.smart4j.framework.util.ReflectionUtil; 4 5 import java.util.HashMap; 6 import java.util.Map; 7 import java.util.Set; 8 9 /** 10 * Created by jack on 2017/5/23. 11 * bean 助手类 12 */ 13 public class BeanHelper { 14 /** 15 * 定义bean映射,(用于存放bean类与bean实例的映射关系) 16 */ 17 private static final Map<Class<?>,Object> BEAN_MAP = new HashMap<Class<?>, Object>(); 18 19 /** 20 * 静态代码块 21 */ 22 static { 23 Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet(); 24 for (Class<?> beanClass : beanClassSet) { 25 Object object = ReflectionUtil.newInstance(beanClass); 26 BEAN_MAP.put(beanClass,object); 27 } 28 } 29 30 /** 31 * 获取Bean映射 32 */ 33 public static Map<Class<?>,Object> getBeanMap(){ 34 return BEAN_MAP; 35 } 36 37 /** 38 * 获取Bean实例 39 */ 40 public static <T> T getBean(Class<?> cls){ 41 if (!BEAN_MAP.containsKey(cls)){ 42 throw new RuntimeException("can not get bean by class:"+cls); 43 } 44 return (T) BEAN_MAP.get(cls); 45 } 46 }
现在,BeanHelper就相当于一个“Bean”容器了,因为在Bean map中存放了Bean类和Bean实例的对应关系,我们只需要调用getBean方法,传入一个Bean类,就能获取Bean实例。
以上是关于手写web框架之实现Bean容器的主要内容,如果未能解决你的问题,请参考以下文章
JAVAWEB开发之Spring详解之——Spring的入门以及IOC容器装配Bean(xml和注解的方式)Spring整合web开发整合Junit4测试