`

Java自动重载Spring配置文件

    博客分类:
  • Tool
阅读更多
系统中有些配置文件,修改后需要重启应用,这很让人苦恼,也很无奈,谁叫他只加载一次。
下面涉及动态加载配置文件。
需求如下:
         “如果配置文件有改动,自动加载配置文件,重配Spring加载”
需要监控目录下的文件是否变更,可以设置监控间隔时间,比如我这配置发上去,1分钟后自动生效,具体的生效时间可自定义.
代码如下,借助commons-io.jar,毕竟重复造轮子不是我的最爱.
package com.ycl.filter.FileCleaner;

import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;

/**
 * 监控类.
 * @author yangchunlong.tw
 *
 */
public class FileMonitor {

	FileAlterationMonitor monitor = null;

	/**
	 * 默认10妙看一次
	 * @param ob
	 */
	public FileMonitor(FileAlterationObserver ob){
		this(10000,ob);
	}

	/**
	 * 每隔多少时候看一次,观察者
	 * @param fileName
	 * @param ob
	 */
	public FileMonitor(long interval,FileAlterationObserver ob){
		monitor = new FileAlterationMonitor(interval,new FileAlterationObserver[]{ob});
	}

	/**
	 * 添加观察者
	 * @param observer
	 */
	public void addObserver(FileAlterationObserver observer){
		monitor.addObserver(observer);
	}

	/**
	 * 移除观察者
	 * @param observer
	 */
	public void removeObserver(FileAlterationObserver observer){
		monitor.removeObserver(observer);
	}

	/**
	 * 获取所有观察者
	 * @return
	 */
	public Iterable<FileAlterationObserver> getObservers() {
		return monitor.getObservers();
	}

	/**
	 * 启动监控[observer.initialize()]
	 */
	public void start(){
		try {
			monitor.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 停止监控[observer.destroy()]
	 */
	public void stop(){
		try {
			monitor.stop();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * [不做调用]
	 * 具体的监控操作:
	 *     observer.checkAndNotify()
	 */
	private void run(){
		monitor.run();
	}


}


以上是文件监控类,其中涉及到观察者,观察者如下:
package com.ycl.filter.FileCleaner;

import java.io.File;
import java.io.FileFilter;

import org.apache.commons.io.IOCase;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;

public class FileObserver extends FileAlterationObserver{

	private static final long serialVersionUID = 3637219592248717850L;

	/**
	 * 设置观查的文件对象/路径对象
	 * @param directory
	 */
	public FileObserver(String directory) {
		this(new File(directory),(FileFilter)null);
	}

	/**
	 * 设置观查的文件路径,带文件过滤器,比如所有xml文件.
	 *     这里的IOCase是设置文件比较器(排序).[根据系统,可以不用理会]
	 * @param directoryName
	 * @param fileFilter
	 */
	public FileObserver(File fileName, FileFilter fileFilter){
		super(fileName,fileFilter,(IOCase)null);
	}

	/**
	 * 监控启动时初始化方法
	 *   1. 刷新本文件对象
	 *   2. 得到本文件列表
	 *   3. 循环初始化File实体
	 *   4. 设置本文件以及其下的上下级关系
	 */
	 public void initialize() throws Exception {
		super.initialize();
	 }

	 /**
	  * 停止监控
	  * 	默认啥都没做
	  */
	 public void destroy() throws Exception {
		 super.destroy();
	 }


	 /**
	  * 监测文件有没有创建,修改,删除
	  *        并触发相应监听
	  *        如果文件名称比原先的大,那么创建一个实体,并调用onDirectoryCreate/onFileCreate
	  *        如果文件名称比原先的小,那么删除一个实体,并调用onDirectoryDelete/onFileDelete
	  *        如果文件名称和原告的一样,新的文件与原先的文件进行对比,如果文件属性有改变,并调用onDirectoryChange/onFileChange,循环调用自身,可能是文件夹
	  *        如果名称长度排在之后,添加文件,并调用onDirectoryCreate/onFileCreate
	  * 这样就注册了所有文件的监听器
	  */
	 public void checkAndNotify() {
		 super.checkAndNotify();
	 }

	 /**
	  * 添加监听器
	  */
	 public void addListener(final FileAlterationListener listener) {
		 super.addListener(listener);
	 }

	 /**
	  * 移除监听器
	  */
	 public void removeListener(final FileAlterationListener listener) {
		 super.removeListener(listener);
	 }


	 /**
	  * 获取观察者对象的所有监听器
	  */
	 public Iterable<FileAlterationListener> getListeners() {
		 return super.getListeners();
	 }

}


在观察者当中涉及到监听者,比如当文件变化了,有个监听者去执行相应的逻辑,比如重新加载Spring配置文件.
package com.ycl.filter.FileCleaner;

import java.io.File;

import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationObserver;

public class FileListener extends FileAlterationListenerAdaptor{

	@Override
	public void onDirectoryChange(File directory) {
		System.out.println("文件目录变更了:"+directory.getAbsolutePath());
	}

	@Override
	public void onDirectoryCreate(File directory) {
		System.out.println("文件目录创建了:"+directory.getAbsolutePath());
	}

	@Override
	public void onDirectoryDelete(File directory) {
		System.out.println("文件目录删除了:"+directory.getAbsolutePath());
	}

	@Override
	public void onFileChange(File file) {
		System.out.println("文件变更了:"+file.getAbsolutePath());
	}

	@Override
	public void onFileCreate(File file) {
		System.out.println("文件创建了:"+file.getAbsolutePath());
	}

	@Override
	public void onFileDelete(File file) {
		System.out.println("文件删除了:"+file.getAbsolutePath());
	}

	@Override
	public void onStart(FileAlterationObserver observer) {
		System.out.println("开始监听:"+observer.getDirectory());
	}

	@Override
	public void onStop(FileAlterationObserver observer) {
		System.out.println("停止监听:"+observer.getDirectory());
	}

}


万事俱备了,以下是测试代码:
package com.ycl.filter.FileCleaner;

public class TestFileMonitor {

	public static void main(String args[]){
		FileObserver ob = new FileObserver("D:\\test");
		FileListener listener = new FileListener();
		ob.addListener(listener);
		FileMonitor monitor = new FileMonitor(ob);
		monitor.start();
	}
}


监听某个目录下的文件,如果不需要监听,可以调用stop()方法。比如我可以在配置里面设置这个参数来控制是否需要动态加载Spring配置文件.
测试结果如下:
...
文件目录创建了:D:\test\bbb
停止监听:D:\test
开始监听:D:\test
文件目录删除了:D:\test\bbb
文件目录创建了:D:\test\新建文件夹
停止监听:D:\test
开始监听:D:\test
文件目录创建了:D:\test\cccc
文件目录删除了:D:\test\新建文件夹
停止监听:D:\test
开始监听:D:\test
文件创建了:D:\test\cccc\新建 文本文档.txt
停止监听:D:\test
开始监听:D:\test
文件创建了:D:\test\cccc\abc.test
文件删除了:D:\test\cccc\新建 文本文档.txt
停止监听:D:\test
开始监听:D:\test
文件删除了:D:\test\cccc\abc.test
文件目录删除了:D:\test\cccc
停止监听:D:\test

可以返复操作此目录下的文件或者文件夹,这里都能监听到此目录下文件的变化.
分享到:
评论
28 楼 wkshippou 2011-06-29  
包名大写,牛白!
27 楼 richit 2011-06-25  
kyfxbl 写道
脱离需求啊,有什么场景会边跑边改spring配置文件吗?

还是有可能的,在Dev阶段,大项目的时候,分层很多,配置文件很多,有时候不免会忘记配置一些类。
26 楼 坏孩子 2011-06-24  
a123159521 写道
如果只是java文件修改了,如何加载。。。
feiyu86 写道
能写下具体怎么加载吗?
如果只是java文件修改了,如何加载。。。

具体的加载方式需要了解Spring对bean的生命周期,我说下思路,具体的自已去实现。
如果文件是新加的xml,则可以新建一个Application,指定其父Application.
如果文件是删除的xml,则可以销毁一个Application.
如果文件是修改的xml,则需要检测文件的修改点,比哪BeanA做了变更,则可以重新加载BeanA,放设置到Application中,其中引用BeanA的Bean,如果需要更新的,则需要重新初始化它的引用。



你怎么知道bean对应的xml文件?反射获取还是改了spring的代码?
25 楼 feiyu86 2011-06-24  
jsjmz 写道
LZ 有个东西叫着 apache commons configuration
你可以使用之
e.g.
    <bean id="....config" class="org.apache.commons.configuration.XMLConfiguration">
        <constructor-arg type="java.lang.String" value="XXXX.xml"/>
        <property name="reloadingStrategy">
            <bean class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
        </property>
    </bean>



回去研究下。
24 楼 a123159521 2011-06-24  
如果只是java文件修改了,如何加载。。。
feiyu86 写道
能写下具体怎么加载吗?
如果只是java文件修改了,如何加载。。。

具体的加载方式需要了解Spring对bean的生命周期,我说下思路,具体的自已去实现。
如果文件是新加的xml,则可以新建一个Application,指定其父Application.
如果文件是删除的xml,则可以销毁一个Application.
如果文件是修改的xml,则需要检测文件的修改点,比哪BeanA做了变更,则可以重新加载BeanA,放设置到Application中,其中引用BeanA的Bean,如果需要更新的,则需要重新初始化它的引用。
23 楼 feiyu86 2011-06-24  
能写下具体怎么加载吗?
如果只是java文件修改了,如何加载。。。
22 楼 坏孩子 2011-06-23  
楼主没有把如何重新加载bean的代码贴出来,直接刷整个context速度很慢,还不如直接重启
21 楼 xwf2010_good 2011-06-23  
开发的时候 自己修改配置以后 还不如写个main手动加载一下更方便。
20 楼 sking945 2011-06-23  
LZ,使用条件只有一个,那就是监听其他服务器是否正常使用。对于正在使用的服务,这样进行修改配置文件重新加载,肯定会出问题的。。。。
19 楼 newvirus 2011-06-23  
代码不错 不过实际应用中应用的很少 
18 楼 a123159521 2011-06-23  
BruceXX 写道
像这种非动态的还不靠谱。。。试下用spring加载groovy,ruby之类的。。

使用动态语言是不错的选择,这个也看你应用的场景。
现在有两种模式,一种是推,推就是说我有新闻,我会给每一家都发放报纸。[肯定有新闻]
                一种是拉,拉就是说只看浙江晚报,我去你家取。[可能没新闻]
比如,文件变化了,我告诉你我变化了,所有使用到我的关系户,你们监听到了,做相应的变更吧.
比如,文件变化了,我每一次去检测一下,有没有变化,如果变化了,我自己做相应的变更.
当然不同的需求,不同的业务,就会有不同的解决方案。
17 楼 a123159521 2011-06-23  
jsjmz 写道
LZ 有个东西叫着 apache commons configuration
你可以使用之
e.g.
    <bean id="....config" class="org.apache.commons.configuration.XMLConfiguration">
        <constructor-arg type="java.lang.String" value="XXXX.xml"/>
        <property name="reloadingStrategy">
            <bean class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
        </property>
    </bean>

嗯,这个不错,应用了文件变更策略.
Spring重载bean为什么会产生多代的bean呢,不知道你有没有看过Spring的源码。bean一般只初始化一次,如果配置文件重载了,你覆盖以前的bean便是了.
如果业务逻辑正在处理,你把bean变更了,会不会对业务产生影响。Spring使用的是并发Map,支持多线程并发操作,如果当前业务得到的是“老”的bean,那么走“老”的逻辑,如果得到的“新”的bean,走的是“新”的逻辑.
16 楼 BruceXX 2011-06-23  
像这种非动态的还不靠谱。。。试下用spring加载groovy,ruby之类的。。
15 楼 xpfnihao 2011-06-23  
commons-io.jar能给我一个不?我觉着这个功能要是实现了,开发的时候就不用总重启了,耽误时间,想研究下
xpfnihao@163.com
14 楼 hpsysljt 2011-06-23  
楼主其实就是想实现一个类似wtp的动态加载配置文件的功能,提升开发效率,无关生产环境、需求之流
13 楼 JE帐号 2011-06-23  
问题有复杂化的倾向...
也就是说,运行一段时间后,你的Spring容器里会有第1次配置时的产生的bean以及第n次产生的bean.同时如果bean的scope又不同的话,或者scope不是singleton 这样的,同一个bean可能会有多个实现版本在运行,会不会引发一些冲突之类?

结果是,每次你发布spring配置文件的时候,除了要检查语义上的完备性,还给去检查业务与逻辑的冲突.这个责任由谁来负责?
12 楼 ferly_j 2011-06-23  
没看到跟spring有什么关系
11 楼 mayEyeInfo 2011-06-23  
支持楼主!虽然重载spring配置文件应用型不高,不过可以检测某些文件的改变!
10 楼 jsjmz 2011-06-23  
LZ 有个东西叫着 apache commons configuration
你可以使用之
e.g.
    <bean id="....config" class="org.apache.commons.configuration.XMLConfiguration">
        <constructor-arg type="java.lang.String" value="XXXX.xml"/>
        <property name="reloadingStrategy">
            <bean class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
        </property>
    </bean>
9 楼 handong890 2011-06-23  
楼主可以看看jrebel是不是你需要的

相关推荐

    Java进程配置文件Reload

    4. **Spring Boot的自动配置**:在Spring Boot应用中,我们可以利用`spring-boot-devtools`模块的特性实现配置文件的热加载。它默认开启文件系统监听,当`application.properties`或`application.yml`更改时,会自动...

    java类重载,可以用于热更新

    Java类重载是面向对象编程中的一个重要概念,它允许我们在同一个类中定义多个同名方法,...如果你需要更深入地学习这个主题,建议查阅相关的Java教程,实践编写和测试类重载的方法,同时探索如何配置和使用热更新工具。

    struts2配置文件详细说明

    - `struts.configuration.xml.reload`设定是否在配置文件更改后自动重载,`true`适合开发环境。 3. **开发模式与调试**: - `struts.devMode`设置为`true`,启动开发模式,提供详细的错误信息和更友好的调试体验...

    Spring系列面试题129道(附答案解析)

    Spring配置文件是XML格式的文件,用于定义对象及其依赖关系,通过配置文件,Spring IoC容器可以管理这些对象的生命周期。 7、Spring应用程序有哪些不同组件? Spring应用程序的组件主要包括: - Beans:在Spring ...

    Java_Spring引导教程列表.zip

    通过解压并分析这个文件,我们可以学习到如何构建一个Spring Boot应用,包括设置主应用类、配置文件、添加依赖、编写控制器、数据库集成、RESTful API设计等关键环节。 1. **Spring Boot入门**:首先,你需要了解...

    java开发方面的学习,包括Java基础部分、高级部分、以及spring、springboot、springcloud.zip

    Java开发是软件行业中不可或缺的一部分,尤其在企业级应用领域,Spring框架及其衍生技术Spring Boot和Spring Cloud更是占据了主导地位。本资料包包含了Java基础、高级部分以及Spring、Spring Boot和Spring Cloud的...

    狂神说Java系列笔记.rar

    2. **25、SpringBoot入门及原理.pdf**:SpringBoot是Java企业级应用开发的热门框架,简化了Spring的配置和启动过程。这份笔记涵盖了SpringBoot的基本使用,如起步依赖、自动配置、内嵌Web服务器,以及SpringBoot的...

    大数据面试宝典包含java基础和spring面试题

    - 提供自动配置、起步依赖管理等功能。 #### 三、大数据技术知识点 ##### 1. Hadoop生态系统 - **Hadoop**是分布式存储和计算框架。 - 主要组件包括:HDFS(分布式文件系统)、MapReduce(分布式计算框架)等。 #...

    技术文档JAVAspring

    【Java Spring 技术文档概览】 在Java Spring框架中,开发者经常需要处理HTTP请求,了解GET和POST请求的区别至...在Spring框架中,字符串常用于构建SQL语句、配置文件等,理解其特性和不可变性对于优化代码至关重要。

    Spring Boot参考指南

    7. **YAML与Properties配置**:Spring Boot支持YAML和Properties两种配置文件格式,YAML提供了更友好的层次结构,而Properties则是传统的键值对形式。 8. **Spring Boot Actuator的安全性**:Actuator的端点默认...

    spring-tool-suite-3.9.8.RELEASE-e4.11.0-win32-x86_64.zip

    3. **Spring配置编辑器**:专用的XML编辑器支持Spring配置文件,具有语法高亮、错误检测、自动完成和结构视图等功能,使配置文件的编辑更加直观易懂。 4. **Spring Boot支持**:集成对Spring Boot的全面支持,包括...

    Spring boot 热加载 springloaded-1.2.4.RELEASE JAR包

    1. 添加依赖:在Maven或Gradle的配置文件中,引入SpringLoaded的依赖,确保在编译时和运行时都能使用到。 2. 配置IDE:在IDE的设置中,配置Spring Boot的运行配置,启用SpringLoaded并指定版本。 3. 运行应用:...

    java高频面试题1/java二年开发常问面试题

    在Java中,权限设置通常通过访问控制修饰符(public, protected, private, default)和访问权限配置文件(如Java Policy)来控制。权限的时效性取决于代码执行环境和安全策略的配置。 3. **Spring Boot简介**: ...

    Spring boot web 访问

    这是一个强大的开发工具,提供了实时重载应用功能,当源代码发生改变时,无需手动重启服务器,应用会自动刷新。要使用DevTools,只需要在项目中加入`spring-boot-devtools`依赖即可。但是要注意,由于DevTools会开启...

    Spring-Reference_zh_CN(Spring中文参考手册)

    13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form标签 ...

    spring-boot-reference-guide-zh.pdf

    Spring Boot根据类路径中的jar和配置文件,自动配置Spring应用。例如,如果在类路径下发现了`HSQLDB`,那么它就会自动配置内存数据库。 5. **Actuator**: Actuator是Spring Boot的一个重要组件,它提供了健康...

    idea+springboot+springloaded热部署例子

    首先,Idea是JetBrains公司出品的一款强大的Java开发集成工具,它提供了丰富的功能,包括代码高亮、自动完成、调试等,特别适合于Spring框架的开发。 Spring Boot是由Pivotal团队提供的全新框架,其设计目标是用来...

    springloaded-1.2.6实现spring热部署,最全的教程

    总结,SpringLoaded为Spring应用提供了高效的热部署解决方案,通过实时类的重载,大大加快了开发周期。理解其工作原理和使用方法,能帮助开发者更好地利用这一工具提升开发效率。在实践中,应结合具体项目情况灵活...

    Spring Boot 参考指南

    - **Application Properties**:Spring Boot 支持将配置文件中的属性映射到 Java 对象。 - **多环境配置**:支持多环境配置,例如开发、测试和生产环境。 - **YAML vs Properties**: - **加载 YAML 文件**:...

    play+spring+jpa

    8. `main.scala.conf`或`Application.java`:Play应用的主配置文件或启动类,初始化Spring容器。 通过运行这个示例项目,开发者可以学习如何在Play框架中集成Spring和JPA,理解它们之间的协作方式,以及如何使用...

Global site tag (gtag.js) - Google Analytics