2009-02-10 24 views

Trả lời

7

Tôi không khuyên bạn nên làm điều đó. Bạn mong đợi điều gì sẽ xảy ra với đậu đơn mà cấu hình của chúng được sửa đổi? Bạn có mong đợi tất cả các đơn vị để tải lại? nhưng một số đối tượng có thể chứa tham chiếu đến những người độc thân đó.

Xem bài đăng này cũng Automatic configuration reinitialization in Spring

10

Vâng, nó có thể hữu ích để thực hiện như một tải lại bối cảnh trong khi thử nghiệm ứng dụng của bạn.

Bạn có thể thử phương thức refresh của một trong các lớp AbstractRefreshableApplicationContext: nó sẽ không làm mới hạt đã được instanciated trước đó của bạn, nhưng lệnh gọi tiếp theo trong ngữ cảnh sẽ trả về các hạt được làm mới.

import java.io.File; 
import java.io.IOException; 

import org.apache.commons.io.FileUtils; 
import org.springframework.context.support.FileSystemXmlApplicationContext; 

public class ReloadSpringContext { 

    final static String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
     "<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\"\n" + 
     " \t\"http://www.springframework.org/dtd/spring-beans.dtd\">\n"; 

    final static String contextA = 
     "<beans><bean id=\"test\" class=\"java.lang.String\">\n" + 
      "\t\t<constructor-arg value=\"fromContextA\"/>\n" + 
     "</bean></beans>"; 

    final static String contextB = 
     "<beans><bean id=\"test\" class=\"java.lang.String\">\n" + 
      "\t\t<constructor-arg value=\"fromContextB\"/>\n" + 
     "</bean></beans>"; 

    public static void main(String[] args) throws IOException { 
     //create a single context file 
     final File contextFile = File.createTempFile("testSpringContext", ".xml"); 

     //write the first context into it 
     FileUtils.writeStringToFile(contextFile, header + contextA); 

     //create a spring context 
     FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
      new String[]{contextFile.getPath()} 
     ); 

     //echo the bean 'test' on stdout 
     System.out.println(context.getBean("test")); 

     //write the second context into it 
     FileUtils.writeStringToFile(contextFile, header + contextB); 

     //refresh the context 
     context.refresh(); 

     //echo the bean 'test' on stdout 
     System.out.println(context.getBean("test")); 
    } 

} 

Và bạn sẽ có được kết quả này

fromContextA 
fromContextB 

Một cách khác để đạt được điều này (và có thể là một trong những đơn giản hơn) là sử dụng tính năng làm mới Bean xuân 2.5+ Với ngôn ngữ động (groovy, vv) và mùa xuân bạn thậm chí có thể thay đổi hành vi đậu của bạn. Hãy xem spring reference for dynamic language:

24.3.1.2. Đậu có thể làm mới

Một trong những (nếu không phải) nhất giá trị hấp dẫn thêm hỗ trợ ngôn ngữ động vào mùa xuân là tính năng 'refreshable bean'.

Một bean làm mới là một bean động ngôn ngữ hậu thuẫn rằng với một lượng nhỏ cấu hình, một động-ngôn ngữ được hỗ trợ đậu màn hình thay đổi trong tập tin tài nguyên nguồn cơ bản của nó, và sau đó có thể tải lại bản thân khi ngôn ngữ động tệp nguồn được thay đổi (ví dụ: khi nhà phát triển chỉnh sửa và lưu thay đổi đối với tệp trên hệ thống tệp ).

2

Bạn có thể xem http://www.wuenschenswert.net/wunschdenken/archives/138 này khi bạn thay đổi bất kỳ thứ gì trong tệp thuộc tính và lưu nó, hạt sẽ được tải lại với các giá trị mới.

+0

Điều này đã được điều chỉnh tại https://github.com/Unicon/springframework-addons/wiki/Auto-reloading-properties-files – Vadzim

+0

Cập nhật liên kết: http://maven-repository.com/artifact/net.unicon. springframework/springframework-addons/0.1, https://github.com/UniconLabs/springframework-addons/blob/master/src/main/java/net/unicon/springframework/addons/properties/ReloadingPropertyPlaceholderConfigurer.java, https: // github.com/knightliao/disconf/blob/master/disconf-client/src/main/java/com/baidu/disconf/client/addons/properties/ReloadingPropertyPlaceholderConfigurer.java – Vadzim

1

Đối với những người ngại về điều này gần đây hơn - cách hiện tại và hiện đại để giải quyết vấn đề này là sử dụng Spring Boot's Cloud Config.

Chỉ cần thêm chú thích @RefreshScope vào đậu có thể làm mới và @EnableConfigServer trên chính/cấu hình của bạn.

Vì vậy, ví dụ, lớp điều khiển này:

@RefreshScope 
@RestController 
class MessageRestController { 

    @Value("${message}") 
    private String message; 

    @RequestMapping("/message") 
    String getMessage() { 
     return this.message; 
    } 
} 

sẽ trả về giá trị mới của message sở hữu chuỗi của bạn cho /message endpoint bất cứ khi nào cấu hình của bạn được cập nhật.

Xem ví dụ Spring Guide for Centralized Configuration chính thức để biết thêm chi tiết triển khai.

Các vấn đề liên quan