主要涉及到的技术以及API

反射、xml定义和解析、树模型
反射可以在代码运行状态下动态的创建对象以及调用方法。 API:Dom4j、Class、Field、Method。
请仔细阅读接下来的API详解,为代码的阅读进行铺垫。

Dom4j

org.dom4j.io.SAXreader - Xml读取工具。
- Document read(InputStream is) 读取输入流,并返回文档对象/文档树模型。 org.dom4j.Document - 文档对象/文档树模型。
- Element getRootElement() 通过文档对象,获取xml文档的根节点。 org.dom4j.Element - 元素/节点对象,一个Element对象就表示一个xml文档的节点。
- String getName() 获取当前节点的名称。
- List<Element> elements() 获取当前节点的所有子节点。
- String attributeValue("属性名称") 获取当前节点的属性值

Class

java.lang.Class        - 类对象,该类的实例由Java虚拟机和类加载器自动构造。
- static Class forName(String className) 根据参数自定的类名创建类对象,类对象中记录了className指定类名的信息。
- T newInstance() 创建该class对象所记录类型的实例。
- Field getDeclaredField(String name) 根据参数指定的name获取类型的字段/成员变量。
- Method[] getMethods() 用于获取Class对象所表示类中的所有公共方法。

Field

java.lang.reflect.Field    - 单个 字段/成员变量 对象
- void setAccessible(boolean falg)java是门安全的语言,字段默认不可暴力访问,想要通过这种方式访问某个字段,需要打开访问权限,传入true即可。
- Type getGenericType() 获取字段类型。

Method

java.lang.reflect.Method    - 用于描述获取到的单个 成员方法 信息。
- String getName() 获取当前方法名称 如setName。
- Object invoke(Object obj, Object... args) 使用参数对象 obj 去调用该 Method 对象所表示的成员方法,实参传递 args。
- 若该 Method 对象表示Person类中setName()方法,则调用该方法就是 obj.setName()。

铺垫完毕 上代码

首先 - 目录结构

pom.xml

第一部分 - Person类

展开查看

public class Person {
private int age;
private String name; @Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Person() {
} public Person(int age, String name) {
this.age = age;
this.name = name;
}

}

###第二部分 - xml文档
![](https://img2018.cnblogs.com/blog/1416345/201912/1416345-20191203004536177-1199634813.png)

注意!!!

第三部分XmlUtil的代码中,由于MarkDown标签冲突原因,集合中的泛型并没有正常显示
如:
Map<String,Object> map = new HashMap<>();
List<Element> beans = rootElement.elements(); 摘抄代码时,还请手动添加。

第三部分 - XmlUtil类

展开查看

public class XmlUtil {
//创建Map集合,用于bean对象的存储
Map map = new HashMap();
/**
* @param xmlName 想要解析的xml文档
* @throws Exception
*/
XmlUtil(String xmlName) throws Exception {
//加载输入流
InputStream is = getClass().getClassLoader().getResourceAsStream(xmlName);
//创建解析器
SAXReader saxReader = new SAXReader();
//解析输入流,得到整个文档
Document document = saxReader.read(is);
//调用init,并将文档树模型传入
init(document);
} public void init(Document document) throws Exception {
//获取文档中的根元素,也就是xml中的beans标签
Element rootElement = document.getRootElement();
//通过根元素,获取文档中所有的bean标签
List<Element> beans = rootElement.elements();
//声明Class类型的引用
Class cls;
//声明实列引用,后续执行方法时用到
Object instance;
//声明String类型的beanId,充当Map集合中的key
String beanId;
//依次取出bean标签
for (Element bean:beans){
//获取bean标签的class属性值
String className = bean.attributeValue("class");
//获取bean标签的id属性值
beanId = bean.attributeValue("id");
//根据获取的class属性值创建Class对象
cls = Class.forName(className);
//根据cls记录的类创建实列
instance = cls.newInstance();
//获取bean标签下的所有property标签
List<Element> propertys = bean.elements();
//挨个取出property标签
for (Element property : propertys){
//获取property标签的name属性值
String name = property.attributeValue("name");
//然后从cls记录的类型中获取name中存储的字段
Field field = cls.getDeclaredField(name);
//如果字段是private修饰,需要手动打开访问权限
field.setAccessible(true);
//获取这个字段的类型,用于后续赋值时的类型判断
Type type = field.getGenericType();
//开始拼接set方法,拼接的方式是 "set"+字段 , 用于后续寻找想要使用的set方法
String methodName = "set" + name;
//获取cls记录类型的所有方法
Method[] methods = cls.getMethods();
String value = property.attributeValue("value");
//遍历所有的方法,并找到吻合的set方法
for (Method method : methods){
//获取方法名,调用String类中的compareToIgnoreCase方法与已经拼接好的 set 方法做比较
if (method.getName().compareToIgnoreCase(methodName) == 0) {
//使用已经获取到的字段类型与标签中读取到的值进行比较
//这里进行String类型的比较
if (type.equals(value.getClass())) {
method.invoke(instance, value);
//如果类型不一致,则进入下一个类型判断
}else if(type == Integer.TYPE){
int i = Integer.parseInt(value);
method.invoke(instance,i);
}
//。。。这里可以继续if else进行类型的判断
}
} }
//所有流程执行完毕,将准备好的 beanId 以及 填充完毕的实列对象放入map集合中
map.put(beanId,instance);
}
} /**
* @param beanId Map中的key
* @return 返回参数key所对应的对象/实列
*/
public Object getBean(String beanId){
return map.get(beanId);
} //main方法中进行测试
public static void main(String[] args) throws Exception {
XmlUtil xmlUtil = new XmlUtil("beans.xml");
Object bean = xmlUtil.getBean("1002");
Person p = (Person)bean;
System.out.println(p);
}

}

###执行结果
![](https://img2018.cnblogs.com/blog/1416345/201912/1416345-20191203004036505-509115665.png)

泡吧一年半,丰富了自己的阅读,也学到很多。第一次写随笔,如有不足还请指出!

SpringIoc以及set注入八种基本类型的简单实现的更多相关文章

  1. Java的八种基本类型:(按字节来分)

    Java的八种基本类型:(按字节来分) boolean   布尔型   1个字节 8bit(8位) byte     字节类型   1个字节 char     字符类型   2个字节 short    ...

  2. 【Java中级】(一)面向对象的特性与八种基本类型

    1.1.Java 基本数据类型: Java提供了8种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. byte.short.int.long.float.double. ...

  3. HTTP协议八种请求类型介绍

    HTTP 协议中共定义了八种方法或者叫“动作”来表明对 Request-URI 指定的资源的不同操作方式,具体介绍如下: OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法.也可以利用向W ...

  4. String类型不属于八种基本类型

    String不属于8种基本数据类型,String是一个对象.因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. new String( ...

  5. http协议的八种请求类型

    GET:向特定的资源发出请求. POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件).数据被包含在请求体中.POST请求可能会导致新的资源的创建和/或已有资源的修改. OPTIONS: ...

  6. Java八种基本类型

    boolean 二进制位: true ,false   byte 二进制位:8 -128 - 127   -2的7次方到2的7次方-1 char 二进制位:16 0 - 65535   short 二 ...

  7. 【转】MYSQL数据库四种索引类型的简单使用--MYSQL组合索引“最左前缀”原则

    MYSQL数据库索引类型包括普通索引,唯一索引,主键索引与组合索引,这里对这些索引的做一些简单描述: (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 ...

  8. Java源码解读(一) 8种基本类型对应的封装类型

    说起源码其实第一个要看的应该是我们的父类Object,这里就不对它进行描述了大家各自对其进行阅读即可. 一.八种基本类型 接下来介绍我们的八种基本类型(这个大家都知道吧):char.byte.shor ...

  9. JVM常量池和八种基本数据及字符串

    迄今为止看到的对常量池和字符串最为透彻的解释,赞一个! 常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据.它包括了关于类.方法.接口等中的常量, ...

随机推荐

  1. python小例子(一)

    参考链接:https://zhuanlan.zhihu.com/p/83998758?utm_source=qq&utm_medium=social&utm_oi=7282008528 ...

  2. fenby C语言 P26

    指针 地址 类型+“*”+变量名=指针变量 int *p1;//指向整型变量的指针变量p1 float *p2;//指向浮点型变量的指针变量p2 char *p3;//指向字符型变量的指针变量p3 “ ...

  3. VBoxManage.exe: error: Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, CL SID_VirtualBox w/ IUnknown works.

    我先把vagrantbox卸载了 重新装了一个 然后提示这个错误 当时我一脸蒙逼 后来经过百度 1, win+r 快捷键打开 “运行”,输入regedit 打开注册表 2,找到 HKEY_CLASSE ...

  4. [UWP]使用PointLight并实现动画效果

    1. Composition Lighting UWP中的Composition Light是一组可以创建3D光照的API,它明明十分好玩而且强大, 但博客园几乎没有相关文章(用UWP或pointli ...

  5. 大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app

    大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app ( 本文内容为melodyWxy原作,git地址:https://github.com/melodyWx ...

  6. 一个自动管理项目的Makefile(C语言)

    Linux 是所有嵌入式软件工程师绕不过去的坎, makefile 是在Linux系统中绕不过去的坎. 花了几天时间初步学习和了解了makefile 的作用以及功能,并且制作了一个通用型的makefi ...

  7. 【暂时停更】Gungame更新下载平台

    v1.0: 这是本游戏的第一个版本, 制作于2019.4.12. 控制 : Player1: wsad为移动, r键开炮(有朝向限制) Player2: ikjl为移动, p键开炮(有朝向限制) 下载 ...

  8. python 3.7.5 官方tutorial 学习笔记

    用了好久python,还没有完整看过官方的tutorial,这几天抽空看了下,还是学到些东西 --- Table of Contents 1. 课前甜点 2. 使用 Python 解释器 2.1. 调 ...

  9. [专题总结]AC自动机

    其实前面的模板也不是1A,我在题库里提前做过,也不必在意罚时,刚开始我在做别的专题 裸模板我就不说了,各个博客讲解的很明白 void insert(string s){ ,len=s.size(); ...

  10. C/C.cpp

    我是怎么说服自己这题没有答案单调性的? 当轮数大于最优答案时,B的操作就成了捣乱,会使A多进行若干操作才能回复原状态 嗯,所以答案没有单调性. 就没去想A的操作可以把B的抵消啊.. 另外swap没有交 ...