zoukankan      html  css  js  c++  java
  • 手写web框架之实现依赖注入功能

      我们在Controller中定义了Service成员变量,然后在Controller的Action方法中调用Service成员变量的方法,那么如果实现Service的成员变量? 之前定义了@Inject注解,就用它来实现Service是例话,那么谁来实例化呢。

          不是开发者通过new的方式来实例化,而是通过框架自身来实例化,像这类实例化过程称为IOC(控制反转),控制不是由开发者来决定,而是反转给框架了。一般也将控制反转称为DI(依赖注入),可以理解为将某个类需要依赖的成员注入到这个类中,那么我们该如何实现了?

          最简单的方式是,先通过BeanHelper获取所有的BeanMap(是一个Map<Class<?>,Object>结构,记录了类与对象的映射关系),然后遍历这个映射关系,分别取出Bean类与Bean实例,进而通过反射获取类中所有成员变量。继续遍历这些成员变量,在循环中判断这些成员变量是否带有Inject注解,若带有该注解,则从BeanMap根据Bean类取出Bean实例。最后通过ReflectionUtil的setField的方法来修改当前成员变量的值。

         把上面的逻辑写成一个IocHelper的类,让它来完成这件事,代码如下:

     1 package org.smart4j.framework.helper;
     2  
     3  
     4 import org.smart4j.framework.annotation.Inject;
     5 import org.smart4j.framework.org.smart4j.framework.util.ArrayUtil;
     6 import org.smart4j.framework.org.smart4j.framework.util.CollectionUtil;
     7 import org.smart4j.framework.org.smart4j.framework.util.ReflectionUtil;
     8  
     9 import java.lang.reflect.Field;
    10 import java.util.Map;
    11  
    12 /**
    13  * Created by jack on 2017/5/23.
    14  * 依赖注入助手类
    15  */
    16 public class IocHelper {
    17     static {
    18         //获取所有的Bean类与Bean实例之间的关系(简称Bean Map)
    19         Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
    20         if (CollectionUtil.isNotEmpty(beanMap)) {
    21             //遍历beanMap
    22             for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
    23                 //从beanMap中获取bean类与bean实例
    24                 Class<?> beanClass = beanEntry.getKey();
    25                 Object beanInstance = beanEntry.getValue();
    26                 //获取Bean类定义的所有成员变量(简称Bean Field)
    27                 Field [] beanFields = beanClass.getDeclaredFields();
    28                 if (ArrayUtil.isNotEmpty(beanFields)){
    29                     //遍历beanField
    30                     for (Field beanField : beanFields) {
    31                         //判断当前的Bean Field是否带有Inject注解
    32                         if (beanField.isAnnotationPresent(Inject.class)){
    33                             //在Bean Map中获取Bean Field对应的实例
    34                             Class<?> beanFieldClass = beanField.getType();
    35                             Object beanFieldInstance = beanMap.get(beanFieldClass);
    36                             if (beanFieldInstance != null){
    37                                 //通过放射初始化beanField值
    38                                 ReflectionUtil.setField(beanInstance,beanField,beanFieldInstance);
    39                             }
    40                         }
    41                     }
    42                 }
    43  
    44  
    45             }
    46         }
    47     }
    48 }
  • 相关阅读:
    全国大学生信息安全竞赛—创新实践能力赛 华东北赛区部分wp
    全国大学生信息安全竞赛—创新实践能力赛初赛部分wp
    XMan冬令营 哈尔滨 day3 移动恶意应用分析
    XMan冬令营 哈尔滨 day2 安卓应用程序逆向分析
    XMan冬令营 哈尔滨 day1 移动应用程序渗透测试
    Linux大作业
    c++ 手写计算器
    KMP字符匹配算法
    二叉树遍历的几种实现
    Jmeter之CSS选择器/JQuery选择器关联
  • 原文地址:https://www.cnblogs.com/duan2/p/11749177.html
Copyright © 2011-2022 走看看