spring 用什么spring4 读取配置文件件dom4j吗

模拟Spring阐述依赖注入的思想以及的内部的实现原理(读取配置文件,通过反射进行装配和依赖注入)
&*&想分层,把不同的层次作用以及之间的关系给别人说一遍。
&*&例如要想在数据库添加一个用户,一开始最土的方法是直接在main方法里面写数据库的连接,写直接写add一个用户,后来人们想到至少分一个层次出来即model层,但是添加的方法add写到
&*&model层的话需要new一个对象才能使用这个方法,所以人们又想到对于用户的管理层,通过UserService调用User,之后添加用户会把User添加到DB中,也就是所UserService
&*&会访问User以及数据库DB。最初是这样的,但是这样不合理。如果我们想跨越数据库平台,我写的这个Userservice这个add方法呢,既能往mysql里面存,也能往Oracle中存,也
&*&可以往其他的数据库中存,那么这一个方法肯定是涵盖不了的,除非在里面写一大堆的if,所以更好的方法是抽象出来一个对数据库的管理层,这个我们可以称为DAO层,这里为UserDAO层
&*&由UserDAO负责和User以及数据库DB打交道(把User存到数据库中)对于UserService只需要访问UserDAO层,对外只提供UserService接口,由UserService来调用UserDAO
&*&DAO层提供一个对数据库的屏蔽作用,例如底层数据库变了,只要变UserDAO就可以了。
&*&那么怎样实现跨数据库平台呢?我们在DAO层中的写UserDAO类,写成public&class&UserDAO{里面写&public&void&save(User&user){}方法},但是这样的话把UserDAO写死了,因为save
&*&方法里面写了连接MySQL的代码,要想连接Oracle则需要改save方法里面的代码,把它换成连接Oracle的代码,这样比较麻烦。那怎么才能实现呢?才能变的灵活了?办法是面向抽象的编程,也就是面向接口的编程呢个,即把public&class&UserDAO
&*&该成public&interface&UserDAO{},接下来再分一个DAO的实现,实现了UserDAO&接口,然后实现里面的save方法。然后当我们使用UserService是对接口进行编程,userDAO&=&new&UserDAOImpl();现在灵活性就出来了,要想实现跨数据库平台
&*&就可以多写几个UserDAO的实现,想连接mysql写UserDAOMysqlImpl的UserDAO的实现,相连接Oracle我们就写UserDAOOracleImpl的UserDAO的实现。然后Service层中的UserService需要用mysql存数据的时候就new&UserDAOMysqlImpl()
&*&需要用Oracle的时候就new&UserDAOOracleImpl()这个就叫做面向抽象的编程,原来的话就是写死的,现在就灵活了,相连接那个数据库就new哪个。
&*&假如说我有好多好多的DAO以及Service
&*&添加不同对象的管理,例如我想添加对老师的管理,就需要添加TeacherService,如果添加对课程的管理,就需要添加CourceService
&*&对应的子道中需要添加TeacherDAO,还需要添加TeacherDAOImpl,
&*&添加对学生的管理,就需要添加对学生的管理,需要添加StudentService,还需要添加StudentDAO,还需要
&*&添加其实现。这样就会产生很多的DAO。怎样管理不同对象的DAO呢,可以通过一个工厂来进行管理,就需要用到工厂模式
&*&这样其实也比较麻烦因为每一个不同的DAO都要产生不同的工厂,既然这样的话不如来一个大的工厂,把我们所有的具体的
&*&DAO东西都用这个大的工厂来产生。这个工厂呢要求比较灵活的产生这些DAO,那么怎样实现呢?需要用配置文件来实现,用XML文件,那么就要学习怎样读取XML文件?
1.首先讲解dom4j 解析XML的过程:
&&&& 1.引入jar包,jdom-1.1.jar。
&&&& 2.把要解析的XML文件放到项目工程的src下面,代码如下:
&?xml version="1.0" encoding="UTF-8"?&
&disk name="C"&
&capacity&8G&/capacity&
&directories&200&/directories&
&files&1580&/files&
&disk name="D"&
&capacity&10G&/capacity&
&directories&500&/directories&
&files&3000&/files&
写解析jdom的方法:
import java.util.L
import org.jdom.*;
import org.jdom.input.SAXB
public class sample1 {
public static void main(String[] args) throws Exception{
SAXBuilder sb=new SAXBuilder();
//构造文档对象
Document doc=sb.build(sample1.class.getClassLoader().getResourceAsStream("test.xml"));
//获取根元素HD
Element root=doc.getRootElement();
//取名字为disk的所有元素
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");//获取属性为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-----------------------------------
2.使用反射的思想和jdom解析XML文件模拟Spring容器初始解析配置文件的过程,以及搞明白什么是IOC/DI
在不用Spring的时候,我们在Service调用DAO,需要在UserService里面把new Dao层的对象。例如private UserDao userDAO = new UserDAOImpl();有了容器后容器帮我们把DAO层注入到Service层。怎么注入的?我们看下面的代码:
下面是我的整个项目工程:
这里给出部分代码:
package com.lp.
import com.lp.model.U
//UserDao负责把对象存到不同的数据库中去,考虑为什么写成接口,而不写成一个类?
//答案是:为了实现跨数据库,面向抽象的编程
public interface UserDao {
public void save(User user);
package com.lp.dao.
import com.lp.dao.UserD
import com.lp.model.U
//UserDAOImpl负责和不同的数据库打交道,为了实现跨数据库,我们可以多写几个UserDao的实现
//例如mysql的连接就写一个UsermysqlDAO的实现,其它数据库的实现就写其他数据库的实现
public class UserDAOImpl implements UserDao {
public void save(User user) {
//这里写不同的数据库连接的实现
//Hibernate
System.out.println("user saved!");
Service层:
package com.lp.
import com.lp.dao.UserD
import com.lp.model.U
import com.lp.dao.impl.UserDAOI
public class UserService {
//private UserDao userDAO = new UserDAOImpl();
private UserDao userDAO;//有了配置文件就不用向上面的那样new了,
public UserDao getUserDAO() {
return userDAO;
public void setUserDAO(UserDao userDAO) {
this.userDAO = userDAO;
//向数据库中添加一个用户,只要通过调用UserDAO,然后通过调用save()方法就能实现
public void add(User user){
userDAO.save(user);
&模拟Spring里面的ApplicationContext.xml在src下面放置要解析的配置文件bean.xml,代码:
&?xml version="1.0" encoding="UTF-8"?&
&!-- 把 UserDAOImpl读出来放到DAO里面去,也就是new一个Class的对象为u的--&
&bean id="u" class="com.lp.dao.impl.UserDAOImpl"/&
&bean id="userService" class="com.lp.service.UserService"&
&!-- 在userService有一个属性,这个属性就是userDAO,更准确点就是setUserDAO方法,
也就是说spring可以把userService下面的userDAO注入进来,装配到一块。
&property name = "userDAO" bean="u"&&/property&
跟上面读取配置文件一样。这个类实现了一个接口叫做。叫做工厂。
package com.lp.
* 存放各种各样的DAO的工厂
public interface BeanFactory {
public Object getBean(String name);//每个bean都有一个名字通过id指定
&&& 为了模拟spring怎样读取配置文件还需要读取配置文件的类,这里我们自己创建一个包叫Com.lp.spring这里存放了里面的类:这里类:ClassPathXmlApplicationContext:使用这个类来读取的配置文件,实现BeanFactory,实现里面获取bean对象的方法:
package com.lp.
import java.lang.reflect.M
import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXB
* ClassPathXmlApplicationContext是模拟spring的类
public class ClassPathXmlApplicationContext implements BeanFactory {
//用Map容器存储bean的名字和值
private Map&String , Object& beans = new HashMap&String, Object&();
//IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() throws Exception {
SAXBuilder sb=new SAXBuilder();
//解析beans.xml文件
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //构造文档对象
//获取根元素beans
Element root=doc.getRootElement();
List list=root.getChildren("bean");
//取名字为bean的所有的小孩存放到List集合当中
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的值
//把class="com.lp.dao.impl.UserDAOImpl"生成一个对象 o
Object o = Class.forName(clazz).newInstance();
//System.out.println(id);
//System.out.println(clazz);
beans.put(id, o);//然后把id和对应的对象放到容器里面
//用了反射思想
for(Element propertyElement : (List&Element&)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject = beans.get(bean);//UserDAOImpl instance
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);//通过这句话构造setUserDAO()方法
System.out.println("method name = " + methodName);
Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);//setUserDAO(UserDao.class)
m.invoke(o, beanObject);
* 从容器中把这个对象取出来
public Object getBean(String id) {
return beans.get(id);
&*&测试类专门写在另外一个source包里面,然后引入junit.jar文件,然后右键
&*&要测试的类,选择jUnitCase创建测试类
&*&使用bean容器
package com.lp.
* 测试类专门写在另外一个source包里面,然后引入junit.jar文件,然后右键
* 要测试的类,选择jUnitCase创建测试类
import static org.junit.Assert.*;
import org.junit.T
import com.lp.dao.UserD
import com.lp.model.U
import com.lp.spring.BeanF
import com.lp.spring.ClassPathXmlApplicationC
public class UserServiceTest {
public void testAdd() throws Exception {
//把容器给new出来
BeanFactory factory = new ClassPathXmlApplicationContext();
//思考怎样使UserService也不用new?答案就是交给工厂BeanFactory,从配置文件里面读出来
//UserService service = new UserService();
UserService service = (UserService) factory.getBean("userService");
/*UserDao userdao = (UserDao) factory.getBean("u");
service.setUserDAO(userdao);//把这个对象注入到service中
User u = new User();
service.add(u);
运行结果:
method name = setUserDAOuser saved!
以前要写的代码与在容器中配置的文件对应关系:
&bean id="userService" class="com.lp.service.UserService"&
&property name = "userDAO" bean="u"&&/property&
&/bean&这段代码的意识:userService中调用userDao:
&&& UserService&service&=&new&UserService();
&&& service.setUserDAO(userdao);
&& 这两句代码。
&& 意思:通过配置文件把userdao和service&这两个对象的关系设定好了,不用硬性的编码,也就是把userDao装配到service里面了。
IOC/DI原理:IOC(inverse&of&controll)控制反转:通过上面的例子可以看出,以前Service层中想调用Dao层中的方法,需要在Service层中new出来,是由自己控制的,而现在由Spring容器控制创建初始化bean(对象),维护bean与bean之间的关系,权利从程序中转移到了Spring容器,而程序本身不需要再维护。
DI(dependency&injection)依赖注入:实际上和IOC是一个概念,为了更准确的描述Spring的核心技术,对象之间的关系是相互依赖的,一些通用的bean组件可以依赖容器注入进来。原理:也可以说成反射注入,通过使用解析XML技术,以及反射的机制,构造真实实例对象,构造set方法把userDAO这个bean注入到userService中。
好处:耦合性大大的降低,用配置文件注入bean,修改起来方便,不用硬性的修改代码。
阅读(...) 评论()spring(19)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:72225次
积分:1364
积分:1364
排名:千里之外
原创:56篇
转载:77篇
评论:15条
(2)(2)(1)(1)(1)(1)(2)(3)(6)(4)(7)(1)(2)(2)(1)(3)(1)(3)(19)(13)(21)(18)(17)(2)1370人阅读
需要用到的jar包,dom4j的jar包,网上可以下载
配置文件applicationContext.xml的配置如下:
&?xml version="1.0" encoding="UTF-8"?&
&bean id="car" class="com.test.spring.dom4j.Car"&&/bean&
&bean id="plane" class="com.test.spring.dom4j.Plane"&&/bean&
&bean id="train" class="com.test.spring.dom4j.Train"&&/bean&
在ClassPathXmlApplicationContext类的构造方法中,构造方法参数为配置文件的路径名,如在本例中:com/test/spring/dom4j/applicationContext.xml &. 接着在构造方法中,
SAXReader reader = new SAXReader();
Document doc = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));
Element root = doc.getRootElement();
List list = root.elements();
//以下为遍历配置文件中的所有节点,读取每个节点的 id 和 class 属性
for(int index= 0 ; index & list.size();index++){
Element bean = (Element) list.get(index);
String id = bean.attributeNodeName("id");
String className = bean.attributeNodeName("class");
Object o = Class.forName(className).newInstance();
map.put(id,o);
map为一个hashmap, Map&String,Object& map = new HashMap&Sting,Object&();
然后提供一个返回map中值的方法,
public Object getBean(String id){
return map.get(id);
差不多完成了。创建一个Test类来测试一下。
public Test{
public static void main(String[] args){
BeanFactory beanFactory = new ClassPathXmlApplicationContext("com/test/spring/dom4j/applicationContext.xml");
VehicleFactory v = beanFactory.getBean("car");//plane,train
其中,ClassPathXmlApplicationContext 类实现了BeanFactory 接口,该接口中只定义了一个getBean(String id)方法
Car , Plane , Train 类实现了 VehicleFactory 接口,该接口只定义了一个run()方法。
如此就结束了。简单的模拟了spring的bean工厂机制
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:197443次
积分:1680
积分:1680
排名:千里之外
原创:35篇
评论:36条
(3)(2)(1)(1)(3)(1)(1)(1)(1)(2)(1)(1)(2)(1)(1)(1)(1)(1)(1)(6)(3)(4)使用dom4j读取spring配置文件
public class ItcastClassPathXmlApplicationContext
private List beanDefines = new
ArrayList();
public ItcastApplicationContext(String
filename){
init(filename);
private void init(String
filename){
SAXReader saxReader = new SAXReader();&&
Document document=&&
URL xmlpath =
this.getClass().getClassLoader().getResource(filename);
document = saxReader.read(xmlpath);
Map nsMap = new HashMap();
nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间,下面要用ns,才能找到指定元素!
XPath xsub =
document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap);//设置命名空间
List beans = xsub.selectNodes(document);//获取文档下所有bean节点
for(Element element: beans){
&&&&&&&&&&&
String id = element.attributeValue("id");//获取id属性值
&&&&&&&&&&&
String clazz = element.attributeValue("class");
//获取class属性值&&&&&&&
&&&&&&&&&&&
BeanDefinition beanDefine = new BeanDefinition(id,
&&&&&&&&&&&
beanDefines.add(beanDefine);
}catch(Exception e){&&
&&&&&&&&&&&
e.printStackTrace();
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Java web(4)
了解过-Boot这个技术的,应该知道Spring-Boot的核心配置文件application.properties,当然也可以通过注解自定义配置文件的信息。
Spring-Boot读取配置文件的方式:
一.读取核心配置文件信息application.properties的内容
& & &核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法有两种,都比较简单。
核心配置文件application.properties内容如下:
方式一:使用@Value方式(常用)
注意:在@Value的${}中包含的是核心配置文件中的键名。在Controller类上加@RestController表示将此类中的所有视图都以JSON方式显示,类似于在视图方法上加@ResponseBody。
访问:http://localhost:8088/index1时得到:&方式一:Hello World
SpringBoot&
方式二:使用Environment方式
注意:这种方式是依赖注入Evnironment来完成,在创建的成员变量private Environment env上加上@Autowired注解即可完成依赖注入,然后使用env.getProperty(&键名&)即可读取出对应的值。
访问:http://localhost:8088/index2时得到:&方式二:Hello World
SpringBoot&
二.读取自定义配置文件信息,例如:author.properties
为了不破坏核心文件的原生态,但又需要有自定义的配置信息存在,一般情况下会选择自定义配置文件来放这些自定义信息,这里在resources目录下创建配置文件author.properties
resources/author.properties内容如下:
创建管理配置的实体类:
& &&在@ConfigurationProperties注释中有两个属性:
locations:指定配置文件的所在位置
prefix:指定配置文件中键名称的前缀(我这里配置文件中所有键名都是以author.开头)
& & 使用@Component是让该类能够在其他地方被依赖使用,即使用@Autowired注释来创建实例。
创建测试Controller
注意:由于在Conf类上加了注释@Component,所以可以直接在这里使用@Autowired来创建其实例对象。
访问:http://localhost:8088/test时得到:&Name:Solin---Age:22&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5287次
排名:千里之外
原创:38篇
转载:20篇
(3)(1)(6)(9)(5)(11)(6)(2)(1)(9)(5)}

我要回帖

更多关于 spring4 读取配置文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信