主要涉及到的技术以及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. SpringBoot的Banner

    一 官方文档介绍 1 自定义横幅 通过在 classpath 中添加banner.txt文件或将banner.location设置为此类文件的位置,可以更改启动时打印的横幅.如果文件具有异常编码,则可 ...

  2. day3------基本数据类型int, bool, str,list,tuple,dict

    基本数据类型(int, bool, str,list,tuple,dict) 一.python基本数据类型 1. int  整数. 主要用来进行数学运算 2. str  字符串, 可以保存少量数据并进 ...

  3. Nginx、WSGI、 uWSGI、 uwsgi的区别

    当我们部署完一个应用程序,浏览网页时具体的过程是怎样的呢?首先我们得有一个 Web 服务器来处理 HTTP 协议的内容,Web 服务器获得客户端的请求,交给应用程序,应用程序处理完,返回给 Web 服 ...

  4. Nexus 上传项目到私服

    1. maven setting配置 <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed ...

  5. Flutter学习笔记--Dart基础

    前言 Flutter使用Dart语言开发, Dart是面向对象编程语言, 由Google2011年推出, 目前最新版本是2.4.0. 工欲善其事,必先利其器. 为了更好的开发Flutter应用, 我们 ...

  6. [windows篇] 使用Hexo建立个人博客,自定义域名https加密,搜索引擎google,baidu,360收录

    为了更好的阅读体验,欢迎阅读原文.原文链接在此. [windows篇] 使用Hexo建立个人博客,自定义域名https加密,搜索引擎google,baidu,360收录 Part 2: Using G ...

  7. csps模拟测试 77爆零反思

    题不算太难,可是我还是没考出应有水平. $1h8min$切掉前两道题,然后$T3$想到正解并且码出来了并且过了大样例并且爆零. 没什么好说的,我太自信了,没打对拍? 想到了正解,还不如随便打个暴力分高 ...

  8. 卡特兰数&&prufer序列&&BSGS水题集

    首先说一下BSGS的一个坑点: 解方程A^x≡B(mod p) 需要特判一个东西=>A%p==B%p==0? 如果相等的话puts("1")反之则无解. 因为如果A%p=0, ...

  9. Nginx 的进程结构,你明白吗?

    Nginx 进程结构 这篇文章我们来看下 Nginx 的进程结构,Nginx 其实有两种进程结构: 单进程结构 多进程结构 单进程结构实际上不适用于生产环境,只适合我们做开发调试使用.因为在生产环境中 ...

  10. [转载]2.4 UiPath循环活动While的介绍和使用

    一.While循环的介绍 先判断条件是否满足, 如果满足, 再执行循环体, 直到判断条件不满足, 则跳出循环 二.While循环在UiPath中的使用 1. 打开设计器,在设计库中新建一个Flowch ...