🎨🔥 删除 DynProps4FilesService.java
This commit is contained in:
parent
8b2c7f93b5
commit
9c38e94b04
@ -1,348 +0,0 @@
|
|||||||
package com.rymcu.vertical.core.service.props;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态配置文件,可以设置更新周期
|
|
||||||
* 配置读取读取服务
|
|
||||||
* @author ronger
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class DynProps4FilesService {
|
|
||||||
private Logger _log = LoggerFactory.getLogger(DynProps4FilesService.class);
|
|
||||||
/**
|
|
||||||
* 属性文件
|
|
||||||
*/
|
|
||||||
private File[] fileArray;
|
|
||||||
/**
|
|
||||||
* 启动延时
|
|
||||||
*/
|
|
||||||
private long delay;
|
|
||||||
/**
|
|
||||||
* 更新周期
|
|
||||||
*/
|
|
||||||
private long period;
|
|
||||||
/**
|
|
||||||
* 属性对象
|
|
||||||
*/
|
|
||||||
private Properties property = new Properties();
|
|
||||||
/**
|
|
||||||
* 文件监控器
|
|
||||||
*/
|
|
||||||
private List<FileMonitor> monitors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param files 属性文件
|
|
||||||
* @param delay 从<code>DynProps</code>被创建到第一次动态监视的时间间隔. 约束范围delay > 0
|
|
||||||
* @param period 动态监视的时间间隔. 约束范围period >= 0;等于0表示不执行动态监视,退化为静态配置文件.
|
|
||||||
*/
|
|
||||||
public DynProps4FilesService(File[] files, long delay, long period) throws IOException {
|
|
||||||
this.fileArray = files;
|
|
||||||
this.delay = delay;
|
|
||||||
this.period = period;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynProps4FilesService(List<String> fileNames, long delay, long period) throws IOException {
|
|
||||||
this.delay = delay;
|
|
||||||
this.period = period;
|
|
||||||
fileArray = new File[fileNames.size()];
|
|
||||||
int index = 0;
|
|
||||||
for (String oriFileName : fileNames) {
|
|
||||||
String fileName = oriFileName.trim();
|
|
||||||
if (StringUtils.indexOfIgnoreCase(fileName, "classpath:") == 0) {
|
|
||||||
fileArray[index++] = new File(
|
|
||||||
this.getClass().getClassLoader().getResource("").getPath() + File.separator +
|
|
||||||
fileName.substring("classpath:".length()));
|
|
||||||
} else {
|
|
||||||
fileArray[index++] = new File(fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public DynProps4FilesService(String fileNames, long delay, long period) throws IOException {
|
|
||||||
this.delay = delay;
|
|
||||||
this.period = period;
|
|
||||||
boolean isClassPath = false;
|
|
||||||
if (fileNames.startsWith("classpath")) {
|
|
||||||
fileNames = fileNames.substring("classpath:".length());
|
|
||||||
isClassPath = true;
|
|
||||||
}
|
|
||||||
String[] fileName = fileNames.split("[,|,|;|;]");
|
|
||||||
fileArray = new File[fileName.length];
|
|
||||||
if (isClassPath) {
|
|
||||||
for (int i = 0; i < fileName.length; i++) {
|
|
||||||
fileArray[i] = new File(this.getClass().getClassLoader().getResource("").getPath() + fileName[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < fileName.length; i++) {
|
|
||||||
fileArray[i] = new File(fileName[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynProps4FilesService(File[] files, long period) throws IOException {
|
|
||||||
this(files, 0, period);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynProps4FilesService(String fileNames, long period) throws IOException {
|
|
||||||
this.period = period;
|
|
||||||
this.delay = 0;
|
|
||||||
String[] fileName = fileNames.split("[,|,|;|;]");
|
|
||||||
|
|
||||||
File[] files = new File[fileName.length];
|
|
||||||
for (int i = 0; i < fileName.length; i++) {
|
|
||||||
files[i] = new File(fileName[i]);
|
|
||||||
}
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynProps4FilesService() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载属性文件,启动监控
|
|
||||||
*
|
|
||||||
* @throws IOException 加载文件时出现IO异常
|
|
||||||
*/
|
|
||||||
protected void load() throws IOException {
|
|
||||||
update();
|
|
||||||
if (monitors == null) {
|
|
||||||
monitors = new ArrayList<FileMonitor>(fileArray.length);
|
|
||||||
} else {
|
|
||||||
for (FileMonitor monitor : monitors) {
|
|
||||||
try {
|
|
||||||
monitor.timer.cancel();
|
|
||||||
} catch (Exception e) {
|
|
||||||
_log.warn(String.format("Timer for file [%s] cancelling failed.", monitor.file.getAbsolutePath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : fileArray) {
|
|
||||||
long lastModify = file.lastModified();
|
|
||||||
FileMonitor monitor = new FileMonitor(file, lastModify);
|
|
||||||
this.monitors.add(monitor);
|
|
||||||
monitor.doTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 如果文件有更新调用此方法载入
|
|
||||||
*
|
|
||||||
* @throws IOException 没有找到文件或读文件错误时抛出
|
|
||||||
*/
|
|
||||||
protected void update() throws IOException {
|
|
||||||
for (File file : fileArray) {
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
in = new FileInputStream(file);
|
|
||||||
this.property.load(in);
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof IOException) {
|
|
||||||
throw (IOException) e;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException(e);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param key 需要获取属性值的KEY
|
|
||||||
* @param def 默认值
|
|
||||||
*
|
|
||||||
* @return 属性值
|
|
||||||
*/
|
|
||||||
public String getProperty(String key, String def) {
|
|
||||||
String val = this.property.getProperty(key);
|
|
||||||
return val == null ? def : val.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String key) {
|
|
||||||
String val = this.property.getProperty(key);
|
|
||||||
return val == null ? null : val.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置属性值
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void setProperty(String key, String value) {
|
|
||||||
this.property.setProperty(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param key 需要获取属性值的KEY
|
|
||||||
* @param def 默认值
|
|
||||||
*
|
|
||||||
* @return 属性值
|
|
||||||
*
|
|
||||||
* @throws NumberFormatException 如果属性值不是整数形式
|
|
||||||
*/
|
|
||||||
public int getInt(String key, int def) throws NumberFormatException {
|
|
||||||
String val = this.getProperty(key);
|
|
||||||
return val == null ? def : Integer.parseInt(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt(String key) throws NumberFormatException {
|
|
||||||
return getInt(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFloat(String key, float def) throws NumberFormatException {
|
|
||||||
String val = this.getProperty(key);
|
|
||||||
return val == null ? def : Float.parseFloat(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFloat(String key) throws NumberFormatException {
|
|
||||||
return getFloat(key, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDouble(String key, double def) {
|
|
||||||
String val = this.getProperty(key);
|
|
||||||
return val == null ? def : Double.parseDouble(val);
|
|
||||||
}
|
|
||||||
public double getDouble(String key) throws NumberFormatException {
|
|
||||||
return getDouble(key,0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public long getLong(String key, long def) {
|
|
||||||
String val = this.getProperty(key);
|
|
||||||
return val == null ? def : Long.parseLong(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLong(String key) throws NumberFormatException {
|
|
||||||
return getLong(key, 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() throws IOException {
|
|
||||||
for (File file : fileArray) {
|
|
||||||
if (!file.exists() || file.length() == 0) {
|
|
||||||
throw new IllegalArgumentException("动态配置文件 " + file.getAbsolutePath() + " 不存在,或是空文件!");
|
|
||||||
}
|
|
||||||
if (delay <= 0) {
|
|
||||||
throw new IllegalArgumentException("定时器延时时间不能为负数!");
|
|
||||||
}
|
|
||||||
if (period <= 0) {
|
|
||||||
throw new IllegalArgumentException("定时器更新周期不能为负数!");
|
|
||||||
}
|
|
||||||
this.property = new Properties();
|
|
||||||
this.load();// 初始构造时,执行第一次加载.
|
|
||||||
}
|
|
||||||
//当进程终止时,取消定时任务
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ShutdownHook implements Runnable {
|
|
||||||
private DynProps4FilesService dynProps4FilesService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
System.out.println("Monitors cancelling start ...");
|
|
||||||
if (monitors != null) {
|
|
||||||
for (FileMonitor monitor : monitors) {
|
|
||||||
try {
|
|
||||||
monitor.timer.cancel();
|
|
||||||
} catch (Exception e) {
|
|
||||||
_log.warn(String.format("Timer for file [%s] cancelling failed.",
|
|
||||||
monitor.file.getAbsolutePath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 描述:一个内部私有类,实时监控文件有没有更新,如果更新则自动载入
|
|
||||||
*/
|
|
||||||
private class FileMonitor {
|
|
||||||
|
|
||||||
private long lastModifiedTime;
|
|
||||||
private File file;
|
|
||||||
/**
|
|
||||||
* 定时器,以守护线程方式启动
|
|
||||||
*/
|
|
||||||
private Timer timer = new Timer(true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param lastMonitorTime 最后的更新时间
|
|
||||||
*/
|
|
||||||
private FileMonitor(File file, long lastMonitorTime) {
|
|
||||||
this.file = file;
|
|
||||||
this.lastModifiedTime = lastMonitorTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对文件进行实时监控,有更新则自动载入
|
|
||||||
*/
|
|
||||||
private void doTask() {
|
|
||||||
if (delay < 0) {
|
|
||||||
delay = 0L;
|
|
||||||
}
|
|
||||||
if (period <= 0) {
|
|
||||||
return;// 如果更新周期非正数,则退化成静态配置文件.
|
|
||||||
}
|
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
long t = file.lastModified();
|
|
||||||
// 文件被删除
|
|
||||||
// 如果动态更新过程中,配置文件被强制删除了,本次不执行任何更新.或者对配置文件进行恢复
|
|
||||||
if (t == 0) {
|
|
||||||
try {
|
|
||||||
if (file.createNewFile()) {
|
|
||||||
OutputStream fos = new FileOutputStream(file);
|
|
||||||
property.store(fos, "文件被删除,自动恢复.");
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ioe2) {
|
|
||||||
// 这里基本上只有磁盘空间满才会发生,暂时不处理
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 文件被更新
|
|
||||||
if (t > lastModifiedTime) {
|
|
||||||
lastModifiedTime = t;
|
|
||||||
// 2秒后还在改变,则本次更新不做处理
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(2);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
if (t != file.lastModified()) {
|
|
||||||
_log.info("文件可能未更新完成,本次不更新!");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
property.clear();
|
|
||||||
update();
|
|
||||||
_log.info("UPDATED " + file.getAbsolutePath());
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
_log.error("UPDATING " + file.getAbsolutePath() + " failed", ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_log.debug("-----------------------:" + property.keySet());
|
|
||||||
}
|
|
||||||
}// end run()
|
|
||||||
}, delay, period);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis 服务接口
|
* Redis 服务接口
|
||||||
* Jimersy Lee
|
* @author Jimersy Lee
|
||||||
* 2017-09-18 14:58:21
|
* 2017-09-18 14:58:21
|
||||||
*/
|
*/
|
||||||
public interface RedisService {
|
public interface RedisService {
|
||||||
|
@ -3,19 +3,16 @@ package com.rymcu.vertical.core.service.redis.impl;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.TypeReference;
|
import com.alibaba.fastjson.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
import com.rymcu.vertical.core.service.props.DynProps4FilesService;
|
import com.rymcu.vertical.config.RedisProperties;
|
||||||
import com.rymcu.vertical.core.service.redis.RedisResult;
|
import com.rymcu.vertical.core.service.redis.RedisResult;
|
||||||
import com.rymcu.vertical.core.service.redis.RedisService;
|
import com.rymcu.vertical.core.service.redis.RedisService;
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.JedisPool;
|
import redis.clients.jedis.JedisPool;
|
||||||
import redis.clients.jedis.JedisPoolConfig;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
@ -34,14 +31,10 @@ public class RedisServiceImpl implements RedisService {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);
|
private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);
|
||||||
|
|
||||||
|
|
||||||
private static JedisPool pool = null;
|
private static JedisPool pool = null;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DynProps4FilesService dynProps4Files;
|
private RedisProperties redisProperties;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private Environment env;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,25 +46,23 @@ public class RedisServiceImpl implements RedisService {
|
|||||||
if (pool != null) {
|
if (pool != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*JedisPoolConfig config = new JedisPoolConfig();
|
pool = getJedisPool();
|
||||||
config.setMaxIdle(dynProps4Files.getInt("REDIS_MAX_IDLE", JedisPoolConfig.DEFAULT_MAX_IDLE));
|
}
|
||||||
config.setMaxTotal(dynProps4Files.getInt("REDIS_MAX_TOTAL", JedisPoolConfig.DEFAULT_MAX_TOTAL));
|
|
||||||
config.setMaxWaitMillis(dynProps4Files.getLong("REDIS_MAX_WAIT", JedisPoolConfig.DEFAULT_MAX_WAIT_MILLIS));
|
|
||||||
config.setTestOnBorrow(true);
|
|
||||||
pool = new JedisPool(config, dynProps4Files.getProperty("REDIS_HOST"),
|
|
||||||
dynProps4Files.getInt("REDIS_PORT", 6379), dynProps4Files.getInt(
|
|
||||||
"REDIS_MAX_WAIT", 1000), dynProps4Files.getProperty("REDIS_PASSWORD", null));*/
|
|
||||||
|
|
||||||
JedisPoolConfig config = new JedisPoolConfig();
|
|
||||||
config.setMaxIdle(dynProps4Files.getInt("REDIS_MAX_IDLE", JedisPoolConfig.DEFAULT_MAX_IDLE));
|
|
||||||
config.setMaxTotal(dynProps4Files.getInt("REDIS_MAX_TOTAL", JedisPoolConfig.DEFAULT_MAX_TOTAL));
|
|
||||||
config.setMaxWaitMillis(dynProps4Files.getLong("REDIS_MAX_WAIT", JedisPoolConfig.DEFAULT_MAX_WAIT_MILLIS));
|
|
||||||
config.setTestOnBorrow(true);
|
|
||||||
pool = new JedisPool(config, env.getProperty("spring.redis.host"),
|
|
||||||
dynProps4Files.getInt("REDIS_PORT", 6379), dynProps4Files.getInt(
|
|
||||||
"REDIS_MAX_WAIT", 1000), dynProps4Files.getProperty("REDIS_PASSWORD", env.getProperty("spring.redis.password")));
|
|
||||||
|
|
||||||
|
|
||||||
|
private JedisPool getJedisPool() {
|
||||||
|
if (pool == null) {
|
||||||
|
synchronized (RedisServiceImpl.class) {
|
||||||
|
if (pool == null) {
|
||||||
|
pool = new JedisPool(redisProperties, redisProperties.getHost(),
|
||||||
|
redisProperties.getPort(), redisProperties.getConnectionTimeout(),
|
||||||
|
redisProperties.getSoTimeout(), redisProperties.getPassword(),
|
||||||
|
redisProperties.getDatabase(), redisProperties.getClientName(),
|
||||||
|
redisProperties.isSsl(), redisProperties.getSslSocketFactory(),
|
||||||
|
redisProperties.getSslParameters(), redisProperties.getHostnameVerifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -106,7 +97,7 @@ public class RedisServiceImpl implements RedisService {
|
|||||||
if (jedis == null) {
|
if (jedis == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IOUtils.closeQuietly(jedis);
|
jedis.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.rymcu.vertical.service.impl;
|
package com.rymcu.vertical.service.impl;
|
||||||
|
|
||||||
import com.rymcu.vertical.core.service.AbstractService;
|
import com.rymcu.vertical.core.service.AbstractService;
|
||||||
import com.rymcu.vertical.core.service.redis.RedisService;
|
|
||||||
import com.rymcu.vertical.dto.ArticleTagDTO;
|
import com.rymcu.vertical.dto.ArticleTagDTO;
|
||||||
import com.rymcu.vertical.dto.LabelModel;
|
import com.rymcu.vertical.dto.LabelModel;
|
||||||
import com.rymcu.vertical.entity.Article;
|
import com.rymcu.vertical.entity.Article;
|
||||||
@ -36,8 +35,6 @@ public class TagServiceImpl extends AbstractService<Tag> implements TagService {
|
|||||||
private TagMapper tagMapper;
|
private TagMapper tagMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ArticleMapper articleMapper;
|
private ArticleMapper articleMapper;
|
||||||
@Resource
|
|
||||||
private RedisService redisService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = { UnsupportedEncodingException.class,BaseApiException.class })
|
@Transactional(rollbackFor = { UnsupportedEncodingException.class,BaseApiException.class })
|
||||||
|
Loading…
Reference in New Issue
Block a user