手写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容器的主要内容,如果未能解决你的问题,请参考以下文章

Spring之核心容器bean

JAVAWEB开发之Spring详解之——Spring的入门以及IOC容器装配Bean(xml和注解的方式)Spring整合web开发整合Junit4测试

Spring框架核心功能手写实现

java之spring

Spring框架系列 - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

Spring之IOC容器装配Bean