Java利用反射和读取xml实现迷你容器

news2024/11/18 13:52:07

由于需要框架能实现多态,达到控制反转解耦。所以容器还是需要的,容器的存在可以简化对象获取工作,但是容器也不是万能的。合理使用即可,Spring对我来说太庞大了,用不着,为此给框架写一个迷你版容器。

容器配置还是继承以前用spring.net的容器配置,名称为ObjConfig.xml放在程序根目录供容器初始化

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns='http://www.springframework.net' default-autowire="byType">
  <!--这个配置文件主要用来配置系统的业务服务类,不要删除、修改提交其他人添加的配置,新加配置提交时主要同时提交配置使用的动态库,-->
  <!--否则会造成其他人更新后报错-->
  <!--检验数据访问层底层。postgresql配LIS.DAL.Base.PostgreSqlBase-->
  <object id="LisMianDbFactory" type="LIS.Dal.Base.PostgreSqlBase,LIS.Dal.Base"  singleton="false">
  </object>
 
</objects>

容器实现

package LIS.Core.Context;

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.io.File;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.HashMap;
import java.util.*;

//一个迷你版容器,供ORM等控制反转使用
public class ObjectContainer {

    ///用来存类型
    private static List<Class> classList=new ArrayList<Class>();

    ///存类的查找关系
    private static HashMap<String, Integer> classIndexMap = new HashMap<String, Integer>();

    /// <summary>
    /// 按类型返回强类型的对象,一般用接口获得实现类
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <returns>返回的对象</returns>
    public static <T> T GetObject()
    {
        Type type = ObjectContainer.class.getClass().getGenericSuperclass();
        Class c=type.getClass();
        Class<?> parent=c.getSuperclass();
        String cName=c.getName();
        if(classIndexMap.containsKey(cName))
        {
            //创建对象
            Object o = GetObject(cName);
            return (T)o;
        }
        if(parent!=null)
        {
            String parentName=parent.getName();
            if(classIndexMap.containsKey(parentName))
            {
                //创建对象
                Object o = GetObject(parentName);
                return (T)o;
            }
        }
        Class<?> interfaceArr[]=c.getInterfaces();
        if(interfaceArr!=null&&interfaceArr.length>0)
        {
            for(int j=0;j<interfaceArr.length;j++)
            {
                String interfaceName=interfaceArr[j].getName();
                if(classIndexMap.containsKey(interfaceName))
                {
                    //创建对象
                    Object o = GetObject(interfaceName);
                    return (T)o;
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 按名称返回强类型的对象
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <param name="name">对象名称</param>
    /// <returns>返回的对象</returns>
    public static <T> T GetTypeObject(String name)
    {
        Object o=GetObject(name);
        return (T)o;
    }

    /// <summary>
    /// 按名称返回对象
    /// </summary>
    /// <param name="name">对象名称</param>
    /// <returns>返回对象</returns>
    public static Object GetObject(String name)
    {
        if(classIndexMap.containsKey(name))
        {
            try {
            int index=classIndexMap.get(name);
            Class c=classList.get(index);
            //创建对象
            Object o = c.newInstance();
            return o;
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
        }
        return null;
    }


    /// <summary>
    /// 用类型全名和程序集全名获得类型
    /// </summary>
    /// <param name="typeName">类型全名</param>
    /// <param name="assemblyName">程序集名</param>
    /// <returns></returns>
    private static Class GetType(String typeName, String assemblyName)
    {
        try {
            //得到根路径
            Class<?> clazz = ObjectContainer.class;
            ClassLoader classLoader = clazz.getClassLoader();
            URL resourceURL1 = classLoader.getResource("");
            String bashePath = resourceURL1.getFile();
            //组装成jar包路径
            String jarPath=bashePath+assemblyName+".jar";
            File file = new File(jarPath);
            if (!file.exists()) {
                throw new Exception("未能找到"+jarPath+"的文件");
            }
            //反射得到类型
            //自己生成jar包路径
            URL url = file.toURI().toURL();
            URL[] urls = new URL[]{url};
            //加载程序集
            URLClassLoader loader = new URLClassLoader(urls);
            //加载类
            Class c = loader.loadClass(typeName);
            if(c!=null)
            {
                return  c;
            }
            else
            {
                throw new Exception("未能构建类型"+typeName);
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return  null;
    }

    /// <summary>
    /// 从根目录的ObjConfig初始化IOC容器,还是按Spring.Net的配置格式
    /// </summary>
    public static void InitIoc() {
        try {
            //得到根路径
            Class<?> clazz = ObjectContainer.class;
            ClassLoader classLoader = clazz.getClassLoader();
            URL resourceURL = classLoader.getResource("resources/ObjConfig.xml");
            String IocPath = resourceURL.getFile();
            //判断配置是否存在
            File file = new File(IocPath);
            if (!file.exists()) {
                System.out.println("resources/ObjConfig.xml文件不存在,请确认!");
                return;
            }
            //解析xml
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(file);
            // 获得根节点
            Element rootElement = document.getDocumentElement();
            // 获得根节点下的所有子节点
            NodeList students = rootElement.getChildNodes();
            for (int i = 0; i < students.getLength(); i++) {
                // 由于节点多种类型,而一般我们需要处理的是元素节点
                Node childNode = students.item(i);
                // 元素节点就是非空的子节点,也就是还有孩子的子节点
                if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element childElement = (Element) childNode;
                    //不是对象配置元素就忽略
                    if(childElement.getNodeName()!= "object")
                    {
                        continue;
                    }
                    //解析类型配置
                    String type=childElement.getAttribute("type");
                    //是否单例
                    String singleton=childElement.getAttribute("singleton");
                    //取对象id
                    String id=childElement.getAttribute("id");
                    //分割类全面和包名
                    String [] arr=type.split(",");
                    //反射得到类型
                    Class c=GetType(arr[0],arr[1]);
                    //添加到类型列表
                    classList.add(c);
                    //存储索引
                    int index=classList.size()-1;
                    Class<?> parent=c.getSuperclass();
                    //有id就存id映射
                    if(id!=null&&id!="")
                    {
                        if(classIndexMap.containsKey(id))
                        {
                            throw new Exception("已经包含了id为:"+id+"的类型");
                        }
                        classIndexMap.put(id,index);
                    }
                    //有父类就存父类映射
                    if(parent!=null)
                    {
                        String parentName=parent.getName();
                        if(!classIndexMap.containsKey(parentName))
                        {
                            classIndexMap.put(parentName,index);
                        }
                    }
                    //得到所有实现的接口
                    Class<?> interfaceArr[]=c.getInterfaces();
                    //循环存接口映射
                    if(interfaceArr!=null&&interfaceArr.length>0)
                    {
                        for(int j=0;j<interfaceArr.length;j++)
                        {
                            String interfaceName=interfaceArr[j].getName();
                            if(!classIndexMap.containsKey(interfaceName)) {
                                classIndexMap.put(interfaceName, index);
                            }
                        }
                    }
                }
            }

        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

使用容器
在这里插入图片描述
在这里插入图片描述

运行测试,成功取到PG数据库的数据
在这里插入图片描述

经过下午两小时的努力,LIS.Core的一个核心小功能实现了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1118325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty的高性能基石ByteBuf

前言 ​ NIO中缓冲区是数据传输的基础&#xff0c;JDK通过ByteBuffer实现&#xff0c;Netty框架中并未采用JDK原生的ByteBuffer,而是构造了ByteBuf。 ​ Netty中的ByteBuf对ByteBuffer做了大量的优化&#xff0c;比如说内存池&#xff0c;零拷贝&#xff0c;引用计数&#xf…

QFileDialog 文件对话框

文章目录 1、简介2、公共类型3、属性4、functions1、访问属性相关 function2、静态公共成员1、 通过对话框获取用户选择的文件路径&#xff1a;QFileDialog::getOpenFileName2、 通过对话框获取用户选择的文件夹路径&#xff1a;QFileDialog::getExistingDirectory 3、Public F…

家庭资产配置

不同家庭的资产配置 理财就是理人生 为人生的每件事&#xff0c;准备好相应的钱 生存的事 生活费 假设我们今年30岁&#xff0c;则至60岁期间所需的日常生活开支为&#xff1a; 4000元/月X 12月X30年144万 养老的事 养老费 吃饭居住娱乐其他开销60至80岁期间所需的养老…

用Wokwi仿真ESP-IDF项目

陈拓 2023/10/21-2023/10/21 1. 概述 Wokwi是一个在线的电子电路仿真器。你可以使用它来仿真Arduino、ESP32、STM32和许多其他流行的电路板、元器件以及传感器&#xff0c;免去使用开发板。 Wokwi提供基于浏览器的界面&#xff0c;您可以通过这种简单直观的方式快速开发一个…

农产品农货经营小程序商城的作用是什么

农产品行业涵盖的产品很多&#xff0c;以小麦、稻子、玉米、高粱等为主&#xff0c;还有粮油、果蔬、畜牧等产品。 自建技术团队&#xff0c;耗时耗力&#xff0c;培养成本较高&#xff0c;销售渠道单一、等客上门、产品无法高效宣传及促进用户购买&#xff0c;营销力不足&…

会声会影2023官方破解版激活码

随着短视频、vlog等媒体形式的兴起&#xff0c;视频剪辑已经成为了热门技能。甚至有人说&#xff0c;不会修图可以&#xff0c;但不能不会剪视频。实际上&#xff0c;随着各种智能软件的发展&#xff0c;视频剪辑已经变得越来越简单。功能最全的2023新版&#xff0c;全新视差转…

JavaWeb学生管理系统(详细源码+解析)

​ 很多人大学的第一个小项目就是使用JavaWeb实现了一个学生管理系统或者是图书管理系统。在没有项目经验的情况下&#xff0c;前后端都需要自己去完成&#xff0c;还是要耗费不少时间精力的。本次我就分享一下我在大学期间完成的第一个小项目&#xff1a;学生管理系统。采用的…

2023年【司钻(钻井)】及司钻(钻井)作业模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 司钻&#xff08;钻井&#xff09;是安全生产模拟考试一点通生成的&#xff0c;司钻&#xff08;钻井&#xff09;证模拟考试题库是根据司钻&#xff08;钻井&#xff09;最新版教材汇编出司钻&#xff08;钻井&#…

Tuxera NTFS2023破解版苹果电脑磁盘读写工具

当您获得一台新 Mac 时&#xff0c;它只能读取 Windows NTFS 格式的 USB 驱动器。要将文件添加、保存或写入您的 Mac&#xff0c;您需要一个附加的 NTFS 驱动程序。Tuxera 的 Microsoft NTFS for Mac 是一款易于使用的软件&#xff0c;可以在 Mac 上打开、编辑、复制、移动或删…

性能优化:JIT即时编译与AOT提前编译

优质博文&#xff1a;IT-BLOG-CN 一、简介 JIT与AOT的区别&#xff1a; 两种不同的编译方式&#xff0c;主要区别在于是否处于运行时进行编译。 JIT:Just-in-time动态(即时)编译&#xff0c;边运行边编译&#xff1a;在程序运行时&#xff0c;根据算法计算出热点代码&#xf…

CVE-2019-1388 UAC提权实战

1.查看用户权限&#xff1a;guest来宾权限 2.右键-以管理员身份运行&#xff1a; 3.这个时候会弹出UAC&#xff0c;不用管它&#xff0c;点击&#xff1a;显示详细信息 4.然后点击蓝色字体&#xff1a;显示有关此发布者的证书信息 5.来到证书信息这里&#xff0c;点击颁发着…

线程是如何在 6 种状态之间转换的?

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 今天我们主要学习线程是如何在 6 种状态之间转换的。 线程的 6 种状态 就像生物从出生到长大、最终死亡的过程一样&#xff0c;线程也有自己的生命周期&#xff0c;在 Java 中线程的生命周期中一共有 6 种状态。 …

揭开 Amazon Bedrock 的神秘面纱 | 基础篇

在 2023 年 4 月&#xff0c;亚马逊云科技曾宣布将 Amazon Bedrock 纳入使用生成式人工智能进行构建的新工具集。Amazon Bedrock 是一项完全托管的服务&#xff0c;提供各种来自领先 AI 公司&#xff08;包括 AI21 Labs、Anthropic、Cohere、Stability AI 和 Amazon 等&#xf…

Python学习第一天-安装Python

文章目录 前言一、下载Python二、执行安装程序三、命令行验证总结 前言 以下榜单来自于TIOBE编程语言流行指数 不多说了&#xff0c;Python天下第一 一、下载Python 从官网下载Python安装程序 二、执行安装程序 找到python-3.12.0-amd64.exe执行&#xff0c;选择Install …

基于Python3的Scapy构造DNS报文

一&#xff1a;DNS协议 DNS&#xff08;Domain Name System&#xff09;协议是计算机网络中的一种基础协议&#xff0c;它用于将域名&#xff08;如www.baidu.com&#xff09;转换为IP地址&#xff08;如192.168.0.1&#xff09;&#xff0c;从而实现计算机之间的通信。 DNS 分…

【Unity地编细节】为什么Unity笔刷在地形上面刷不出来

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

【编解码】解码字符串中的 UNICODE 字符

前言 由于前后端交互中编码的问题&#xff0c;出现了这样的一串字符&#xff1a; {"share_names":["\u4e2d\u6587\u8def\u5f84"]}出现了unicode编码作为字符串内容的情况&#xff0c;直接用json解析的话会报错&#xff0c;所以在json解析前需要先进行转码…

Linux | 深入浅出冯诺依曼

前言 但凡是科班出生的小伙伴多多稍稍应该都听过冯诺依曼体系吧&#xff0c;这似乎已成为入门计算机的必备知识了&#xff0c;本章就带着大家一起去理解冯诺依曼体系&#xff1b; 一、体系构成 冯诺依曼体系主张计算机由五大部件组成&#xff0c;如下所示&#xff1b; 输入设备…

进程(0)——计算机的中的软硬件【Linux】

进程&#xff08;0&#xff09;——计算机的中的软硬件【Linux】 一.硬件&#xff1a;1.1 冯诺依曼结构&#xff1a;1.2 存储金字塔1.2.1输入设备和存储器&#xff1a;1.2.2输出设备和存储器&#xff1a; 二.软件&#xff1a;2.1 操作系统2.1.1 如何理解管理&#xff1a; 博主自…

【Asp.net】Asp.net core中IIS配置注意事项

1、应用地址池设为无托管代码 一、提示&#xff1a;关于IIS上运行ASP.NET Core 站点的“HTTP 500.19”错误 安装dotnet-hosting-3.1.2-win.exe ASP.NET Core 3.1 Runtime (v3.1.2)下载地址&#xff1a; https://download.visualstudio.microsoft.com/download/pr/dd119832-dc4…