• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

基于Java反射技术实现简单IOC容器

java 搞代码 4年前 (2022-01-05) 59次浏览 已收录 0个评论

这篇文章主要介绍了基于Java反射技术实现简单IOC容器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

首先思考一个问题,如果你正在做一个复杂的系统,一个系统模块内有几百个功能业务类,这些类需要使用同一些对象来进行工作。那么,你会怎样去管理这些通用且一样的对象呢?

学习过Spring的朋友会知道,Spring框架为此提供了一种非常先进的思想,即IOC(控制反转)。Spring可以理解为一个工厂,负责对象的创建和对象间关系的维护。IoC即控制反转,简单说就是之前需要使用new的方式创建对象,而Spring框架会从XML文件中根据配置的信息来创建对象,然后放进它自己的容器之中。在程序要使用到该对象的时候,自动注入。

下面就来做一个最简单的IOC容器。

1.创建一个实体类,比如学生类,汽车类

2.创建XML文件配置对象的信息

3.编写一个IOC容器类。这个类工作起来,首先加载XML文件,扫描自己配置的对象信息,之后使用反射技术创建对象,最后将这些

对象放进自己的Map集合中(容器)。外部想要调用这些对象,那么就使用Map的键,来拿到这个集合中对应的值(对象)。

编写一个喜闻乐见的Student学生类。

我做的比较简单,没有使用get() set()方法。

后面使用反射技术可以强制给 private 修饰的属性赋值

 package cn.haidnor.bean; public class Student { /** 学生姓名 */ private String name; /** 学生性别 */ private String gender; /** 学生年龄 */ private int age; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", age=" + age + '}'; } }

创建XML文件,配置对象信息

  • id 表示在IOC容器(Map)的键
  • class 表示对象类的全类名
  • name 表示对象的各种属性名
  • property下的文本节点表示该属性的值
    Lucy18female Tom21male LiLi23female

编写IOC容器类

1.首先根据XML中的配置文件,生成学生对象

2.所有的对象都放入到一个Map中

3.提供一个getBean()的方法,传入配置文件中的id,返回对应的对象

 package cn.haidnor.core; 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.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class SpringIOC { /** * 配置文件地址 */ private static final String CONFIGURATION_PATH = "resources/applicationContext.xml"; /** * ioc容器 */ private static Map ioc = new HashMap(); static { initialization(); } /** * 从 ioc 容器中获取指定 bean * * @param name 需要获取的 bean 的 id, 对应 XML 配置文件中的 bean id * @return bean */ public static Object getBean(String name) { return ioc.get(name); } /** * 初始化容器 */ private static void initialization() { Document document = null; try { DocumentBuilderFactory bdf = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = bdf.newDocumentBuilder(); document = documentBuilder.parse(CONFIGURATION_PATH); } catch (Exception e) { e.printStackTrace<em style="color:transparent">来源gao.dai.ma.com搞@代*码网</em>(); } NodeList beanNodes = document.getElementsByTagName("bean"); for (int i = 0; i <beanNodes.getLength(); i++) { Node node = beanNodes.item(i); reloadBean(node); } } /** * 装载 benn * * @param beanNode xml 文件 bean 根节点 */ private static void reloadBean(Node beanNode) { Element bean = (Element) beanNode; String id = bean.getAttribute("id");      // IOC 容器中 bean 的名字 String beanClass = bean.getAttribute("class"); // 全类名 // 每个 bean 节点下的全部 property 节点 NodeList childNodes = beanNode.getChildNodes(); Map attributeMap = reloadAttribute(childNodes); // 使用反射构造 bean 对象 Object instance = creatBean(beanClass, attributeMap); // 将所有的 bean 对象放入容器中 ioc.put(id, instance); } /** * 加载 bean 的属性值 * * @param attributeNodes 所有的属性 property 节点 * @return Map 属性的名字和值集合 */ private static Map reloadAttribute(NodeList attributeNodes) { Map keyValue = new HashMap(); for (int i = 0; i  attributes) { Object instance = null; try { Class clazz = Class.forName(className); instance = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { setFiledValue(instance, field, attributes); } } catch (Exception e) { e.printStackTrace(); } return instance; } /** * 为实例对象的属性赋值 * * @param instance  实例对象 * @param field   属性字段对象 * @param attributes 属性名与属性值的 Map 集合 */ private static void setFiledValue(Object instance, Field field, Map attributes) { // 忽略 field 权限检查 field.setAccessible(true); String type = field.getType().toString(); String name = field.getName(); try { switch (type) { case "char": field.setChar(instance, attributes.get(name).charAt(0)); break; case "class java.lang.Boolean": case "boolean": field.setBoolean(instance, Boolean.parseBoolean(attributes.get(name))); break; case "class java.lang.Byte": case "byte": field.setByte(instance, Byte.parseByte(attributes.get(name))); break; case "class java.lang.Float": case "float": field.setFloat(instance, Float.parseFloat(attributes.get(name))); break; case "class java.lang.Integer": case "int": field.setInt(instance, Integer.parseInt(attributes.get(name))); break; case "class java.lang.Long": case "long": field.setLong(instance, Long.parseLong(attributes.get(name))); break; case "class java.lang.Short": case "short": field.setShort(instance, Short.parseShort(attributes.get(name))); break; default: field.set(instance, attributes.get(name)); break; } } catch (Exception e) { e.printStackTrace(); } } }

最后编写测试类

  • 不使用new的方式创建学生对象
  • 使用ioc容器getBean()方法获取对象
  • 调用对象的复写的toString()方法
 package cn.haidnor.test; import cn.haidnor.bean.Student; import cn.haidnor.core.SpringIOC; public class Test { public static void main(String[] args) { // 不使用 new 的方式创建对象, 从容器中获取 Student stu1 = (Student) SpringIOC.getBean("stu3"); // 调用学生类的方法,打印信息 System.out.println(stu1.toString()); } }

运行结果,控制台打印输出的内容

Student{name='LiLi', gender='female', age=23}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持gaodaima搞代码网

以上就是基于Java反射技术实现简单IOC容器的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:基于Java反射技术实现简单IOC容器

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址