【从零写javaweb框架】(四)实现Bean容器

上一章,我们写了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。

下一篇终于轮到重头戏——实现依赖注入了。

【从零写javaweb框架】(五)实现依赖注入功能



©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页