主要涉及到的技术以及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. SOLID原则、设计模式适用于Python语言吗

    在阅读 clean architecture的过程中,会发现作者经常提到recompile redeploy,这些术语看起来都跟静态类型语言有关,比如Java.C++.C#.而在我经常使用的pytho ...

  2. 过滤器、拦截器和AOP的分析与对比

    目录 一.过滤器(Filter) 1.1 简介 1.2 应用场景 1.3 源码分析 二.拦截器(Interceptor) 2.1 简介 2.2 应用场景 2.2 源码分析 三.面向切面编程(AOP) ...

  3. NOIP201605玩具谜题-解题报告

    NOIP201605玩具谜题-解题报告                                                                         2019-11- ...

  4. 货物移动BAPI:BAPI_GOODSMVT_CREATE报错提示“不能执行功能模块 MB_CREATE_GOODS_MOVEMENT”的原因

    在开发过程中,我们调用BAPI:BAPI_GOODSMVT_CREATE进行货物移动生成物料凭证时,出现了报错提示:“不能执行功能模块 MB_CREATE_GOODS_MOVEMENT”,如下图所示: ...

  5. 【aliyun】学java,看这里,不迷茫!1460道Java热门问题

    阿里极客公益活动: 或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里系技术专家来云栖问答为你解答技术难题了 他们用户自己手中的技术来帮助用户成长 ...

  6. MIT线性代数:5.转置,置换,向量空间

  7. python-->二进制的用法

    1.10进制转换为其他进制 方法一:函数 十进制转二进制:bin(10) --> '0b1010' tpye:是字符串类型 0b:表示2进制 十进制转八进制:oct(10) --> '0o ...

  8. CDQ分治学习笔记(三维偏序题解)

    首先肯定是要膜拜CDQ大佬的. 题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai​.b_ibi​.c_ ...

  9. window.getComputedStyle()方法的使用及其扩展

    1.window.getComputedStyle()方法返回值 是一个可以获取当前元素所有最终使用的CSS属性值.返回的是一个CSS样式声明对象([object CSSStyleDeclaratio ...

  10. 『题解』洛谷P5015 标题统计

    题意描述 给你一个字符串,求所有字符的总数. 字符只包含数字,大小写字母. 分析 字符串的长度还是\(\le5\)的. 直接枚举就可以了. AC代码: NOIP官方标准程序是这样的 #include ...