Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面是具体的步骤:

  第一步,编写配置文件.配置文件的书写,采用了和Spring的配置文件applicationContext.xml一样的书写规则:

<?xml version="1.0" encoding="UTF-8"?>
<!-- applicationContext.xml配置文件 -->
<beans>
<bean id="student1" class="com.xyy.domain.Student">
<property name="name" value="hlhdidi"></property>
<property name="age" value="13"></property>
<property name="teacher" ref="teacher1"></property>
</bean>
<bean id="teacher1" class="com.xyy.domain.Teacher">
<property name="name" value="cwb"></property>
<property name="classes" value="高三九班"></property>
</bean>
</beans>

  第二步,编写JavaBean类,书写了两个JavaBean,其中Student类中有一个Teacher类的引用.

//Student类
public class Student implements Serializable{
private String name;
private int age;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", teacher=" + teacher + "]";
} }
//Teacher类
public class Teacher implements Serializable{
private String name;
private String classes;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClasses() {
return classes;
}
public void setClasses(String classes) {
this.classes = classes;
}
@Override
public String toString() {
return "Teacher [name=" + name + ", classes=" + classes + "]";
} }

  第三步,也是最关键的一步,编写MyClassPathXmlApplicationContext类,在这个类里面做了如下操作:

  1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象

  2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.

  3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.

  4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.

  5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.

  6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null

  代码如下:

public class MyClassPathXmlApplicationContext {
private String xmlName; public MyClassPathXmlApplicationContext(String xmlName) {
this.xmlName=xmlName;
} public Object getBean(String id) {
Object obj=null; //声明引用.
//进行xml的解析
SAXReader reader=new SAXReader();
try {
Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(xmlName));
Element root=document.getRootElement();
//遍历.看是否有元素的id为传入的参数.
List<Element> elements = root.elements();
if(elements.size()>0) {
for(Element element:elements ) {
if(element.attributeValue("id").equals(id)) {//id相同开始创建对象
//采用反射创建对象.
String className=element.attributeValue("class");
Class beanClass=Class.forName(className);
obj=beanClass.newInstance();
//获取子标签的属性.
List<Element> attributes=element.elements();
if(attributes.size()>0) {
for(Element attribute:attributes) {
String name=attribute.attributeValue("name");
Field field = beanClass.getDeclaredField(name);
field.setAccessible(true);
if(attribute.attribute("ref")!=null) {
//此属性的值是一个对象.这里由于直接调用getBean方法赋值给对象,返回的对象一定是Bean参数的对象,因此强制转换不会出问题
String refid=attribute.attributeValue("ref");
field.set(obj, getBean(refid));
}
else {
//此属性值是一个字符串.这里单独处理int,float类型变量.如果不处理,会将String类型直接赋值给int类型,发生ClassCastException
String value=attribute.attributeValue("value");
//需要对类型进行判断
if(value.matches("[0-9]+")) {
//整数
int x=Integer.parseInt(value);
field.set(obj, x);
continue;
}
if(value.matches("[0-9]*(\\.+)[0-9]*")) {
//浮点数
float y=Float.parseFloat(value);
field.set(obj, y); //注意double可以接受float类型
continue;
}
field.set(obj, value);//处理String类型
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}

  第四步:测试.

@Test
public void testMySpring() {
MyClassPathXmlApplicationContext applicationContext=new MyClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(applicationContext.getBean("student1"));
}

  测试结果:

Student [name=hlhdidi, age=13, teacher=Teacher [name=cwb, classes=高三九班]]

  总结:

  dom4j是一个很好的解析xml的工具,而解析xml是一个很重要的基本功,对于理解框架原理有很大的帮助.反射结合xml文件的解析,可以实现在任何类中方便的创建任何对象.

采用dom4j和反射模拟Spring框架的依赖注入功能的更多相关文章

  1. spring框架之依赖注入(DI)

    1. IOC和DI的概念 * IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!! * DI -- Dependency Injection,依赖注入,在 ...

  2. PHP 从另一个角度来分析 Laravel 框架的依赖注入功能

    从根本上说,依赖注入不是让对象创建一个依赖关系,也不是让工厂对象去创建对象,而是将所需的依赖变成一个外部对象,使之成为一个"某些人的问题” 你为"某些人的问题”注入了类的依赖关系. ...

  3. Spring框架——IOC依赖注入

    本来想把IOC和AOP一起介绍的,但是AOP内容太多了,所以就分开了,最后的结果就是这一篇只剩下一点点了.这不是第一次写关于IOC的文章了,之前写过Java反射,Java注解,也写过通过XML解析实现 ...

  4. Spring框架(依赖注入)

    特点 1轻量级和侵入性低 2依赖注入和面向接口实现松耦合 3面向切面编程 减少样式代码 专有名词: 1依赖注入:对象无需自行管理依赖关系.通过系统负责协调在创建对象的第三方组件的设定,实现依赖关系自动 ...

  5. Spring框架的IOC核心功能快速入门

    2. 步骤一:下载Spring框架的开发包 * 官网:http://spring.io/ * 下载地址:http://repo.springsource.org/libs-release-local/ ...

  6. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  7. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  8. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

  9. [ASP.NET Core 3框架揭秘] 依赖注入[9]:实现概述

    <服务注册>.<服务消费>和<生命周期>主要从实现原理的角度对.NET Core的依赖注入框架进行了介绍,接下来更进一步,看看该框架的总体设计和实现.在过去的多个版 ...

随机推荐

  1. 五种常见的 PHP 设计模式

    设计模式 一书将设计模式引入软件社区,该书的作者是 Erich Gamma.Richard Helm.Ralph Johnson 和 John Vlissides Design(俗称 “四人帮”).所 ...

  2. UIPickerView滚轮选择器视图

    //必须实现两个协议 //数据源协议必须实现的两个方法 //选取器的输出借口singlePicker,并在故事版中选择该选取器将dataSource和delegate拖入视图控制器与之关联 //@pr ...

  3. crontab每秒执行URL接口

    首先crontab -e打开进行编辑 添加以下代码(默认为每秒执行一次脚本crontab.sh): * * * * * /bin/sh /var/www/aa/crontab.sh 下面是/var/w ...

  4. CSS中的overflow属性

    导读:overflow属性一般用来隐藏超过div范围的元素,包括不隐藏(visible),直接隐藏(hidden),用滚动条隐藏(scroll),自动(aotu)这四个属性.当然overflow的用法 ...

  5. 使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型

    C#反射中的MakeGenericType函数可以用来指定泛型方法和泛型类的具体类型,方法如下面代码所示这里就不多讲了,详情看下面代码一切就清楚了: using System; using Syste ...

  6. Java 导入Excel文件到数据库

    原文:http://www.jb51.net/article/44021.htm 项目中要求读取excel文件内容,并将其转化为xml格式.常见读取excel文档一般使用POI和JExcelAPI这两 ...

  7. js使用模板快速填充数据

    1.html <!DOCTYPE html> <html> <head> <title>模板标签</title> </head> ...

  8. SQL 语句调优 where 条件 数据类型 临时表 索引

    基本原则 避免全表扫描 建立索引 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理 尽量避免大事务操作,提高系统并发能力 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方 ...

  9. 【转】Source Insight的Alt + W键不能使用的解决办法

    转载地址:http://velep.com/archives/607.html 对于Source Insight 3.5,习惯于使用Alt + W组合键并配合数字键来切换文件窗口,带来无比的便利.但是 ...

  10. 前端之CSS(一)

    一.什么是CSS CSS是Cascading Style Sheets,层叠样式表,高大上的说法是用来控制网页数据的表现,可以使网页的表现与数据内容分离.通俗来讲,就是用各种盒子的堆叠实现我们想要的H ...