package org.springframework.learning.resource;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.*;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
`import java.util.concurrent.Executors;
/**
\* @author
\* @date 2020/10/15 9:15 下午
*
\* 動態(tài)監(jiān)聽配置文件的變動,實現動態(tài)MessageSource
\* 1. 定位資源位置
\* 2. 初始化properties
\* 3. 實現resolveCode方法
\* 4. 文件監(jiān)聽 @see WatchService
*/
public class DynamicMessageSourceDemoextends AbstractMessageSourceimplements ResourceLoaderAware {
private static final StringFILE_NAME ="messages.properties";
private static final StringRESOURCE_PATH ="/META-INF/i18n/" +FILE_NAME;
private static final StringENCODE ="UTF-8";
private ResourceLoaderresourceLoader;
private final Propertiesproperties;
private final ResourcemessagePropertiesResource;
private final ExecutorServiceexecutorService = Executors.newSingleThreadExecutor();
public DynamicMessageSourceDemo() {
this.messagePropertiesResource = getMessagePropertiesSource();
? this.properties = loadProperties();
? onMessagePropertiesChanged();
}
private void onMessagePropertiesChanged() {
try {
FilemessagePropertiesSourceFile =messagePropertiesResource.getFile();
?? ? PathmessagePropertiesSourcePath =messagePropertiesSourceFile.toPath();
?? ? FileSystemfileSystem = FileSystems.getDefault();
?? ? WatchServicewatchService =fileSystem.newWatchService();
?? ? Pathdir =messagePropertiesSourcePath.getParent();
?? ? dir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
?? ? executorService.submit(()->{
processMessagePropertiesChanged(watchService);
?? ? });
? }catch (IOExceptione) {
throw new RuntimeException();
? }
}
private void processMessagePropertiesChanged(WatchServicewatchService) {
while (true){
WatchKey watchKey =null;
?? ? try {
watchKey =watchService.take();
?? ? ? if(watchKey.isValid()){
Pathdir = (Path) watchKey.watchable();
?? ? ? for (WatchEventevent : watchKey.pollEvents()) {
PathabsolutePath =dir.resolve((Path)event.context());
?? ? ? ? if("messages.properties".equals(absolutePath.getFileName().toString())){
System.out.println("文件變化" +absolutePath.toString());
?? ? ? ? ? Filefile =absolutePath.toFile();
?? ? ? ? ? PropertiesnewProperties = loadProperties(new FileReader(file));
?? ? ? ? ? synchronized (properties){
properties.clear();
?? ? ? ? ? ? properties.putAll(newProperties);
?? ? ? ? ? }
}
}
}
}catch (Exceptione) {
throw new RuntimeException(e);
?? ? }finally {
if(null!=watchKey){
watchKey.reset();
?? ? ? }
}
}
}
private PropertiesloadProperties() {
EncodedResourceencodedResource =new EncodedResource(messagePropertiesResource, ENCODE);
? try {
return loadProperties(encodedResource.getReader());
? }catch (IOExceptione) {
throw new RuntimeException(e);
? }
}
private ResourcegetMessagePropertiesSource() {
return getResourceLoader().getResource(RESOURCE_PATH);
}
private PropertiesloadProperties(Readerreader) {
Propertiesproperties =new Properties();
? try {
properties.load(reader);
? }catch (IOExceptione) {
throw new RuntimeException(e);
? }finally {
try {
reader.close();
?? ? }catch (IOExceptione) {
throw new RuntimeException(e);
?? ? }
}
return properties;
}
@Override
protected MessageFormatresolveCode(Stringcode, Localelocale) {
StringmessageFormatPattern =properties.getProperty(code);
? if (StringUtils.hasText(messageFormatPattern)) {
return new MessageFormat(messageFormatPattern, locale);
? }
return null;
}
@Override
public void setResourceLoader(ResourceLoaderresourceLoader) {
this.resourceLoader =resourceLoader;
}
public ResourceLoadergetResourceLoader() {
return this.resourceLoader !=null ?this.resourceLoader :new DefaultResourceLoader();
}
public static void main(String[]args)throws InterruptedException {
DynamicMessageSourceDemodemo =new DynamicMessageSourceDemo();
? for(int i=0;i<10000;i++){
Stringmessage =demo.getMessage("name", null, Locale.getDefault());
?? ? System.out.println(message);
?? ? Thread.sleep(1000);
? }
}
}