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

由于需要框架能实现多态,达到控制反转解耦。所以容器还是需要的,容器的存在可以简化对象获取工作,但是容器也不是万能的。合理使用即可,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;}//解析xmlDocumentBuilderFactory 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");//取对象idString 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.rhkb.cn/news/165918.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# Onnx Yolov8 Detect 指纹检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Onnx…

「2021年TYWZ普及模拟题」多边形 待定题解

文章目录 题目描述输入格式输出格式样例样例输入 1样例输出 1样例输入 2样例输出 2 数据范围与提示前置知识思路与部分实现完整代码文章小结 题目描述 一个凸多边形具有非常多优秀的性质&#xff0c;它的任意内角小于或等于 18 0 。 180^。 180。 。 小 F 将 n n n 条边交给…

自然语言处理基础

自然语言 自然语言处理是人工智能能够通过图灵测试的重要工具。 自然语言处理基本的任务和应用 词性标注&#xff1a;把每句话的各个单词的词性标注出来&#xff0c;例如&#xff1a;形容词、名词、动词 named entity recognition命名实体的识别&#xff1a;识别哪些单词是真…

C1N短网址 - 是如何做到行业领先的

今天从技术角度来聊下短网址的一些事情&#xff0c;市面上的短网址发展基本上经历了几个阶段。 短网址发展的几个阶段&#xff1a; 第一阶段&#xff1a;网址缩短&#xff0c;很纯粹的功能&#xff0c;各个大小公司都在做&#xff0c;门槛很低。典型代表&#xff1a;百度短网…

滚珠螺杆应如何存放避免受损

滚珠螺杆是一种高精度的机械零件&#xff0c;保存或使用不当&#xff0c;会直接损坏&#xff0c;影响生产效率&#xff0c;因此我们在使用时需要注意以下事项&#xff1a; 1、避免垂直放置&#xff1a;没有施加预压的螺杆垂直放置时&#xff0c;螺母会因自重而从螺杆轴上脱荐下…

【ArcGIS绘图系列1】在ArcGIS中制作柱状图与饼状图

成图展示 图形出处&#xff1a;J2023-Assessment of agricultural drought based on multi-source remote sensing data in a major grain producing area of Northwest China 实现步骤 第一步 查看数据信息 数据输入到ArcGIS中&#xff1a;包含数据表和shp文件 1、shp文件…

[牛客]计算机网络习题笔记_1020

1、物理层&#xff1a;以太网 调制解调器 电力线通信(PLC) SONET/SDH G.709 光导纤维 同轴电缆 双绞线等。 2、数据链路层&#xff08;网络接口层包括物理层和数据链路层&#xff09;&#xff1a;Wi-Fi(IEEE 802.11) WiMAX(IEEE 802.16) ATM DTM 令牌环 以太网 FDD…

MySQL -- 数据库基础

MySQL – 数据库基础 文章目录 MySQL -- 数据库基础一、基础知识1.什么是数据库2.连接服务器3.服务器、数据库、表的关系3.MySQL架构4.SQL分类5.存储引擎 一、基础知识 1.什么是数据库 文件存储数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询和管理文件…

vue2 element手术麻醉信息系统源码,手术预约、手术安排、排班查询、手术麻醉监测、麻醉记录单

手术麻醉临床信息系统有着完善的临床业务功能&#xff0c;能够涵盖整个围术期的工作&#xff0c;能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施&#xff0c;能够规范麻醉科的工作流程&#xff0c;实现麻醉手术过程的信息数字化&#xff0c;自动生成麻…

vscode提示扩展主机在过去5分钟内意外终止了3次,解决方法

参考链接&#xff1a; https://code.visualstudio.com/blogs/2021/02/16/extension-bisect https://code.visualstudio.com/docs/setup/uninstall#_clean-uninstall 使用vscode打开jupyter notebook记事本时&#xff0c;窗口右下角提示扩展主机在过去5分钟内意外终止了3次 而…

四川农业大学就业指南←缺失的就业指导课

推荐 125页就业指南&#xff0c; 包含就业去向、就业政策介绍&#xff0c; 也有毕业生常见问题&#xff0c; 就业协议与劳动合同的阐释&#xff0c; 帮助毕业生系统梳理庞杂的各类就业信息&#xff0c; 人文温度冲淡就业惨淡的灰冷阴霾。 有这样一群人&#xff0c;在2023&…

解决Unity打包时,Android SDK 报错问题

报错内容应该包括类似如下信息&#xff1a; CommandInvokationFailure: Failed to update Android SDK package list. java.lang.UnsupportedClassVersionError: com/android/prefs/AndroidLocationsProvider has been compiled by a more recent version of the Java Runtim…

WPF实现签名拍照功能

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

前言:自动化框架的设计模式

1、UI自动化框架的设计模式 自动化测试框架有很多种&#xff0c;常见的自动化框架分类如下&#xff1a; 在使用上面的自动化框架时&#xff0c;通常会结合使用分层思想&#xff0c;也就是一些自动化框架设计模式&#xff0c;今天重点分享一下UI自动化框架设计使用比较多的一种…

S7-1200通过CM CANopen模块与KINCO伺服连接

CM CANopen模块简介 CM CANopen模块&#xff08;Profinet转CANopen&#xff09;来自瑞典HMS &#xff0c;由西 门子授权HMS公司开发&#xff0c;与S7-1200完美兼容。 可做为S7-1200与CANopen/CAN设备之间的桥梁&#xff0c;能够联接任意 CANopen或CAN 2.0A设备到SIMATIC S7-1…

二维码智慧门牌管理系统升级解决方案:地图展示

文章目录 前言一、地图展示功能二、其他升级和改进 前言 随着城市的发展和信息化建设的推进&#xff0c;二维码智慧门牌管理系统在社区管理、物流配送、巡检巡查等多个领域发挥着越来越重要的作用。为了更好地满足用户需求&#xff0c;提升管理效率和服务质量&#xff0c;我们…

Linux——centos7.4磁盘空间调整分配

安装centos7.4操作系统时&#xff0c;采用默认安装方式&#xff0c;导致磁盘分配不太合理&#xff0c;于是重新进行磁盘空间分配。 1、cnetos7.4默认安装完成时磁盘分配情况 可以看到/dev/mapper/centos-home分区占用大部分空间&#xff0c;如今想将根目录空间增大。 注意&…

IntelliJ IDEA Maven加载超时问题

IDEA创建Maven项目遇到如下错误&#xff1a; Could not transfer artifact org.apache.maven.plugins:maven-compiler-plugin:pom:3.10.1 from/to central (Central Repository:): Connect to repo.maven.apache.org:443 [repo.maven.apache.org/146.75.112.215] failed: conn…

Mysql数据库表操作--存储

建表&#xff1a; 插入上面的数据&#xff1a; 1、创建一个可以统计表格内记录条数的存储函数 &#xff0c;函数名为count_sch() 2、创建一个存储过程avg_sal&#xff0c;有3个参数&#xff0c;分别是deptno&#xff0c;job&#xff0c;接收平均工资(out);功能查询employees表的…