假设我们先写一个模块,这个模块是用户管理。

以后会有很过个Dao存在,取Dao的时候需要改代码,比较不方便,可以将Dao写在XML然后去读取也可以。

以前的解决方式是工厂类,FactoryMethod,但是也会很慢麻烦(每个Dao一个Factory)

我们可以做个很大的工厂,用来获取所有的Dao。其实就是一个大的配置文件。

我们模拟spring的配置文件,我们读取XML。

读取XML的样例和方法(使用的Jdom开源API)
导入jdom的jar包jdom.jar。
测试XML-text.xml:

<?xml version="1.0" encoding="UTF-8"?>
<HD>
<disk name="C">
<capacity>8G</capacity>
<directories>200</directories>
<files>1580</files>
</disk>


<disk name="D">
<capacity>10G</capacity>
<directories>500</directories>
<files>3000</files>
</disk>
</HD>



测试类:


package cn.edu.hpu.jdom;

import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXBuilder;


public class Sample {
public static void main(String[] args) throws Exception{
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build(Sample.class.getClassLoader().getResourceAsStream("text.xml"));//构建文档对象
Element root=doc.getRootElement();//获取根元素
List list=root.getChildren("disk");//获取名字为disk的所有元素
for(int i=0;i<list.size();i++)
{
Element element=(Element)list.get(i);
String name=element.getAttributeValue("name");
String capacity=element.getChildText("capacity");//取disk子元素capacity的内容
String directories=element.getChildText("directories");
String files=element.getChildText("files");
System.out.println("磁盘信息:");
System.out.println("分区盘符:"+name);
System.out.println("分区容量:"+capacity);
System.out.println("目录数:"+directories);
System.out.println("文件数:"+files);
System.out.println("-----------------------------------");

}
}
}




运行结果:


磁盘信息:


分区盘符:C


分区容量:8G


目录数:200


文件数:1580


-----------------------------------


磁盘信息:


分区盘符:D


分区容量:10G


目录数:500


文件数:3000


-----------------------------------




能够读取XML了,下面我们来

模拟spring来读取beans.xml:


User.java:


package cn.edu.hpu.model;

public class User {
private String username;
private String password;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}


User.Dao:


package cn.edu.hpu.dao;

import cn.edu.hpu.model.User;


public interface UserDao {


public void save(User u);
}


UserDaoImpl.java:
package cn.edu.hpu.dao.Impl;


import cn.edu.hpu.model.User;


public class UserDaoImpl implements UserDao{


public void save(User u) {
System.out.println("add success!!");
}


}



UserService.java:


package cn.edu.hpu.service;

import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.dao.Impl.UserDaoImpl;
import cn.edu.hpu.model.User;


public class UserService {


private UserDao userDao= new UserDaoImpl();

public UserDao getUserDao() {
return userDao;
}


public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}


public void add(User u){
this.userDao.save(u);
}
}



对于UserService中的:


private UserDao userDao= new UserDaoImpl();你调用的是谁的DaoImpl,add方法里面就调用的谁的save方法。


可以把UserDaoImpl()写在配置文件中,将来从配置文件读出来,灵活性就会好很多,你要改它的实现只要改配置文件就可以了。



我要做的事情就是从配置文件beans.xml读出这部分内容放在UserService中的UserDao后面。



beans.xml:


<beans>
<bean id="u" class="cn.edu.hpu.dao.Impl.UserDaoImpl" />
<!--
<bean id="userService" class="cn.edu.hpu.service.UserService" >
<property name="userDao" bean="u"/>
</bean>
-->
</beans>

先写一个模拟spring加载配置文件返回对应实体类的类:


package cn.edu.hpu.spring;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;


public class ClassPathXmlApplicationContext implements BeanFactory{
//启动程序的时候先把配置文件的数据读取到容器里
//需要使用的时候再取出来

private Map<String,Object> beans=new HashMap<String,Object>();

public ClassPathXmlApplicationContext() throws Exception{
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
Element root=doc.getRootElement();//获取根元素
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");
String clazz=element.getAttributeValue("class");
System.out.println(id+":"+clazz);
Object o =Class.forName(clazz).newInstance();//newInstance默认调用无参构造器
beans.put(id,o);
}
}

public Object getBean(String id) {

return beans.get(id);
}



}



其中BeanFactiry接口:


package cn.edu.hpu.spring;


public interface BeanFactory {
public Object getBean(String name);
}



测试:


package cn.edu.hpu.service;
import org.junit.Test;


import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.model.User;
import cn.edu.hpu.spring.BeanFactory;
import cn.edu.hpu.spring.ClassPathXmlApplicationContext;


public class UserServiceTest {

@Test
public void testAdd() throws Exception{
/*
//这里是传统方式获取UserService
UserService service=new UserService();
User u=new User();
service.add(u);*/
BeanFactory factory=new ClassPathXmlApplicationContext();

UserService userService=new UserService();
UserDao userDao=(UserDao)factory.getBean("u");
userService.setUserDao(userDao);
User u=new User();
userService.add(u);
}
}




结果:


u:cn.edu.hpu.dao.Impl.UserDaoImpl


add success!!


模拟了一个Spring框架的过程,让大家更加理解Spring框架的运行机制