A. java應用(非web應用)中log4j.properties/xml動態修改配置文件,無需重啟,就能立即生效,如何實現
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class BeTestClass {
static String log4jPath;
static Logger log = Logger.getLogger(BeTestClass.class);
static {
PropertyConfigurator.configureAndWatch("log4j.properties", 1000);
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
//PropertyConfigurator.configure(log4jPath);
log.info("----------info");
log.debug("----------debug");
log.error("----------error");
System.out.println("***********************");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
B. spring如何動態載入配置文件,就是配置文件修改了,application.xml如何能讀取到
項目,需要訪問多個資料庫,而且需要在伺服器運行不重新啟動的情況下,動態的修改spring中配置的數據源datasource,在網上找了很多資料,最後找到了適合我的方法,下面總結一下。
spring的配置文件是在容器啟動的時候就載入到內存中的,如果手動改了application.xml,我們必須要重新啟動伺服器配置文件才會生效。而在spring中提供了一個類WebApplicationContext,這個類可以讓你獲得一些bean,可以修改內存中的信息,我就是通過這個類來實現的。下面是我具體的代碼。
package com.southdigital.hospital;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class ChangeSpringConfig extends HttpServlet
{
private String ipAddress = "127.0.0.1";
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//先取得servleContext對象,提供給spring的WebApplicationUtils來動態修改applicationContext.xml
ipAddress = request.getParameter("ipAddress");
System.out.println(ipAddress);
ServletContext servletContext = this.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
ComboPooledDataSource cpds = (ComboPooledDataSource) applicationContext.getBean("dataSource");
cpds.setJdbcUrl("jdbc:mysql://"+ipAddress+":3306/ssh");
}
}
注意:通過這種方法修改applicationContext.xml文件的時候用c3p0,而不可以用dbcp,dbcp不支持動態修改讀取到內存裡面的數據。
spring 3.1已經支持了。
C. JAVA中如何重新載入.properties文件,使其他引用實時改變
*Spring提供的PropertiesLoaderUtils允許您直接通過基於類路徑的文件地址載入屬性資源
*最大的好處就是:實時載入配置文件,修改後立即生效,不必重啟
*/
privatestaticvoidspringUtil(){
Propertiesprops=newProperties();
while(true){
try{
props=PropertiesLoaderUtils.loadAllProperties("message.properties");
for(Objectkey:props.keySet()){
System.out.print(key+":");
System.out.println(props.get(key));
}
}catch(IOExceptione){
System.out.println(e.getMessage());
}
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
D. java熱部署:tomcat運行中,動態修改配置文件(java文件)中的static屬性並生效
<Context path="/tomcatTest" reloadable="true" docBase="E:\workplace\testProject\WebRoot"/>
第一個是容器里的項目path 要加/
第二個參數是你的workplace的路徑,一般是到webroot
寫個context.xml文件,放到項目的META-INF里.context.xml頭部像上面那樣寫就可以
E. Java讀取配置文件的幾種方法
在現實工作中,我們常常需要保存一些系統配置信息,大家一般都會選擇配置文件來完成,本文根據筆者工作中用到的讀取配置文件的方法小小總結一下,主要敘述的是spring讀取配置文件的方法。
一、讀取xml配置文件
(一)新建一個java bean
package chb.demo.vo;
public class HelloBean {
private String helloWorld;
public String getHelloWorld() {
return helloWorld;
}
public void setHelloWorld(String helloWorld) {
this.helloWorld = helloWorld;
}
}
(二)構造一個配置文件
?xml version="1.0" encoding="UTF-8"?
!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ""
beans
bean id="helloBean" class="chb.demo.vo.HelloBean"
property name="helloWorld"
valueHello!chb!/value
/property
/bean
/beans
(三)讀取xml文件
1.利用
ApplicationContext context = new ("beanConfig.xml");
HelloBean helloBean = (HelloBean)context.getBean("helloBean");
System.out.println(helloBean.getHelloWorld());
2.利用FileSystemResource讀取
Resource rs = new FileSystemResource("D:/software/tomcat/webapps/springWebDemo/WEB-INF/classes/beanConfig.xml");
BeanFactory factory = new XmlBeanFactory(rs);
HelloBean helloBean = (HelloBean)factory.getBean("helloBean");
System.out.println(helloBean.getHelloWorld());
值得注意的是:利用FileSystemResource,則配置文件必須放在project直接目錄下,或者寫明絕對路徑,否則就會拋出找不到文件的異常。
二、讀取properties配置文拿鎮件
這里介紹兩種啟敬技術:利用spring讀取properties 文件和利用java.util.Properties讀取
(一)利用spring讀取properties 文件
我們還利用上面的HelloBean.java文件,構造如下beanConfig.properties文件:
helloBean.class=chb.demo.vo.HelloBean
helloBean.helloWorld=Hello!chb!
屬性文件中的"helloBean"名稱即是Bean的別名設定,.class用於指定類來消旁粗源。
然後利用org.springframework.beans.factory.support.來讀取屬性文件
BeanDefinitionRegistry reg = new DefaultListableBeanFactory();
reader = new (reg);
reader.loadBeanDefinitions(new ClassPathResource("beanConfig.properties"));
BeanFactory factory = (BeanFactory)reg;
HelloBean helloBean = (HelloBean)factory.getBean("helloBean");
System.out.println(helloBean.getHelloWorld());
(二)利用java.util.Properties讀取屬性文件
比如,我們構造一個ipConfig.properties來保存伺服器ip地址和埠,如:
ip=192.168.0.1
port=8080
則,我們可以用如下程序來獲得伺服器配置信息:
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("ipConfig.properties");
Properties p = new Properties();
try {
p.load(inputStream);
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("ip:"+p.getProperty("ip")+",port:"+p.getProperty("port"));
F. java如何動態更新一個.class文件,一個.jar文件
java裡面有一個叫動態代理的實現,可以說是動態生成class文件,在調用java裡面的打包命令,應該可以做到。
G. WEB項目改了java文件不會自動更新,改了jsp不會自動更新
原因可能是因為改動了java文件之後,存在錯誤或者引用的jar包有問題專:
1.java compiler選項的設置。大多是選項漏屬選,導致部分代碼修改後不會重新編譯。
2.java build path選項的設置,jar文件引用錯誤或jre版本不對等等。
H. Springboot 使用@RefreshScope 註解,實現配置文件的動態載入
實現配置文件動態讀取的好處不必多說,修改配置文件後不必重啟Application ,想想就開心。
合格調包俠的必備技能,從Maven倉庫引入依賴的Jar包,
搞好配置文件,默認在application.yml /properties 就行,與本功能相關的配置項(採用yml格式)如下:
distributed-id是自定義需要動態部署的配置文件。management:是暴露refresh介面,不加此條配置將無法啟用動態載入配置文件的功能(也就是管你理解不理解,別問,加就對了)。
1.編寫自定義配置文件的Java對象,一定要在類上加@RefreshScope註解
@data是lombok的註解,別的註解不多說。
2.編寫你的conroller ,也一定要加@RefreshScope註解, 不加的話,呵呵,對不起,無法運行。。原因嗎---在這 @RefreshScope not working - Spring Boot - Stack Overflow
我這里是返回配置文件中distributed-id.mechineId的值。
3.到此為止了,簡單吧😒。其實的話,第一步也可以直接在Bean的配置中心(也就是@Configuration註解的類)搞一下,效果是一樣的。
使用這種寫法,就可以不用在配置對象類上加@Component和@RefreshScope。
測試一下啦,啟動應用前,將配置文件設置如下:
運行程序後,在瀏覽器輸入你的測試地址,返回如下,是5沒錯了:
然後找到你編譯後文件,修改配置文件的值,注意是 編譯後的配置文件 就是下圖中灰色文件的位置
修改如下:mechineId修改為4
接下來向 http://localhost:port/actuator/refresh 發送 POST 請求,get請求是無法識別的呦😘,可以看到返回了配置文件中被更改的屬性
測試一下,沒錯了,返回值為4