最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Java反射技術(shù)實現(xiàn)簡單IOC容器

 更新時間:2020年07月07日 10:44:19   作者:Haidnor  
這篇文章主要介紹了基于Java反射技術(shù)實現(xiàn)簡單IOC容器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

前言

首先思考一個問題,如果你正在做一個復(fù)雜的系統(tǒng),一個系統(tǒng)模塊內(nèi)有幾百個功能業(yè)務(wù)類,這些類需要使用同一些對象來進行工作。那么,你會怎樣去管理這些通用且一樣的對象呢?

學習過Spring的朋友會知道,Spring框架為此提供了一種非常先進的思想,即IOC(控制反轉(zhuǎn))。Spring可以理解為一個工廠,負責對象的創(chuàng)建和對象間關(guān)系的維護。IoC即控制反轉(zhuǎn),簡單說就是之前需要使用new的方式創(chuàng)建對象,而Spring框架會從XML文件中根據(jù)配置的信息來創(chuàng)建對象,然后放進它自己的容器之中。在程序要使用到該對象的時候,自動注入。

下面就來做一個最簡單的IOC容器。

1.創(chuàng)建一個實體類,比如學生類,汽車類

2.創(chuàng)建XML文件配置對象的信息

3.編寫一個IOC容器類。這個類工作起來,首先加載XML文件,掃描自己配置的對象信息,之后使用反射技術(shù)創(chuàng)建對象,最后將這些

對象放進自己的Map集合中(容器)。外部想要調(diào)用這些對象,那么就使用Map的鍵,來拿到這個集合中對應(yīng)的值(對象)。

編寫一個喜聞樂見的Student學生類。

我做的比較簡單,沒有使用get() set()方法。

后面使用反射技術(shù)可以強制給 private 修飾的屬性賦值

package cn.haidnor.bean;

public class Student {
  /** 學生姓名 */
  private String name;
  /** 學生性別 */
  private String gender;
  /** 學生年齡 */
  private int age;
  
  @Override
  public String toString() {
    return "Student{" +
        "name='" + name + '\'' +
        ", gender='" + gender + '\'' +
        ", age=" + age +
        '}';
  }
}

創(chuàng)建XML文件,配置對象信息

  • id 表示在IOC容器(Map)的鍵
  • class 表示對象類的全類名
  • name 表示對象的各種屬性名
  • property下的文本節(jié)點表示該屬性的值
<?xml version="1.0" encoding="UTF-8"?>
<beans>
  <bean id="stu1" class="cn.haidnor.bean.Student">
    <property name="name">Lucy</property>
    <property name="age">18</property>
    <property name="gender">female</property>
  </bean>

  <bean id="stu2" class="cn.haidnor.bean.Student">
    <property name="name">Tom</property>
    <property name="age">21</property>
    <property name="gender">male</property>
  </bean>

  <bean id="stu3" class="cn.haidnor.bean.Student">
    <property name="name">LiLi</property>
    <property name="age">23</property>
    <property name="gender">female</property>
  </bean>
</beans>

編寫IOC容器類

1.首先根據(jù)XML中的配置文件,生成學生對象

2.所有的對象都放入到一個Map中

3.提供一個getBean()的方法,傳入配置文件中的id,返回對應(yīng)的對象

package cn.haidnor.core;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;


public class SpringIOC {

  /**
   * 配置文件地址
   */
  private static final String CONFIGURATION_PATH = "resources/applicationContext.xml";

  /**
   * ioc容器
   */
  private static Map<String, Object> ioc = new HashMap<>();

  static {
    initialization();
  }

  /**
   * 從 ioc 容器中獲取指定 bean
   *
   * @param name 需要獲取的 bean 的 id, 對應(yīng) XML 配置文件中的 bean id
   * @return bean
   */
  public static Object getBean(String name) {
    return ioc.get(name);
  }

  /**
   * 初始化容器
   */
  private static void initialization() {
    Document document = null;

    try {
      DocumentBuilderFactory bdf = DocumentBuilderFactory.newInstance();
      DocumentBuilder documentBuilder = bdf.newDocumentBuilder();
      document = documentBuilder.parse(CONFIGURATION_PATH);
    } catch (Exception e) {
      e.printStackTrace();
    }

    NodeList beanNodes = document.getElementsByTagName("bean");

    for (int i = 0; i < beanNodes.getLength(); i++) {
      Node node = beanNodes.item(i);
      reloadBean(node);
    }
  }

  /**
   * 裝載 benn
   *
   * @param beanNode xml 文件 bean 根節(jié)點
   */
  private static void reloadBean(Node beanNode) {
    Element bean = (Element) beanNode;

    String id = bean.getAttribute("id");      // IOC 容器中 bean 的名字
    String beanClass = bean.getAttribute("class"); // 全類名

    // 每個 bean 節(jié)點下的全部 property 節(jié)點
    NodeList childNodes = beanNode.getChildNodes();
    Map<String, String> attributeMap = reloadAttribute(childNodes);

    // 使用反射構(gòu)造 bean 對象
    Object instance = creatBean(beanClass, attributeMap);

    // 將所有的 bean 對象放入容器中
    ioc.put(id, instance);
  }

  /**
   * 加載 bean 的屬性值
   *
   * @param attributeNodes 所有的屬性 property 節(jié)點
   * @return Map 屬性的名字和值集合
   */
  private static Map<String, String> reloadAttribute(NodeList attributeNodes) {
    Map<String, String> keyValue = new HashMap<>();
    for (int i = 0; i < attributeNodes.getLength(); i++) {
      Node filed = attributeNodes.item(i);
      if (filed.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element) filed;
        String fileName = element.getAttribute("name");
        String value = element.getFirstChild().getNodeValue();
        keyValue.put(fileName, value);
      }
    }
    return keyValue;
  }

  /**
   * 構(gòu)造bean對象
   *
   * @param className 全類名
   * @param attributes 每個對象的屬性和
   * @return Object 構(gòu)造完成的 bean 對象
   */
  private static Object creatBean(String className, Map<String, String> attributes) {
    Object instance = null;
    try {
      Class<?> clazz = Class.forName(className);
      instance = clazz.newInstance();
      Field[] fields = clazz.getDeclaredFields();

      for (Field field : fields) {
        setFiledValue(instance, field, attributes);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return instance;
  }

  /**
   * 為實例對象的屬性賦值
   *
   * @param instance  實例對象
   * @param field   屬性字段對象
   * @param attributes 屬性名與屬性值的 Map 集合
   */
  private static void setFiledValue(Object instance, Field field, Map<String, String> attributes) {
    // 忽略 field 權(quán)限檢查
    field.setAccessible(true);

    String type = field.getType().toString();
    String name = field.getName();

    try {
      switch (type) {
        case "char":
          field.setChar(instance, attributes.get(name).charAt(0));
          break;

        case "class java.lang.Boolean":
        case "boolean":
          field.setBoolean(instance, Boolean.parseBoolean(attributes.get(name)));
          break;

        case "class java.lang.Byte":
        case "byte":
          field.setByte(instance, Byte.parseByte(attributes.get(name)));
          break;

        case "class java.lang.Float":
        case "float":
          field.setFloat(instance, Float.parseFloat(attributes.get(name)));
          break;

        case "class java.lang.Integer":
        case "int":
          field.setInt(instance, Integer.parseInt(attributes.get(name)));
          break;

        case "class java.lang.Long":
        case "long":
          field.setLong(instance, Long.parseLong(attributes.get(name)));
          break;

        case "class java.lang.Short":
        case "short":
          field.setShort(instance, Short.parseShort(attributes.get(name)));
          break;

        default:
          field.set(instance, attributes.get(name));
          break;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

最后編寫測試類

  • 不使用new的方式創(chuàng)建學生對象
  • 使用ioc容器getBean()方法獲取對象
  • 調(diào)用對象的復(fù)寫的toString()方法
package cn.haidnor.test;

import cn.haidnor.bean.Student;
import cn.haidnor.core.SpringIOC;

public class Test {
  public static void main(String[] args) {
    // 不使用 new 的方式創(chuàng)建對象, 從容器中獲取
    Student stu1 = (Student) SpringIOC.getBean("stu3");
    // 調(diào)用學生類的方法,打印信息
    System.out.println(stu1.toString());
  }
}

運行結(jié)果,控制臺打印輸出的內(nèi)容

Student{name='LiLi', gender='female', age=23}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Struts2 漏洞分析及如何提前預(yù)防

    Struts2 漏洞分析及如何提前預(yù)防

    2016年4月26日,Struts2發(fā)布一份安全公告,CVE編號 CVE-2016-3081。這是自2012年Struts2命令執(zhí)行漏洞大規(guī)模爆發(fā)之后,該服務(wù)時隔四年再次爆發(fā)大規(guī)模漏洞。該漏洞也是今年目前爆出的最嚴重安全漏洞。本文分析了漏洞的原理危害影響防護等內(nèi)容。
    2016-05-05
  • Spring Boot 整合單機websocket的步驟 附github源碼

    Spring Boot 整合單機websocket的步驟 附github源碼

    websocket 是一個通信協(xié)議,通過單個 TCP 連接提供全雙工通信,這篇文章主要介紹了Spring Boot 整合單機websocket的步驟(附github源碼),需要的朋友可以參考下
    2021-10-10
  • SpringBoot整合Quartz實現(xiàn)動態(tài)配置的代碼示例

    SpringBoot整合Quartz實現(xiàn)動態(tài)配置的代碼示例

    這篇文章將介紹如何把Quartz定時任務(wù)做成接口,實現(xiàn)以下功能的動態(tài)配置添加任務(wù),修改任務(wù),暫停任務(wù),恢復(fù)任務(wù),刪除任務(wù),任務(wù)列表,任務(wù)詳情,文章通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • 詳解Java如何實現(xiàn)與JS相同的Des加解密算法

    詳解Java如何實現(xiàn)與JS相同的Des加解密算法

    這篇文章主要介紹了如何在Java中實現(xiàn)與JavaScript相同的DES(Data Encryption Standard)加解密算法,確保在兩個平臺之間可以無縫地傳遞加密信息,希望對大家有一定的幫助
    2025-04-04
  • 在2023idea中實現(xiàn)SpringBoot的IoC和AOP的方法

    在2023idea中實現(xiàn)SpringBoot的IoC和AOP的方法

    這篇文檔詳細介紹了如何在Spring Boot中實現(xiàn)IoC(控制反轉(zhuǎn))和AOP(面向切面編程),深入探討了AOP的基本概念,包括AOP的作用、優(yōu)勢以及實現(xiàn)方式,最后,它提到了AOP的注解,如@Aspect、@Pointcut、@Before、@After、@AfterReturning、@AfterThrowing和@Around
    2024-11-11
  • SpringBatch數(shù)據(jù)讀取的實現(xiàn)(ItemReader與自定義讀取邏輯)

    SpringBatch數(shù)據(jù)讀取的實現(xiàn)(ItemReader與自定義讀取邏輯)

    本文主要介紹了SpringBatch數(shù)據(jù)讀取的實現(xiàn), 文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-04-04
  • 淺談Java數(shù)組的一些使用方法及堆棧存儲

    淺談Java數(shù)組的一些使用方法及堆棧存儲

    下面小編就為大家?guī)硪黄獪\談Java數(shù)組的一些使用方法及堆棧存儲。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • Java中RedissonClient基本使用指南

    Java中RedissonClient基本使用指南

    RedissonClient 是一個強大的 Redis 客戶端,提供了豐富的功能和簡單的 API,本文就來介紹一下Java中RedissonClient基本使用指南,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Struts2實現(xiàn)文件上傳時顯示進度條功能

    Struts2實現(xiàn)文件上傳時顯示進度條功能

    這篇文章主要為大家詳細介紹了Struts2實現(xiàn)文件上傳時顯示進度條功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Spring JPA聯(lián)表查詢之OneToOne源碼詳解

    Spring JPA聯(lián)表查詢之OneToOne源碼詳解

    這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToOne源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04

最新評論

四会市| 阳东县| 沈丘县| 马龙县| 天祝| 喜德县| 准格尔旗| 金平| 汉寿县| 双桥区| 历史| 泰来县| 太康县| 英德市| 靖西县| 镇安县| 天气| 静海县| 西吉县| 布尔津县| 林芝县| 阿克苏市| 宝坻区| 龙江县| 尼勒克县| 治多县| 泾源县| 临高县| 安图县| 南城县| 永和县| 黄大仙区| 徐闻县| 吉木萨尔县| 尚志市| 松滋市| 渭源县| 来凤县| 什邡市| 石阡县| 麟游县|