SpringIoc以及set注入八种基本类型的简单实现
主要涉及到的技术以及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文档

注意!!!
第三部分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);
}
}
###执行结果

泡吧一年半,丰富了自己的阅读,也学到很多。第一次写随笔,如有不足还请指出!
SpringIoc以及set注入八种基本类型的简单实现的更多相关文章
- Java的八种基本类型:(按字节来分)
Java的八种基本类型:(按字节来分) boolean 布尔型 1个字节 8bit(8位) byte 字节类型 1个字节 char 字符类型 2个字节 short ...
- 【Java中级】(一)面向对象的特性与八种基本类型
1.1.Java 基本数据类型: Java提供了8种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. byte.short.int.long.float.double. ...
- HTTP协议八种请求类型介绍
HTTP 协议中共定义了八种方法或者叫“动作”来表明对 Request-URI 指定的资源的不同操作方式,具体介绍如下: OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法.也可以利用向W ...
- String类型不属于八种基本类型
String不属于8种基本数据类型,String是一个对象.因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. new String( ...
- http协议的八种请求类型
GET:向特定的资源发出请求. POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件).数据被包含在请求体中.POST请求可能会导致新的资源的创建和/或已有资源的修改. OPTIONS: ...
- Java八种基本类型
boolean 二进制位: true ,false byte 二进制位:8 -128 - 127 -2的7次方到2的7次方-1 char 二进制位:16 0 - 65535 short 二 ...
- 【转】MYSQL数据库四种索引类型的简单使用--MYSQL组合索引“最左前缀”原则
MYSQL数据库索引类型包括普通索引,唯一索引,主键索引与组合索引,这里对这些索引的做一些简单描述: (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 ...
- Java源码解读(一) 8种基本类型对应的封装类型
说起源码其实第一个要看的应该是我们的父类Object,这里就不对它进行描述了大家各自对其进行阅读即可. 一.八种基本类型 接下来介绍我们的八种基本类型(这个大家都知道吧):char.byte.shor ...
- JVM常量池和八种基本数据及字符串
迄今为止看到的对常量池和字符串最为透彻的解释,赞一个! 常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据.它包括了关于类.方法.接口等中的常量, ...
随机推荐
- SOLID原则、设计模式适用于Python语言吗
在阅读 clean architecture的过程中,会发现作者经常提到recompile redeploy,这些术语看起来都跟静态类型语言有关,比如Java.C++.C#.而在我经常使用的pytho ...
- 过滤器、拦截器和AOP的分析与对比
目录 一.过滤器(Filter) 1.1 简介 1.2 应用场景 1.3 源码分析 二.拦截器(Interceptor) 2.1 简介 2.2 应用场景 2.2 源码分析 三.面向切面编程(AOP) ...
- NOIP201605玩具谜题-解题报告
NOIP201605玩具谜题-解题报告 2019-11- ...
- 货物移动BAPI:BAPI_GOODSMVT_CREATE报错提示“不能执行功能模块 MB_CREATE_GOODS_MOVEMENT”的原因
在开发过程中,我们调用BAPI:BAPI_GOODSMVT_CREATE进行货物移动生成物料凭证时,出现了报错提示:“不能执行功能模块 MB_CREATE_GOODS_MOVEMENT”,如下图所示: ...
- 【aliyun】学java,看这里,不迷茫!1460道Java热门问题
阿里极客公益活动: 或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里系技术专家来云栖问答为你解答技术难题了 他们用户自己手中的技术来帮助用户成长 ...
- MIT线性代数:5.转置,置换,向量空间
- python-->二进制的用法
1.10进制转换为其他进制 方法一:函数 十进制转二进制:bin(10) --> '0b1010' tpye:是字符串类型 0b:表示2进制 十进制转八进制:oct(10) --> '0o ...
- CDQ分治学习笔记(三维偏序题解)
首先肯定是要膜拜CDQ大佬的. 题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai.b_ibi.c_ ...
- window.getComputedStyle()方法的使用及其扩展
1.window.getComputedStyle()方法返回值 是一个可以获取当前元素所有最终使用的CSS属性值.返回的是一个CSS样式声明对象([object CSSStyleDeclaratio ...
- 『题解』洛谷P5015 标题统计
题意描述 给你一个字符串,求所有字符的总数. 字符只包含数字,大小写字母. 分析 字符串的长度还是\(\le5\)的. 直接枚举就可以了. AC代码: NOIP官方标准程序是这样的 #include ...