mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-10-08 13:16:41 +08:00
优化
This commit is contained in:
parent
f417c8a032
commit
eee13c36ea
@ -33,24 +33,25 @@ public class SmartSecurityMetadataSource extends PrePostAnnotationSecurityMetada
|
||||
|
||||
private final PrePostInvocationAttributeFactory attributeFactory;
|
||||
|
||||
private String projectModule;
|
||||
|
||||
private List<String> noValidUrlList;
|
||||
|
||||
public SmartSecurityMetadataSource(PrePostInvocationAttributeFactory attributeFactory, List<String> noValidUrlList, String projectModule) {
|
||||
public SmartSecurityMetadataSource(PrePostInvocationAttributeFactory attributeFactory, List<String> noValidUrlList) {
|
||||
super(attributeFactory);
|
||||
this.attributeFactory = attributeFactory;
|
||||
this.projectModule = projectModule;
|
||||
this.noValidUrlList = noValidUrlList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
|
||||
//只对固定的包的所有接口进行控制
|
||||
if (!targetClass.getName().startsWith(projectModule)) {
|
||||
//自己的控制
|
||||
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||
PostMapping postMapping = method.getAnnotation(PostMapping.class);
|
||||
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
|
||||
if (getMapping == null && postMapping == null && requestMapping == null) {
|
||||
return super.getAttributes(method, targetClass);
|
||||
}
|
||||
|
||||
//是否需要权限
|
||||
NoValidPrivilege methodNoValidPrivilege = method.getAnnotation(NoValidPrivilege.class);
|
||||
if (methodNoValidPrivilege != null) {
|
||||
@ -69,13 +70,6 @@ public class SmartSecurityMetadataSource extends PrePostAnnotationSecurityMetada
|
||||
if (postAuthorize != null) {
|
||||
return super.getAttributes(method, targetClass);
|
||||
}
|
||||
//自己的控制
|
||||
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||
PostMapping postMapping = method.getAnnotation(PostMapping.class);
|
||||
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
|
||||
if (getMapping == null && postMapping == null && requestMapping == null) {
|
||||
return super.getAttributes(method, targetClass);
|
||||
}
|
||||
//获取注解值
|
||||
String uriPrefix = SmartSecurityUrl.getUriPrefix(method);
|
||||
List<String> annotationValueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix);
|
||||
|
@ -7,7 +7,12 @@ import org.reflections.Reflections;
|
||||
import org.reflections.scanners.MethodAnnotationsScanner;
|
||||
import org.reflections.scanners.TypeAnnotationsScanner;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -19,7 +24,7 @@ import java.util.Set;
|
||||
* @author 罗伊
|
||||
* @date 2021/8/31 10:20
|
||||
*/
|
||||
public class SmartSecurityUrlMatchers {
|
||||
public class SmartSecurityUrlMatchers implements BeanPostProcessor {
|
||||
|
||||
/**
|
||||
* 匿名访问URL
|
||||
@ -42,7 +47,7 @@ public class SmartSecurityUrlMatchers {
|
||||
IGNORE_URL.add("/swagger-resources/**");
|
||||
IGNORE_URL.add("/webjars/**");
|
||||
IGNORE_URL.add("/*/api-docs");
|
||||
IGNORE_URL.add(CommonConst.ApiUrl.API_PREFIX_SUPPORT +"/**");
|
||||
IGNORE_URL.add(CommonConst.ApiUrl.API_PREFIX_SUPPORT + "/**");
|
||||
|
||||
AUTHENTICATED_URL = new ArrayList<>();
|
||||
AUTHENTICATED_URL.add("/admin/**");
|
||||
@ -50,14 +55,14 @@ public class SmartSecurityUrlMatchers {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param scanPath 需要扫描的类路径
|
||||
*
|
||||
*/
|
||||
public SmartSecurityUrlMatchers(String scanPath){
|
||||
this.ANONYMOUS_URL = this.initAnonymousUrlList(scanPath);
|
||||
public SmartSecurityUrlMatchers() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取忽略的URL集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getIgnoreUrlList() {
|
||||
@ -66,6 +71,7 @@ public class SmartSecurityUrlMatchers {
|
||||
|
||||
/**
|
||||
* 获取需要匿名访问的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getAnonymousUrlList() {
|
||||
@ -74,6 +80,7 @@ public class SmartSecurityUrlMatchers {
|
||||
|
||||
/**
|
||||
* 获取需要认证的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getAuthenticatedUrlList() {
|
||||
@ -82,6 +89,7 @@ public class SmartSecurityUrlMatchers {
|
||||
|
||||
/**
|
||||
* 不需要权限校验的
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getNoValidUrlList() {
|
||||
@ -93,60 +101,52 @@ public class SmartSecurityUrlMatchers {
|
||||
|
||||
/**
|
||||
* 获取需要忽略的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String [] getIgnoreUrlArray() {
|
||||
String [] ignoreUrlArray = IGNORE_URL.toArray(new String[IGNORE_URL.size()]);
|
||||
public String[] getIgnoreUrlArray() {
|
||||
String[] ignoreUrlArray = IGNORE_URL.toArray(new String[IGNORE_URL.size()]);
|
||||
return ignoreUrlArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要匿名访问的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String [] getAnonymousUrlArray() {
|
||||
String [] anonymousUrlArray = ANONYMOUS_URL.toArray(new String[ANONYMOUS_URL.size()]);
|
||||
public String[] getAnonymousUrlArray() {
|
||||
String[] anonymousUrlArray = ANONYMOUS_URL.toArray(new String[ANONYMOUS_URL.size()]);
|
||||
return anonymousUrlArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要认证的url集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String [] getAuthenticatedUrlArray() {
|
||||
String [] anonymousUrlArray = AUTHENTICATED_URL.toArray(new String[AUTHENTICATED_URL.size()]);
|
||||
public String[] getAuthenticatedUrlArray() {
|
||||
String[] anonymousUrlArray = AUTHENTICATED_URL.toArray(new String[AUTHENTICATED_URL.size()]);
|
||||
return anonymousUrlArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取无需登录可以匿名访问的url信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<String> initAnonymousUrlList(String scanPath) {
|
||||
List<String> anonymousUrlList = Lists.newArrayList();
|
||||
//添加无需登录注解的uri
|
||||
Reflections reflections = new Reflections(new ConfigurationBuilder().forPackages(scanPath).addScanners(new MethodAnnotationsScanner(), new TypeAnnotationsScanner()));
|
||||
Set<Method> methodSet = reflections.getMethodsAnnotatedWith(NoNeedLogin.class);
|
||||
Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(NoNeedLogin.class);
|
||||
//方法级别无需登录
|
||||
for (Method method : methodSet) {
|
||||
String uriPrefix = SmartSecurityUrl.getUriPrefix(method);
|
||||
List<String> valueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix);
|
||||
anonymousUrlList.addAll(valueList);
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass());
|
||||
if (methods == null) {
|
||||
return bean;
|
||||
}
|
||||
//类级别无需登录
|
||||
for (Class clazz : classSet) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
//方法级别无需登录
|
||||
for (Method method : methods) {
|
||||
NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class);
|
||||
if(noNeedLogin != null){
|
||||
String uriPrefix = SmartSecurityUrl.getUriPrefix(method);
|
||||
List<String> valueList = SmartSecurityUrl.getAnnotationValueList(method, uriPrefix);
|
||||
anonymousUrlList.addAll(valueList);
|
||||
this.ANONYMOUS_URL.addAll(valueList);
|
||||
}
|
||||
}
|
||||
return anonymousUrlList;
|
||||
return bean;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -16,16 +16,6 @@ import java.util.Map;
|
||||
@Configuration
|
||||
public class AdminWebAppConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private Map<String, HandlerInterceptor> interceptorMap;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
for(Map.Entry<String, HandlerInterceptor> entry : interceptorMap.entrySet()){
|
||||
registry.addInterceptor(entry.getValue()).addPathPatterns(entry.getKey() + "/**");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/druidMonitor").setViewName("redirect:druid/index.html");
|
||||
|
@ -42,6 +42,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
*/
|
||||
@Autowired
|
||||
private EmployeeLoginTokenService loginTokenService;
|
||||
|
||||
/**
|
||||
* 跨域配置
|
||||
*
|
||||
|
@ -18,9 +18,6 @@ import org.springframework.security.config.annotation.method.configuration.Globa
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration {
|
||||
|
||||
@Value("${project.module}")
|
||||
private String projectModule;
|
||||
|
||||
/**
|
||||
* 无需登录的url
|
||||
*/
|
||||
@ -30,6 +27,6 @@ public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration {
|
||||
@Override
|
||||
public MethodSecurityMetadataSource customMethodSecurityMetadataSource(){
|
||||
ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(this.getExpressionHandler());
|
||||
return new SmartSecurityMetadataSource(attributeFactory, smartSecurityUrlMatchers.getNoValidUrlList(),projectModule);
|
||||
return new SmartSecurityMetadataSource(attributeFactory, smartSecurityUrlMatchers.getNoValidUrlList());
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class SecurityUrlConfig {
|
||||
|
||||
@Value("${project.module}")
|
||||
private String projectModule;
|
||||
|
||||
@Bean
|
||||
public SmartSecurityUrlMatchers securityUrl() {
|
||||
return new SmartSecurityUrlMatchers(projectModule);
|
||||
return new SmartSecurityUrlMatchers();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.common.codeconst.ResponseCodeConst;
|
||||
import net.lab1024.smartadmin.service.common.constant.SystemEnvironmentEnum;
|
||||
import net.lab1024.smartadmin.service.common.domain.ResponseDTO;
|
||||
import net.lab1024.smartadmin.service.common.domain.SystemEnvironmentBO;
|
||||
import net.lab1024.smartadmin.service.common.exception.SmartBusinessException;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -34,7 +35,7 @@ import java.util.stream.Collectors;
|
||||
public class SmartGlobalExceptionHandler {
|
||||
|
||||
@Autowired
|
||||
private SystemEnvironmentEnum systemEnvironmentEnum;
|
||||
private SystemEnvironmentBO systemEnvironmentBO;
|
||||
|
||||
/**
|
||||
* 添加全局异常处理流程
|
||||
@ -95,7 +96,8 @@ public class SmartGlobalExceptionHandler {
|
||||
log.error("捕获全局异常,URL:{}", uri, e);
|
||||
|
||||
// 正式环境 不返回错误信息
|
||||
if (SystemEnvironmentEnum.PROD == systemEnvironmentEnum) {
|
||||
SystemEnvironmentEnum currentEnvironment = systemEnvironmentBO.getCurrentEnvironment();
|
||||
if (SystemEnvironmentEnum.PROD == currentEnvironment) {
|
||||
return ResponseDTO.wrap(ResponseCodeConst.SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,134 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload;
|
||||
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.annotation.SmartReload;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.AbstractSmartReloadObject;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.AnnotationReloadObject;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.InterfaceReloadObject;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.SmartReloadResult;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadCommandInterface;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadThreadLogger;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* SmartReloadManager 管理器
|
||||
* <p>
|
||||
* 可以在此类中添加 检测任务 以及注册 处理程序
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class SmartReloadManager {
|
||||
|
||||
private Map<String, AbstractSmartReloadObject> tagReloadObject;
|
||||
|
||||
private SmartReloadScheduler reloadScheduler;
|
||||
|
||||
private SmartReloadThreadLogger logger;
|
||||
|
||||
public SmartReloadManager(SmartReloadThreadLogger logger, int threadCount) {
|
||||
this.tagReloadObject = new ConcurrentHashMap<>();
|
||||
if (logger == null) {
|
||||
throw new ExceptionInInitializerError("SmartReloadLoggerImp cannot be null");
|
||||
}
|
||||
|
||||
if (threadCount < 1) {
|
||||
throw new ExceptionInInitializerError("threadCount must be greater than 1");
|
||||
}
|
||||
|
||||
this.logger = logger;
|
||||
this.reloadScheduler = new SmartReloadScheduler(this.logger, threadCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认创建单个线程
|
||||
*
|
||||
* @param logger
|
||||
*/
|
||||
public SmartReloadManager(SmartReloadThreadLogger logger) {
|
||||
this(logger, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止
|
||||
*/
|
||||
public void shutdown() {
|
||||
reloadScheduler.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加任务
|
||||
*
|
||||
* @param command SmartReloadCommand实现类
|
||||
* @param initialDelay 第一次执行前的延迟时间
|
||||
* @param delay 任务间隔时间
|
||||
* @param unit 延迟单位 TimeUnit 天、小时、分、秒等
|
||||
*/
|
||||
public void addCommand(SmartReloadCommandInterface command, long initialDelay, long delay, TimeUnit unit) {
|
||||
reloadScheduler.addCommand(command, initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 实现接口的方式
|
||||
*
|
||||
* @param tag
|
||||
* @param reloadable
|
||||
*/
|
||||
public void register(String tag, SmartReloadable reloadable) {
|
||||
requireNonNull(reloadable);
|
||||
requireNonNull(tag);
|
||||
if (tagReloadObject.containsKey(tag)) {
|
||||
logger.error("<<SmartReloadManager>> register duplicated tag reload : " + tag + " , and it will be cover!");
|
||||
}
|
||||
tagReloadObject.put(tag, new InterfaceReloadObject(reloadable));
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 要求此类必须包含使用了SmartReload注解的方法
|
||||
*
|
||||
* @param reloadObject
|
||||
*/
|
||||
public void register(Object reloadObject) {
|
||||
requireNonNull(reloadObject);
|
||||
Method[] declaredMethods = reloadObject.getClass().getDeclaredMethods();
|
||||
if (declaredMethods != null) {
|
||||
for (int i = 0; i < declaredMethods.length; i++) {
|
||||
Method method = declaredMethods[i];
|
||||
SmartReload annotation = method.getAnnotation(SmartReload.class);
|
||||
if (annotation != null) {
|
||||
String reloadTag = annotation.value();
|
||||
this.register(reloadTag, new AnnotationReloadObject(reloadObject, method));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void register(String tag, AbstractSmartReloadObject reloadObject) {
|
||||
if (tagReloadObject.containsKey(tag)) {
|
||||
logger.error("<<SmartReloadManager>> register duplicated tag reload : " + tag + " , and it will be cover!");
|
||||
}
|
||||
tagReloadObject.put(tag, reloadObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload 已注册的ReloadItem
|
||||
*
|
||||
* @param reloadItem
|
||||
* @return SmartReloadResult
|
||||
*/
|
||||
public SmartReloadResult doReload(ReloadItem reloadItem) {
|
||||
AbstractSmartReloadObject reloadObject = tagReloadObject.get(reloadItem.getTag());
|
||||
if (reloadObject != null) {
|
||||
return reloadObject.reload(reloadItem);
|
||||
}
|
||||
// 返回注册结果
|
||||
return new SmartReloadResult(reloadItem.getTag(), reloadItem.getArgs(), reloadItem.getIdentification(), false, "No registered reload handler was found");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadCommandInterface;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadThreadLogger;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Reload 调度器
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class SmartReloadScheduler {
|
||||
|
||||
private ScheduledThreadPoolExecutor executor;
|
||||
|
||||
private SmartReloadThreadLogger logger;
|
||||
|
||||
SmartReloadScheduler(SmartReloadThreadLogger logger, int threadCount) {
|
||||
this.executor = new ScheduledThreadPoolExecutor(threadCount, new SmartReloadSchedulerThreadFactory());
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
try {
|
||||
executor.shutdown();
|
||||
} catch (Throwable e) {
|
||||
logger.error("<<SmartReloadScheduler>> shutdown ", e);
|
||||
}
|
||||
}
|
||||
|
||||
void addCommand(SmartReloadCommandInterface command, long initialDelay, long delay, TimeUnit unit) {
|
||||
executor.scheduleWithFixedDelay(new ScheduleRunnable(command, this.logger), initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
static class ScheduleRunnable implements Runnable {
|
||||
|
||||
private SmartReloadCommandInterface command;
|
||||
|
||||
private SmartReloadThreadLogger logger;
|
||||
|
||||
public ScheduleRunnable(SmartReloadCommandInterface command, SmartReloadThreadLogger logger) {
|
||||
this.command = command;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
command.doTask();
|
||||
} catch (Throwable e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SmartReloadSchedulerThreadFactory implements ThreadFactory {
|
||||
|
||||
private static final AtomicInteger poolNumber = new AtomicInteger(1);
|
||||
|
||||
private final ThreadGroup group;
|
||||
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
|
||||
private final String namePrefix;
|
||||
|
||||
SmartReloadSchedulerThreadFactory() {
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
|
||||
namePrefix = "smart-reload-" + poolNumber.getAndIncrement() + "-thread-";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
|
||||
if (t.isDaemon()) {
|
||||
t.setDaemon(false);
|
||||
}
|
||||
|
||||
if (t.getPriority() != Thread.NORM_PRIORITY) {
|
||||
t.setPriority(Thread.NORM_PRIORITY);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.abstracts;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.SmartReloadManager;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadCommandInterface;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 检测是否 Reload 的类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public abstract class AbstractSmartReloadCommand implements SmartReloadCommandInterface {
|
||||
|
||||
/**
|
||||
* 当前ReloadItem的存储器
|
||||
*/
|
||||
private ConcurrentHashMap<String, String> currentTags = null;
|
||||
|
||||
/**
|
||||
* Reload的执行类
|
||||
*/
|
||||
private SmartReloadManager reloadManager;
|
||||
|
||||
public AbstractSmartReloadCommand(SmartReloadManager reloadManager) {
|
||||
this.reloadManager = reloadManager;
|
||||
this.currentTags = new ConcurrentHashMap<>();
|
||||
// 初始获取ReloadItem数据
|
||||
List<ReloadItem> readTagStatesFromDb = readReloadItem();
|
||||
if (readTagStatesFromDb != null) {
|
||||
for (ReloadItem reloadItem : readTagStatesFromDb) {
|
||||
String tag = reloadItem.getTag();
|
||||
String tagChangeIdentifier = reloadItem.getIdentification();
|
||||
this.currentTags.put(tag, tagChangeIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 任务:
|
||||
* 读取数据库中 ReloadItem 数据
|
||||
* 校验是否发生变化
|
||||
* 执行重加载动作
|
||||
*/
|
||||
@Override
|
||||
public void doTask() {
|
||||
// 获取数据库数据
|
||||
List<ReloadItem> readTagStatesFromDb = readReloadItem();
|
||||
String tag;
|
||||
String tagIdentifier;
|
||||
String preTagChangeIdentifier;
|
||||
for (ReloadItem reloadItem : readTagStatesFromDb) {
|
||||
tag = reloadItem.getTag();
|
||||
tagIdentifier = reloadItem.getIdentification();
|
||||
preTagChangeIdentifier = currentTags.get(tag);
|
||||
// 数据不一致
|
||||
if (preTagChangeIdentifier == null || ! preTagChangeIdentifier.equals(tagIdentifier)) {
|
||||
// 更新map数据
|
||||
currentTags.put(tag, tagIdentifier);
|
||||
// 执行重新加载此项的动作
|
||||
handleReloadResult(this.reloadManager.doReload(reloadItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.abstracts;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.SmartReloadManager;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadCommandInterface;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 检测是否 Reload 的类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public abstract class AbstractSmartReloadCommand4Spring implements SmartReloadCommandInterface {
|
||||
|
||||
/**
|
||||
* 当前ReloadItem的存储器
|
||||
*/
|
||||
protected ConcurrentHashMap<String, String> currentTags = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Reload的执行类
|
||||
*/
|
||||
@Autowired
|
||||
protected SmartReloadManager reloadManager;
|
||||
|
||||
public void init() {
|
||||
List<ReloadItem> readTagStatesFromDb = readReloadItem();
|
||||
if (readTagStatesFromDb != null) {
|
||||
for (ReloadItem reloadItem : readTagStatesFromDb) {
|
||||
String tag = reloadItem.getTag();
|
||||
String tagChangeIdentifier = reloadItem.getIdentification();
|
||||
this.currentTags.put(tag, tagChangeIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务:
|
||||
* 读取数据库中 ReloadItem 数据
|
||||
* 校验是否发生变化
|
||||
* 执行重加载动作
|
||||
*/
|
||||
@Override
|
||||
public void doTask() {
|
||||
// 获取数据库数据
|
||||
List<ReloadItem> readTagStatesFromDb = readReloadItem();
|
||||
String tag;
|
||||
String tagIdentifier;
|
||||
String preTagChangeIdentifier;
|
||||
for (ReloadItem reloadItem : readTagStatesFromDb) {
|
||||
tag = reloadItem.getTag();
|
||||
tagIdentifier = reloadItem.getIdentification();
|
||||
preTagChangeIdentifier = currentTags.get(tag);
|
||||
// 数据不一致
|
||||
if (preTagChangeIdentifier == null || ! preTagChangeIdentifier.equals(tagIdentifier)) {
|
||||
// 更新map数据
|
||||
currentTags.put(tag, tagIdentifier);
|
||||
// 执行重新加载此项的动作
|
||||
handleReloadResult(this.reloadManager.doReload(reloadItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 定义 SmartReload 注解
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SmartReload {
|
||||
|
||||
String value();
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.domain;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.SmartReloadResult;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* AbstractSmartReloadObject 处理程序的抽象类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public abstract class AbstractSmartReloadObject {
|
||||
|
||||
protected String getStackTrace(Throwable e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过reloadItem参数reload,获得结果
|
||||
*
|
||||
* @param reloadItem
|
||||
* @return boolean
|
||||
* @author zhuokongming
|
||||
* @date 2016年10月21日 下午2:09:44
|
||||
*/
|
||||
public abstract SmartReloadResult reload(ReloadItem reloadItem);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.domain;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.annotation.SmartReload;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.SmartReloadResult;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Reload 处理程序的实现类
|
||||
* 用于包装以注解 SmartReload 实现的处理类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class AnnotationReloadObject extends AbstractSmartReloadObject {
|
||||
|
||||
private Object reloadObject;
|
||||
|
||||
private Method method;
|
||||
|
||||
public AnnotationReloadObject(Object reloadObject, Method method) {
|
||||
super();
|
||||
this.reloadObject = reloadObject;
|
||||
this.method = method;
|
||||
this.method.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmartReloadResult reload(ReloadItem reloadItem) {
|
||||
SmartReloadResult result = new SmartReloadResult();
|
||||
String tag = ((SmartReload)this.method.getAnnotation(SmartReload.class)).value();
|
||||
result.setTag(tag);
|
||||
result.setArgs(reloadItem.getArgs());
|
||||
result.setIdentification(reloadItem.getIdentification());
|
||||
result.setResult(true);
|
||||
int paramCount = this.method.getParameterCount();
|
||||
if (paramCount > 1) {
|
||||
result.setResult(false);
|
||||
result.setException("reload方法" + this.method.getName() + "参数太多");
|
||||
return result;
|
||||
} else {
|
||||
try {
|
||||
if (paramCount == 0) {
|
||||
this.method.invoke(this.reloadObject);
|
||||
} else {
|
||||
this.method.invoke(this.reloadObject, reloadItem.getArgs());
|
||||
}
|
||||
} catch (Throwable var6) {
|
||||
result.setResult(false);
|
||||
result.setException(this.getStackTrace(var6));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.domain;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.SmartReloadResult;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.interfaces.SmartReloadable;
|
||||
|
||||
/**
|
||||
* Reload 处理程序的实现类
|
||||
* 用于处理以接口实现的处理类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class InterfaceReloadObject extends AbstractSmartReloadObject {
|
||||
|
||||
private SmartReloadable object;
|
||||
|
||||
public InterfaceReloadObject(SmartReloadable object) {
|
||||
super();
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmartReloadResult reload(ReloadItem reloadItem) {
|
||||
SmartReloadResult reloadResult = new SmartReloadResult();
|
||||
reloadResult.setArgs(reloadItem.getArgs());
|
||||
reloadResult.setIdentification(reloadItem.getIdentification());
|
||||
reloadResult.setTag(reloadItem.getTag());
|
||||
try {
|
||||
boolean res = object.reload(reloadItem);
|
||||
reloadResult.setResult(res);
|
||||
} catch (Throwable e) {
|
||||
reloadResult.setException(getStackTrace(e));
|
||||
}
|
||||
return reloadResult;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.domain.entity;
|
||||
/**
|
||||
* ReloadItem 类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class ReloadItem {
|
||||
|
||||
/**
|
||||
* 项名称
|
||||
*/
|
||||
private String tag;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String args;
|
||||
|
||||
/**
|
||||
* 标识
|
||||
*/
|
||||
private String identification;
|
||||
|
||||
public ReloadItem() {
|
||||
|
||||
}
|
||||
public ReloadItem(String tag, String identification, String args) {
|
||||
this.tag = tag;
|
||||
this.identification = identification;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
public String getIdentification() {
|
||||
return identification;
|
||||
}
|
||||
public void setIdentification(String identification) {
|
||||
this.identification = identification;
|
||||
}
|
||||
public String getArgs() {
|
||||
return args;
|
||||
}
|
||||
public void setArgs(String args) {
|
||||
this.args = args;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReloadItem{" + "tag='" + tag + '\'' + ", identification='" + identification + '\'' + ", args='" + args + '\'' + '}';
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.domain.entity;
|
||||
/**
|
||||
* t_reload_result 表 实体类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public class SmartReloadResult {
|
||||
|
||||
/**
|
||||
* 项名称
|
||||
*/
|
||||
private String tag;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String args;
|
||||
|
||||
/**
|
||||
* 标识
|
||||
*/
|
||||
private String identification;
|
||||
|
||||
/**
|
||||
* 处理结果
|
||||
*/
|
||||
private boolean result;
|
||||
|
||||
/**
|
||||
* 异常说明
|
||||
*/
|
||||
private String exception;
|
||||
|
||||
public SmartReloadResult() {
|
||||
}
|
||||
|
||||
public SmartReloadResult(String tag, String args, boolean result, String exception) {
|
||||
this.tag = tag;
|
||||
this.args = args;
|
||||
this.result = result;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public SmartReloadResult(String tag, String args, String identification, boolean result, String exception) {
|
||||
this.tag = tag;
|
||||
this.args = args;
|
||||
this.identification = identification;
|
||||
this.result = result;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public void setArgs(String args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public void setIdentification(String identification) {
|
||||
this.identification = identification;
|
||||
}
|
||||
|
||||
public void setResult(boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public void setException(String exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public String getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public String getIdentification() {
|
||||
return identification;
|
||||
}
|
||||
|
||||
public boolean isResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SmartReloadResult{" +
|
||||
"tag='" + tag + '\'' +
|
||||
", args='" + args + '\'' +
|
||||
", identification='" + identification + '\'' +
|
||||
", result=" + result +
|
||||
", exception='" + exception + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.interfaces;
|
||||
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.SmartReloadResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检测是否 Reload 的类
|
||||
*
|
||||
* @author zhuoda
|
||||
*/
|
||||
public interface SmartReloadCommandInterface {
|
||||
|
||||
/**
|
||||
* 任务:
|
||||
* 读取数据库中 ReloadItem 数据
|
||||
* 校验是否发生变化
|
||||
* 执行重加载动作
|
||||
*/
|
||||
void doTask();
|
||||
|
||||
/**
|
||||
* 该方法返回一个List<ReloadItem></>:<br>
|
||||
* ReloadItem对象的tagIdentify为:该tag的 状态(状态其实就是个字符串,如果该字符串跟上次有变化则进行reload操作)<br>
|
||||
* ReloadItem对象的args为: reload操作需要的参数<br><br>
|
||||
*
|
||||
* @return List<ReloadItem>
|
||||
*/
|
||||
List<ReloadItem> readReloadItem();
|
||||
|
||||
/**
|
||||
* 处理Reload结果
|
||||
*
|
||||
* @param reloadResult
|
||||
*/
|
||||
void handleReloadResult(SmartReloadResult reloadResult);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.interfaces;
|
||||
|
||||
/**
|
||||
* SmartReloadThreadLogger 日志类
|
||||
*/
|
||||
public interface SmartReloadThreadLogger {
|
||||
|
||||
void error(String string);
|
||||
|
||||
void error(String string, Throwable e);
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package net.lab1024.smartadmin.service.module.support.reload.interfaces;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.reload.domain.entity.ReloadItem;
|
||||
|
||||
/**
|
||||
* reload 接口<br>
|
||||
* 需要reload的业务实现类
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SmartReloadable {
|
||||
|
||||
/**
|
||||
* reload
|
||||
*
|
||||
* @param reloadItem
|
||||
* @return boolean
|
||||
*/
|
||||
boolean reload(ReloadItem reloadItem);
|
||||
}
|
@ -24,7 +24,6 @@ import java.util.function.Function;
|
||||
* @date
|
||||
*/
|
||||
@Aspect
|
||||
@Order(1)
|
||||
public class SmartRepeatSubmitAspect {
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.common.constant.SystemEnvironmentEnum;
|
||||
import net.lab1024.smartadmin.service.common.domain.SystemEnvironmentBO;
|
||||
import net.lab1024.smartadmin.service.module.system.employee.EmployeeService;
|
||||
import net.lab1024.smartadmin.service.module.system.login.domain.EmployeeLoginBO;
|
||||
import net.lab1024.smartadmin.service.module.system.login.domain.EmployeeLoginInfoDTO;
|
||||
@ -42,7 +43,7 @@ public class EmployeeLoginTokenService {
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Autowired
|
||||
private SystemEnvironmentEnum systemEnvironment;
|
||||
private SystemEnvironmentBO systemEnvironmentBO;
|
||||
|
||||
/**
|
||||
* 生成 JWT TOKEN
|
||||
@ -74,7 +75,8 @@ public class EmployeeLoginTokenService {
|
||||
* 非生产环境 直接使用 token 作为id
|
||||
* 不需要的话 注释了吧
|
||||
*/
|
||||
if (SystemEnvironmentEnum.PROD != systemEnvironment && NumberUtils.isParsable(token)) {
|
||||
SystemEnvironmentEnum currentEnvironment = systemEnvironmentBO.getCurrentEnvironment();
|
||||
if (SystemEnvironmentEnum.PROD != currentEnvironment && NumberUtils.isParsable(token)) {
|
||||
return employeeService.getById(Long.parseLong(token));
|
||||
}
|
||||
|
||||
@ -104,7 +106,8 @@ public class EmployeeLoginTokenService {
|
||||
* 非生产环境 直接使用 token 作为id
|
||||
* 不需要的话 注释了吧
|
||||
*/
|
||||
if (SystemEnvironmentEnum.PROD != systemEnvironment && NumberUtils.isParsable(token)) {
|
||||
SystemEnvironmentEnum currentEnvironment = systemEnvironmentBO.getCurrentEnvironment();
|
||||
if (SystemEnvironmentEnum.PROD != currentEnvironment && NumberUtils.isParsable(token)) {
|
||||
return employeeService.getBoById(Long.parseLong(token));
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ package net.lab1024.smartadmin.service.third;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.lab1024.smartadmin.service.module.support.redismq.RedisMqTopicEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.redismq.RedisMsgDTO;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
@ -707,15 +705,4 @@ public class SmartRedisService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送redis消息
|
||||
*
|
||||
* @param topicEnum
|
||||
* @param msgType
|
||||
* @param jsonData
|
||||
*/
|
||||
public void sendMsg(RedisMqTopicEnum topicEnum, Integer msgType, String jsonData) {
|
||||
RedisMsgDTO redisMsgDTO = new RedisMsgDTO(msgType, jsonData);
|
||||
stringRedisTemplate.convertAndSend(topicEnum.getValue(), JSONObject.toJSONString(redisMsgDTO));
|
||||
}
|
||||
}
|
@ -22,9 +22,9 @@ spring.jackson.time-zone=GMT+8
|
||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||
|
||||
######################### database #########################
|
||||
spring.datasource.url=jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v2?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
||||
spring.datasource.url=jdbc:p6spy:mysql://115.29.150.222:11024/smart_admin_v2?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=root
|
||||
spring.datasource.password=11024Lab
|
||||
spring.datasource.initial-size=2
|
||||
spring.datasource.min-idle=1
|
||||
spring.datasource.max-active=10
|
||||
@ -40,14 +40,14 @@ spring.datasource.druid.service.scanner=net.lab1024.smartadmin.module..*Service.
|
||||
|
||||
######################### redis #######################################
|
||||
spring.redis.database=1
|
||||
spring.redis.host=127.0.0.1
|
||||
spring.redis.host=115.29.150.222
|
||||
spring.redis.lettuce.pool.max-active=100
|
||||
spring.redis.lettuce.pool.min-idle=5
|
||||
spring.redis.lettuce.pool.max-idle=10
|
||||
spring.redis.lettuce.pool.max-wait=30000ms
|
||||
spring.redis.port=1234
|
||||
spring.redis.port=21024
|
||||
spring.redis.timeout=10000ms
|
||||
spring.redis.password=root
|
||||
spring.redis.password=21024Lab
|
||||
|
||||
######################### swagger #########################
|
||||
swagger.apiGroupName=smartAdmin
|
||||
|
Loading…
Reference in New Issue
Block a user