在J2EE项目中可能会涉及到一些框架的使用,最近接触到了SSH,拿Spring来说配置文件的使用是相当重要的,Spring的配置文件是一个xml文件,Spring是如何读取到配置文件并进行依赖注入的呢?今天先来说说xml文件的解析。

解析xml文件可以使用jdom,下面我以一个小栗子来说说xml文件的解析。

1.首先下载jdom,在这里我以jdom2.0.6为例

2.接下来附上一个xml文档

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="edu.nupt.bbs.UserDAOImp" />
<bean id ="service" class="edu.nupt.bbs.UserService">
<property name="userdao" ref="u" />
</beans>
</beans>

代码模仿的是Spring的配置文件

3.定义一个User类(model)代码如下

package edu.nupt.bbs;

public class User {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
}

4.定义一个UserDAO接口这是一个DAO接口为了方便实验主要提供了addUser和deleteUser接口

package edu.nupt.bbs;

public interface UserDAO {
public void add();
public void delete();
}

5.定义一个UserDAOImp实现了UserDAO接口一开始我不太明白为什么要将UserDAO写成接口的形式可能是为了在不同的数据库上面做到兼容,具体的代码如下,为了简单直观在add方法和delete方法中直接在控制台打印出一段文字

package edu.nupt.bbs;
/**
* 一种UserDAO的实现(在实际的应用中可能是一种数据库对应一种UserDAO实现)
* @author xiaoysec
*
*/
public class UserDAOImp implements UserDAO { @Override
public void add() {
// TODO Auto-generated method stub
System.out.println("user add");
} @Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("user delete");
} }

6.定义UserService类实现User对象的增删,一开始接触J2EE的时候不是很清楚为什么要写这么多看似不需要的类,但是渐渐地会发现这种分层的思想是极为合理的,方便了程序的拓展和维护。

package edu.nupt.bbs;
/**
* 一种UserDAO的实现(在实际的应用中可能是一种数据库对应一种UserDAO实现)
* @author xiaoysec
*
*/
public class UserDAOImp implements UserDAO { @Override
public void add() {
// TODO Auto-generated method stub
System.out.println("user add");
} @Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("user delete");
} }

基本的工作已经结束了,下面就是进行Spring配置文件读取的模拟了,我模仿了Spring中的命名方式定义了:BeanFactory和ClassPathXmlApplicationContext

7.BeanFactory接口 返回的是一个Object对象我们通过xml的id属性作为参数从BeanFactory中取出一个Bean对象。这个接口就像他的名字一样可以把她想象成一个工厂通过id参数为外界提供bean对象。

package edu.nupt.bbs.Spring;
//根据id返回一个bean
public interface BeanFactory {
public Object getBean(String id); }

8.ClassPathXmlApplicationContext

package edu.nupt.bbs.Spring;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.junit.Test; import edu.nupt.bbs.test.JdomTest; public class ClassPathXmlApplicationContext implements BeanFactory {
// 用于存放bean实例对象
private Map<String, Object> map = new HashMap<String, Object>(); // 用于取出bean实例对象
@Override
public Object getBean(String id) {
// TODO Auto-generated method stub
Object o = map.get(id);
return o;
} public ClassPathXmlApplicationContext() {
try {
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(JdomTest.class.getClassLoader()
.getResourceAsStream("jdom.xml")); // 构造文档对象
Element root = doc.getRootElement(); // 获取根元素 beans
List list = root.getChildren("bean");// 取名字为bean的所有元素
for (int i = 0; i < list.size(); i++) {
Element element = (Element) list.get(i);
String id = element.getAttributeValue("id"); // 获取id的值
String clazz = element.getAttributeValue("class");// 获取class的值
// System.out.println(id + ":" + clazz);
try {
Object o = Class.forName(clazz).newInstance();
map.put(id, o);// 将id代表的对象放入map } catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

需要提供一个Map对象作为容器存放生成的bean对象,其实上面的代码就是完成了xml解析以及bean实例对象的生成,并把bean实例对象放在map中,其中用到了Java反射。

<bean id="u" class="edu.nupt.bbs.UserDAOImp" />这是上面代码中存放在List的一个对象,其实就是用反射根据class的值生成实例的对象赋值给u即 UserDAOImp u = new UserDAOImp();

9.测试类

package edu.nupt.bbs.test;

import static org.junit.Assert.*;

import org.junit.Test;

import edu.nupt.bbs.User;
import edu.nupt.bbs.UserDAO;
import edu.nupt.bbs.UserService;
import edu.nupt.bbs.Spring.BeanFactory;
import edu.nupt.bbs.Spring.ClassPathXmlApplicationContext; public class UserServiceTest { @Test
public void addUsertest() {
BeanFactory bf = new ClassPathXmlApplicationContext();
UserDAO userdao = (UserDAO)bf.getBean("u");
UserService service = (UserService)bf.getBean("service");
service.setUserdao(userdao);
service.addUser();
} }

测试结果

 

使用JDom解析XML文档模拟Spring的配置文件解析的更多相关文章

  1. 解析XML文档之三:使用DOM解析

    dom解析方法是将整个xml文档装载到内存当中,然后通过树形结构方式去解析的,这种方式只适合于在pc端的开发,不是很适合手机端的开发,毕竟来说手机的内存是没法跟pc相提并论的. 具体实现步骤如下: 第 ...

  2. 解析XML文档之一:使用SAX解析

    使用sax解析xml方法总结 解析的的xml文档格式如下 <?xml version="1.0" encoding = "UTF-8"?> < ...

  3. Java高级特性 第15节 解析XML文档(3) - JDOM和DOM4J技术

    一.JDOM解析 特征: 1.仅使用具体类,而不使用接口. 2.API大量使用了Collections类. Jdom由6个包构成: Element类表示XML文档的元素 org.jdom: 解析xml ...

  4. 使用JDOM解析xml文档

    一.使用JDOOM解析xml文档 准备工作 1.下载JDOM.jar 包 解析代码如下 import org.jdom2.Attribute; import org.jdom2.Document; i ...

  5. 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)

    众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...

  6. 浅谈用java解析xml文档(四)

    继续接上一文,这一阵子因为公司项目加紧,导致最后一个解析xml文档的方式,还没有总结,下面总结使用dom4J解析xml. DOM4J(Document Object Model for Java) 使 ...

  7. 浅谈用java解析xml文档(三)

    接上一篇,本文介绍使用JDOM解析xml文档, 首先我们还是应该知道JDOM从何而来,是Breet Mclaughlin和Jason Hunter两大Java高手的创作成果,2000年初, JDOM作 ...

  8. DOM4J解析XML文档

    Tip:DOM4J解析XML文档 Dom4j是一个简单.灵活的开放源代码的库.Dom4j是由早期开发JDOM的人分离出来而后独立开发的.与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j ...

  9. dom4j解析xml文档全面介绍

    一.dom4j介绍 dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常非常优秀的Java XML API,具有性能优异.功能强大和极端易用使用的特点, ...

随机推荐

  1. javascript第三课underfind和类型获取

    1.underfind一般发生于变量定义之后未赋值,因此变量的值就为underfind 2.var obj=new object(); 此时使用obj点,可以获取到obj对象的一些方法,使用alert ...

  2. 项目积累——Blockingqueue,ConcurrentLinkedQueue,Executors

    背景 通过做以下一个小的接口系统gate,了解一下mina和java并发包里的东西.A系统为javaweb项目,B为C语言项目,gate是本篇须要完毕的系统. 需求 1. A为集群系统,并发较高,会批 ...

  3. AngularJs(五)从Controller控制器谈谈$scope作用域

    大纲 用于简单示例和简单应用的controller 应用 多个controller应用的作用域问题 controller继承作用域问题 Controller的创建 AngularJs controll ...

  4. 《think in python》学习-5

    think in python -5 think in python -5 条件和递归 求模操作符% 用于整数,可以计算出第一个操作数除以第二个操作数的余数 7%3 #结果是2 求模操作符%有很多用途 ...

  5. sqlserver数据库差异比较

    相信这个功能会对好多网友有帮助,不得不说vs的功能很强大,废话不多说,切入正题 我们可以使用 vs自带的工具比较两个数据库的架构差异和数据差异,这篇文章只是写了架构的差异,我相信看完以后, 如何进行数 ...

  6. SQL初级阶段笔记

    DataBase Management Stystem(数据库管理系统)简称:DBSM:虽然DBSM并不等于数据库,但行业内通常将DBSM称为数据库,所以一般来说数据库就指的是DBSM. 简单来讲DB ...

  7. Eclipse 浏览文件插件- OpenExplorer

    http://blog.csdn.net/w709854369/article/details/6599167 EasyExplorer  是一个类似于 Windows Explorer的Eclips ...

  8. php simple_html_dom 一个iconv错误引起解析中断的问题,貌似内存溢出

    环境: $pageNum = 8; for ($i = 1; $i < $pageNum; $i++) { $html = new simple_html_dom(); $host = 'htt ...

  9. substr(dirname(__FILE__))

    这是discuz中定义论坛安装根目录的一个常量.现在我们就来分析一下这个很简单但是非常实用的常量.     define('DISCUZ_ROOT', substr(dirname(__FILE__) ...

  10. 织梦list文章列表按权重排序

    织梦的文章列表按权重排序 DEDECMS(织梦)5.6系统支持文档权重weight排序,可以在模板中使用: {dede:arclist row='10' titlelen='50' orderby=' ...