zoukankan      html  css  js  c++  java
  • 使用JDom解析XML文档模拟Spring的配置文件解析

    在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;
    }
    View Code

    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");
        }
    
    }
    View Code

    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");
        }
    
    }
    View Code

    基本的工作已经结束了,下面就是进行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();
            }
    
        }
    
    }
    View Code

    需要提供一个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();
        }
    
    }

    测试结果

     
  • 相关阅读:
    jdk源码调试进去形参没有值
    proxy 简化版本
    spering getBean(),IOC
    彻底清除挖矿程序
    Kworkerd恶意挖矿分析
    怎么让 Android 程序一直后台运行,像 QQ 一样不被杀死
    linux 系统下使用socket进行本地进程间通信
    linux i2c 的通信函数i2c_transfer在什么情况下出现错误
    Java Socket网络编程常见异常(转)
    踩过的坑系列之InputStream.read(byte[])方法
  • 原文地址:https://www.cnblogs.com/xiaoysec/p/4329875.html
Copyright © 2011-2022 走看看