首先自定义Scheduler类
package com.citicsc.mbs.agent.util;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Scheduler implements InitializingBean, DisposableBean {
private ThreadPoolExecutor pool = null;
private ScheduledExecutorService scheduledPool = null;
/**
* AutoStrat
*/
public void afterPropertiesSet(){
int cpu = Runtime.getRuntime().availableProcessors();
pool = new ThreadPoolExecutor(
// corePoolSize
cpu,
// maximumPoolSize
2 * cpu,
// keepAliveTime
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Scheduler-pool-" + r.hashCode());
}
},
// 默认直接拒绝策略
new AbortPolicy());
scheduledPool = Executors.newScheduledThreadPool(cpu, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Scheduler-scheduledPool-" + r.hashCode());
}
});
}
public void start(Runnable r) {
pool.submit(r);
}
public void startScheduled(Runnable r) {
// default
startScheduled(r, 1, 1, TimeUnit.MINUTES);
}
public void startScheduledOf5(Runnable r) {
// default
startScheduled(r, 5, 5, TimeUnit.MINUTES);
}
public void startScheduledOf10(Runnable r) {
// default
startScheduled(r, 10, 10, TimeUnit.MINUTES);
}
public void startScheduled(Runnable r,
long initialDelay,
long period,
TimeUnit unit) {
scheduledPool.scheduleAtFixedRate(r, initialDelay, period, unit);
}
public ThreadPoolExecutor getPool() {
return pool;
}
public ScheduledExecutorService getScheduledPool() {
return scheduledPool;
}
/**
* {@link DisposableBean#destroy()}
*/
public void destroy() throws Exception {
pool.shutdown();
scheduledPool.shutdown();
}
}
scheduleAtFixedRate()方法介绍
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
- Runnable command 任务对象,Runnable 及其子类
- long initialDelay 任务开始执行的延迟时间
- long period 任务执行的间隔周期 例如 1s 10min 1h 等
- TimeUnit unit 任务执行周期的时间单位
// 将任务放入定时服务中
// scheduleAtFixedRate:固定的频率来执行某项计划,它不受计划执行时间的影响。到时间,它就执行。
// scheduleWithFixedDelay:按照相对固定频率来执行,相对是相对任务的。即无论某个任务执行多长时间,等执行完了,再延迟指定的时间执行下一次任务,它受上一次计划执行时间的影响
例子:
我是用在获取token当中:
String tokenSwitch;表示获取token的开关,不需要获取token的时候,在配置文件设置其他的值
package com.citicsc.finance.agent.token;
import com.citicsc.finance.agent.client.GalaxyFeignClient;
import com.citicsc.finance.agent.client.LoginFeignClient;
import com.citicsc.finance.agent.dto.*;
import com.citicsc.finance.agent.enums.ResponseStatusEnum;
import com.citicsc.finance.agent.properties.GalaxyCredentialProperties;
import com.citicsc.finance.agent.util.AESUtil;
import com.citicsc.finance.agent.util.Scheduler;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* @ClassName GalaxyTokenHolder
* @Description TODO
* @Author houbing
* @Date 2023/9/6 16:55
*/
@Slf4j
@Service
public class GalaxyTokenHolder {
/** Token令牌*/
volatile String tokenCached;
@Autowired
GalaxyFeignClient galaxyFeignClient;
@Autowired
LoginFeignClient loginFeignClient;
@Autowired
Scheduler scheduler;
@Autowired
ObjectMapper objectMapper;
@Autowired
GalaxyCredentialProperties galaxyCredentialProperties;
@Value("${config.galaxy.tokenSwitch}")
String tokenSwitch;
private ReentrantLock _lock = new ReentrantLock(false);
@PostConstruct
public void init(){
refreshOtcToken();
scheduler.getScheduledPool().scheduleAtFixedRate(() -> refreshOtcToken(), 1, 1, TimeUnit.HOURS);
}
/**
* 组装token令牌
* @return
*/
public String getAuthorization() {
if (Objects.isNull(tokenCached)) {
refreshOtcToken();
}
return tokenCached;
}
/**
* token刷新
* @return
*/
private synchronized void refreshOtcToken(){
if ("Y".equals(tokenSwitch)){
_lock.lock();
try
{
LoginReq loginReq = new LoginReq();
loginReq.setUserNo(galaxyCredentialProperties.getUserNo());
loginReq.setPassword(galaxyCredentialProperties.getPassword());
BaseResponseDTO<FRResponseResultDTO<LoginAuthRsp>> authorize = galaxyFeignClient.authorize(loginReq);
if (ResponseStatusEnum.SUCCESS == authorize.getResponseStatus()){
log.info("### authorize.getResponseStatus: {}" , authorize);
LoginAuthRsp data = authorize.getResults().getData();
tokenCached = "Bearer " + data.getAccessToken();
} else if (Objects.nonNull(authorize.getResponseErrorMsg())){
log.error("### acquireTicket.responseStatus:{}", authorize.getResponseErrorMsg());
}
} catch (Exception e) {
log.error("### refreshOtcToken.error", e);
} finally {
_lock.unlock();
}
}
}
}
package com.citicsc.finance.agent.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
/**
* @ClassName LoginAuthRsp
* @Description TODO
* @Author houbing
* @Date 2023/9/7 9:35
*/
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class LoginAuthRsp {
/** 用户账号 */
private String userNo;
/** 用户名称 */
private String userName;
/** 访问token */
@JsonProperty("AccessToken")
private String accessToken;
/** 刷新token */
@JsonProperty("RefreshToken")
private String refreshToken;
}