Commit e495c854 authored by liaozan's avatar liaozan 🏀

Polish

parent 0b7013c0
......@@ -37,6 +37,11 @@ public class ExcelReadListenerBase<T> extends AnalysisEventListener<T> {
this.headers = headMap;
}
@Override
public void onException(Exception exception, AnalysisContext context) {
throw new ExcelException(exception.getMessage(), exception);
}
@Override
public void invoke(T data, AnalysisContext context) {
boolean validated = validate(data, context);
......@@ -48,11 +53,6 @@ public class ExcelReadListenerBase<T> extends AnalysisEventListener<T> {
this.dataList.add(data);
}
@Override
public void onException(Exception exception, AnalysisContext context) {
throw new ExcelException(exception.getMessage(), exception);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
......
......@@ -36,10 +36,6 @@ public class HierarchicalDataReadListener extends ExcelReadListenerBase<Map<Inte
});
}
public List<ImportedRecord> getImportedRecords() {
return importedRecords;
}
@Override
protected boolean validate(Map<Integer, String> data, AnalysisContext context) {
Integer rowIndex = context.readRowHolder().getRowIndex();
......@@ -54,6 +50,10 @@ public class HierarchicalDataReadListener extends ExcelReadListenerBase<Map<Inte
return true;
}
public List<ImportedRecord> getImportedRecords() {
return importedRecords;
}
protected void buildImportedRow(Integer rowIndex, Integer columnIndex, String text) {
ImportedRecord importedRecord = new ImportedRecord();
importedRecord.setText(text);
......
......@@ -15,6 +15,10 @@ public class ValidateUtils {
private ValidateUtils() {
}
public static void isTrue(boolean expression) {
isTrue(expression, "操作有误");
}
public static void isTrue(boolean expression, String message) {
isTrue(expression, () -> new ParamInvalidException(message));
}
......@@ -25,6 +29,10 @@ public class ValidateUtils {
}
}
public static void isFalse(boolean expression) {
isFalse(expression, "操作有误");
}
public static void isFalse(boolean expression, String message) {
isFalse(expression, () -> new ParamInvalidException(message));
}
......@@ -35,6 +43,10 @@ public class ValidateUtils {
}
}
public static void notNull(Object object) {
notNull(object, "The validated object is null");
}
public static void notNull(Object object, String message) {
notNull(object, () -> new ParamInvalidException(message));
}
......@@ -45,6 +57,10 @@ public class ValidateUtils {
}
}
public static void isNull(Object object) {
isNull(object, "The validated object is not null");
}
public static void isNull(Object object, String message) {
isNull(object, () -> new ParamInvalidException(message));
}
......@@ -55,6 +71,10 @@ public class ValidateUtils {
}
}
public static void notEmpty(String value) {
notEmpty(value, "The validated string is empty");
}
public static void notEmpty(String value, String message) {
notEmpty(value, () -> new ParamInvalidException(message));
}
......@@ -65,6 +85,10 @@ public class ValidateUtils {
}
}
public static void isEmpty(String value) {
isEmpty(value, "The validated string is not empty");
}
public static void isEmpty(String value, String message) {
isEmpty(value, () -> new ParamInvalidException(message));
}
......@@ -75,6 +99,10 @@ public class ValidateUtils {
}
}
public static void notEmpty(Object[] array) {
notEmpty(array, "The validated array is empty");
}
public static void notEmpty(Object[] array, String message) {
notEmpty(array, () -> new ParamInvalidException(message));
}
......@@ -85,6 +113,10 @@ public class ValidateUtils {
}
}
public static void isEmpty(Object[] array) {
isEmpty(array, "The validated array is not empty");
}
public static void isEmpty(Object[] array, String message) {
isEmpty(array, () -> new ParamInvalidException(message));
}
......@@ -95,6 +127,10 @@ public class ValidateUtils {
}
}
public static void notEmpty(Collection<?> collection) {
notEmpty(collection, "The validated collection is empty");
}
public static void notEmpty(Collection<?> collection, String message) {
notEmpty(collection, () -> new ParamInvalidException(message));
}
......@@ -105,6 +141,10 @@ public class ValidateUtils {
}
}
public static void isEmpty(Collection<?> collection) {
isEmpty(collection, "The validated collection is not empty");
}
public static void isEmpty(Collection<?> collection, String message) {
isEmpty(collection, () -> new ParamInvalidException(message));
}
......@@ -115,6 +155,10 @@ public class ValidateUtils {
}
}
public static void notEmpty(Map<?, ?> map) {
notEmpty(map, "The validated map is empty");
}
public static void notEmpty(Map<?, ?> map, String message) {
notEmpty(map, () -> new ParamInvalidException(message));
}
......@@ -125,6 +169,10 @@ public class ValidateUtils {
}
}
public static void isEmpty(Map<?, ?> map) {
isEmpty(map, "The validated map is not empty");
}
public static void isEmpty(Map<?, ?> map, String message) {
isEmpty(map, () -> new ParamInvalidException(message));
}
......
......@@ -3,8 +3,8 @@ package com.schbrain.common.web;
import com.schbrain.common.web.exception.*;
import com.schbrain.common.web.properties.WebProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -15,24 +15,25 @@ import java.util.stream.Collectors;
* @since 2023-05-08
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "schbrain.web.enable-global-exception-handler", havingValue = "true", matchIfMissing = true)
public class ExceptionHandingConfiguration {
@Bean
public GlobalExceptionHandler defaultGlobalExceptionHandler(ObjectProvider<ExceptionTranslator> exceptionTranslators) {
return new GlobalExceptionHandler(exceptionTranslators.orderedStream().collect(Collectors.toList()));
@ConditionalOnMissingBean
public ExceptionTranslator defaultExceptionTranslator() {
return new DefaultExceptionTranslator();
}
@Bean
@ConditionalOnMissingBean
public ExceptionHandingWebMvcConfigurer defaultExceptionHandingWebMvcConfigurer(WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
return new ExceptionHandingWebMvcConfigurer(webProperties, exceptionHandler);
public GlobalExceptionHandler defaultGlobalExceptionHandler(ObjectProvider<ExceptionTranslator> exceptionTranslators) {
return new GlobalExceptionHandler(exceptionTranslators.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(GlobalExceptionHandler.class)
public ExceptionTranslator defaultExceptionTranslator() {
return new DefaultExceptionTranslator();
public ExceptionHandingWebMvcConfigurer defaultExceptionHandingWebMvcConfigurer(WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
return new ExceptionHandingWebMvcConfigurer(webProperties, exceptionHandler);
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import com.schbrain.common.web.log.RequestLoggingFilter;
import com.schbrain.common.web.properties.WebProperties;
import com.schbrain.common.web.servlet.CharacterEncodingServletContextInitializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -32,8 +33,9 @@ public class ServletComponentConfiguration {
@Bean
@ConditionalOnMissingBean
public RequestLoggingFilter requestLoggingFilter(WebProperties properties) {
return new RequestLoggingFilter(properties);
@ConditionalOnProperty(value = "schbrain.web.enable-request-logging", havingValue = "true", matchIfMissing = true)
public RequestLoggingFilter requestLoggingFilter() {
return new RequestLoggingFilter();
}
}
\ No newline at end of file
......@@ -9,8 +9,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
......@@ -48,9 +47,10 @@ public class WebCommonAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ResponseBodyHandler defaultResponseBodyHandler(WebProperties properties, BeanFactory beanFactory) {
@ConditionalOnProperty(value = "schbrain.web.wrap-response", havingValue = "true", matchIfMissing = true)
public ResponseBodyHandler defaultResponseBodyHandler(BeanFactory beanFactory) {
List<String> basePackages = AutoConfigurationPackages.get(beanFactory);
return new ResponseBodyHandler(properties, basePackages);
return new ResponseBodyHandler(basePackages);
}
@Bean
......
package com.schbrain.common.web.exception;
import com.schbrain.common.web.annotation.ResponseWrapOption;
import com.schbrain.common.web.properties.WebProperties;
import com.schbrain.common.web.utils.HandlerMethodAnnotationUtils;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
......@@ -29,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
@EqualsAndHashCode(callSuper = true)
public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExceptionResolver {
private final WebProperties webProperties;
private final boolean wrapResponse;
private final GlobalExceptionHandler exceptionHandler;
......@@ -41,8 +40,8 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerMethodResolvers = new ConcurrentHashMap<>(64);
public DefaultGlobalExceptionResolver(ExceptionHandlerExceptionResolver handlerMethodResolver, WebProperties webProperties, GlobalExceptionHandler exceptionHandler) {
this.webProperties = webProperties;
public DefaultGlobalExceptionResolver(ExceptionHandlerExceptionResolver handlerMethodResolver, boolean wrapResponse, GlobalExceptionHandler exceptionHandler) {
this.wrapResponse = wrapResponse;
this.exceptionHandler = exceptionHandler;
this.handlerMethodResolver = new ExceptionHandlerMethodResolver(exceptionHandler.getClass());
this.argumentResolverComposite = handlerMethodResolver.getArgumentResolvers();
......@@ -52,7 +51,7 @@ public class DefaultGlobalExceptionResolver extends AbstractHandlerMethodExcepti
@Override
protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {
if (!webProperties.isWrapResponse()) {
if (!wrapResponse) {
return false;
}
......
......@@ -49,7 +49,7 @@ public class ExceptionHandingWebMvcConfigurer implements WebMvcConfigurer {
}
protected HandlerExceptionResolver createExceptionResolver(ExceptionHandlerExceptionResolver adviceExceptionResolver) {
return new DefaultGlobalExceptionResolver(adviceExceptionResolver, webProperties, globalExceptionHandler);
return new DefaultGlobalExceptionResolver(adviceExceptionResolver, webProperties.isWrapResponse(), globalExceptionHandler);
}
}
\ No newline at end of file
......@@ -2,7 +2,6 @@ package com.schbrain.common.web.log;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.ArrayUtil;
import com.schbrain.common.web.properties.WebProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.filter.OrderedFilter;
import org.springframework.core.Ordered;
......@@ -27,15 +26,9 @@ import static com.schbrain.common.web.utils.ContentCachingServletUtils.wrapReque
@Slf4j
public class RequestLoggingFilter extends OncePerRequestFilter implements OrderedFilter {
private final WebProperties webProperties;
public RequestLoggingFilter(WebProperties webProperties) {
this.webProperties = webProperties;
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
return Ordered.HIGHEST_PRECEDENCE + 10;
}
@Override
......@@ -57,9 +50,6 @@ public class RequestLoggingFilter extends OncePerRequestFilter implements Ordere
}
protected boolean shouldSkip(HttpServletRequest request) {
if (!webProperties.isEnableRequestLogging()) {
return true;
}
return CorsUtils.isPreFlightRequest(request);
}
......
package com.schbrain.common.web.result;
import com.schbrain.common.web.annotation.ResponseWrapOption;
import com.schbrain.common.web.properties.WebProperties;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
......@@ -22,34 +21,23 @@ import java.util.concurrent.ConcurrentHashMap;
@RestControllerAdvice
public class ResponseBodyHandler implements ResponseBodyAdvice<Object> {
private final WebProperties webProperties;
private final List<String> basePackages;
private final Map<Method, Boolean> methodCache;
private final Map<Method, Boolean> methodCache = new ConcurrentHashMap<>();
public ResponseBodyHandler(WebProperties webProperties, List<String> basePackages) {
this.webProperties = webProperties;
public ResponseBodyHandler(List<String> basePackages) {
this.basePackages = basePackages;
this.methodCache = new ConcurrentHashMap<>();
}
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
if (!webProperties.isWrapResponse()) {
return false;
}
return methodCache.computeIfAbsent(returnType.getMethod(), this::shouldApply);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
return beforeBodyWrite(body);
}
protected Object beforeBodyWrite(Object body) {
if (body instanceof ResponseDTO) {
return body;
}
......
......@@ -11,16 +11,16 @@ import javax.servlet.ServletRequestListener;
*/
public class TraceIdInitializeServletListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent event) {
// Make sure the traceId is initialized
TraceIdUtils.get();
}
@Override
public void requestDestroyed(ServletRequestEvent event) {
// Make sure the traceId can be cleared
TraceIdUtils.clear();
}
@Override
public void requestInitialized(ServletRequestEvent event) {
// Make sure the traceId is initialized
TraceIdUtils.get();
}
}
\ No newline at end of file
......@@ -46,19 +46,19 @@ public class BaseHandlerInterceptor implements AsyncHandlerInterceptor {
}
}
protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) throws Exception {
protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
return true;
}
protected void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, ModelAndView modelAndView) throws Exception {
protected void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, ModelAndView modelAndView) throws Exception {
}
protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, Exception ex) throws Exception {
protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception ex) throws Exception {
}
protected void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
protected void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
}
......
......@@ -34,8 +34,8 @@ public abstract class AbstractAuthenticator implements Authenticator {
}
@Override
public boolean validate(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
boolean ignore = HandlerMethodAnnotationUtils.hasAnnotation(handler, IgnoreLogin.class);
public boolean validate(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
boolean ignore = HandlerMethodAnnotationUtils.hasAnnotation(handlerMethod, IgnoreLogin.class);
if (ignore) {
return true;
}
......@@ -43,10 +43,10 @@ public abstract class AbstractAuthenticator implements Authenticator {
if (StringUtils.isBlank(authentication)) {
return false;
}
return doValidate(authentication, request, response, handler);
return doValidate(authentication, request, response, handlerMethod);
}
protected abstract boolean doValidate(String authentication, HttpServletRequest request, HttpServletResponse response, HandlerMethod handler);
protected abstract boolean doValidate(String authentication, HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod);
@Nullable
protected String getAuthentication(HttpServletRequest request) {
......
......@@ -38,8 +38,8 @@ public class AuthenticationInterceptor extends BaseHandlerInterceptor implements
}
@Override
protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
boolean validated = authenticator.validate(request, response, handler);
protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
boolean validated = authenticator.validate(request, response, handlerMethod);
if (validated) {
return true;
}
......@@ -48,8 +48,8 @@ public class AuthenticationInterceptor extends BaseHandlerInterceptor implements
}
@Override
protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, Exception ex) {
authenticator.afterCompletion(request, response, handler, ex);
protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception ex) {
authenticator.afterCompletion(request, response, handlerMethod, ex);
}
protected void writeResult(HttpServletResponse response, ResponseDTO<?> result) {
......
......@@ -19,6 +19,6 @@ public interface Authenticator {
/**
* 请求完成后的回调
*/
void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, Exception exception);
void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception);
}
\ No newline at end of file
......@@ -79,7 +79,7 @@
<guava.version>32.0.1-jre</guava.version>
<hutool.version>5.8.20</hutool.version>
<jsr305.version>3.0.2</jsr305.version>
<logstash-logback-encoder.version>7.4</logstash-logback-encoder.version>
<logstash-logback-encoder.version>7.3</logstash-logback-encoder.version>
<mybatis.version>3.5.13</mybatis.version>
<mybatis.starter.version>2.3.0</mybatis.starter.version>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
......
......@@ -54,7 +54,7 @@ class ConfigurablePropertiesLoader {
ApolloProperties apolloProperties = ApolloProperties.get(environment);
// MUST NOT use CachedCompositePropertySource
// MUST NOT use CachedCompositePropertySource, because propertyNames will be cached when property loading
CompositePropertySource compositePropertySource = new CompositePropertySource(PROPERTIES_PROPERTY_SOURCE);
if (apolloProperties.isRemoteFirst()) {
environment.getPropertySources().addFirst(compositePropertySource);
......
......@@ -10,7 +10,6 @@ import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
/**
* AutoConfiguration for schbrain cache
......@@ -25,10 +24,10 @@ public class CacheAutoConfiguration {
@Bean
@ConditionalOnBean(CacheProvider.class)
public CacheProvider cacheProvider(CacheProvider cacheProvider, CacheProperties cacheProperties, Environment environment) {
CacheProviderDelegate delegate = new CacheProviderDelegate(cacheProperties, cacheProvider, environment);
CacheUtils.setCacheProvider(delegate);
return delegate;
public CacheProvider cacheProvider(CacheProvider cacheProvider, CacheProperties cacheProperties) {
CacheProvider provider = new CacheProviderDelegate(cacheProperties, cacheProvider);
CacheUtils.setCacheProvider(provider);
return provider;
}
}
\ No newline at end of file
......@@ -46,6 +46,20 @@ public class CacheUtils {
return getCacheProvider().getExpire(cacheKey);
}
/**
* 模糊搜索 key, 默认采用 scan 实现
*/
public static Set<String> keys(String pattern) {
return keys(pattern, Long.MAX_VALUE);
}
/**
* 模糊搜索 key, 默认采用 scan 实现
*/
public static Set<String> keys(String pattern, long limit) {
return getCacheProvider().keys(pattern, limit);
}
/**
* 获取缓存数据
*/
......@@ -161,18 +175,4 @@ public class CacheUtils {
getCacheProvider().del(cacheKeys);
}
/**
* 模糊搜索 key, 默认采用 scan 实现
*/
public static Set<String> keys(String pattern) {
return keys(pattern, Long.MAX_VALUE);
}
/**
* 模糊搜索 key, 默认采用 scan 实现
*/
public static Set<String> keys(String pattern, long limit) {
return getCacheProvider().keys(pattern, limit);
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.cache.provider;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* @author zhuyf
......@@ -12,6 +9,11 @@ import java.util.Set;
**/
public interface CacheProvider {
/**
* 查询key是否过期
*/
boolean isExpired(String cacheKey);
/**
* 指定缓存失效时间
*/
......@@ -27,30 +29,20 @@ public interface CacheProvider {
*/
boolean hasKey(String cacheKey);
/**
* 删除缓存
*/
void del(List<String> cacheKeys);
/**
* 模糊搜索 key, 默认采用 scan 实现
*/
Set<String> keys(String pattern, long limit);
/**
* 缓存获取
* 删除缓存
*/
<T> T get(String cacheKey, Class<T> valueType);
void del(List<String> cacheKeys);
/**
* 缓存获取
*/
<T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> valueType, boolean discardIfValueIsNull);
/**
* list 缓存获取
*/
<T> List<T> getList(String cacheKey, Class<T> valueType);
<T> T get(String cacheKey, Class<T> valueType);
/**
* 缓存放入并设置时间
......@@ -63,8 +55,13 @@ public interface CacheProvider {
<T> void multiSet(Map<String, T> data, Duration expiration);
/**
* 查询key是否过期
* 缓存获取
*/
boolean isExpired(String cacheKey);
<T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> valueType, boolean discardIfValueIsNull);
/**
* list 缓存获取
*/
<T> List<T> getList(String cacheKey, Class<T> valueType);
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ import com.schbrain.framework.autoconfigure.cache.properties.CacheProperties;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import java.time.Duration;
import java.util.*;
......@@ -24,12 +23,12 @@ public class CacheProviderDelegate implements CacheProvider {
private final CacheProvider cacheProvider;
public CacheProviderDelegate(CacheProperties properties, CacheProvider cacheProvider, Environment environment) {
public CacheProviderDelegate(CacheProperties properties, CacheProvider cacheProvider) {
this.cacheProvider = cacheProvider;
if (properties.isAppendPrefix()) {
String prefix = properties.getPrefix();
if (StringUtils.isBlank(prefix)) {
prefix = ApplicationName.get(environment);
prefix = ApplicationName.get();
}
this.prefixWithDelimiter = prefix + properties.getDelimiter();
} else {
......@@ -37,6 +36,11 @@ public class CacheProviderDelegate implements CacheProvider {
}
}
@Override
public boolean isExpired(String cacheKey) {
return getCacheProvider().isExpired(withKeyPrefix(cacheKey));
}
@Override
public void expire(String cacheKey, Duration expiration) {
checkDuration(expiration);
......@@ -53,15 +57,6 @@ public class CacheProviderDelegate implements CacheProvider {
return getCacheProvider().hasKey(withKeyPrefix(cacheKey));
}
@Override
public void del(List<String> cacheKeys) {
if (CollectionUtils.isEmpty(cacheKeys)) {
return;
}
List<String> keysWithPrefix = StreamUtils.toList(cacheKeys, this::withKeyPrefix);
getCacheProvider().del(keysWithPrefix);
}
@Override
public Set<String> keys(String pattern, long limit) {
Set<String> keys = getCacheProvider().keys(withKeyPrefix(pattern), limit);
......@@ -69,46 +64,17 @@ public class CacheProviderDelegate implements CacheProvider {
}
@Override
public <T> T get(String cacheKey, Class<T> valueType) {
return getCacheProvider().get(withKeyPrefix(cacheKey), valueType);
}
@Override
public <T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> valueType, boolean discardIfValueIsNull) {
public void del(List<String> cacheKeys) {
if (CollectionUtils.isEmpty(cacheKeys)) {
return Collections.emptyMap();
return;
}
List<String> keysWithPrefix = StreamUtils.toList(cacheKeys, this::withKeyPrefix);
Map<String, T> cachedDate = getCacheProvider().multiGet(keysWithPrefix, valueType, discardIfValueIsNull);
Map<String, T> result = Maps.newHashMapWithExpectedSize(keysWithPrefix.size());
// 这里不能用 Stream toMap, toMap 不允许 value 是 null
if (MapUtils.isEmpty(cachedDate)) {
if (discardIfValueIsNull) {
result = Collections.emptyMap();
} else {
for (String cacheKey : keysWithPrefix) {
result.put(removeKeyPrefix(cacheKey), null);
}
}
return result;
} else {
if (discardIfValueIsNull) {
// 值为 null 的key 在实现类获取时已经被丢弃,直接遍历 put 即可
for (Entry<String, T> cacheEntry : cachedDate.entrySet()) {
result.put(removeKeyPrefix(cacheEntry.getKey()), cacheEntry.getValue());
}
} else {
for (String cacheKey : keysWithPrefix) {
result.put(removeKeyPrefix(cacheKey), cachedDate.get(cacheKey));
}
}
}
return result;
getCacheProvider().del(keysWithPrefix);
}
@Override
public <T> List<T> getList(String cacheKey, Class<T> valueType) {
return getCacheProvider().getList(withKeyPrefix(cacheKey), valueType);
public <T> T get(String cacheKey, Class<T> valueType) {
return getCacheProvider().get(withKeyPrefix(cacheKey), valueType);
}
@Override
......@@ -131,8 +97,27 @@ public class CacheProviderDelegate implements CacheProvider {
}
@Override
public boolean isExpired(String cacheKey) {
return getCacheProvider().isExpired(withKeyPrefix(cacheKey));
public <T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> valueType, boolean discardIfValueIsNull) {
if (CollectionUtils.isEmpty(cacheKeys)) {
return Collections.emptyMap();
}
List<String> keysWithPrefix = StreamUtils.toList(cacheKeys, this::withKeyPrefix);
Map<String, T> dataWithPrefixedKey = getCacheProvider().multiGet(keysWithPrefix, valueType, discardIfValueIsNull);
if (MapUtils.isEmpty(dataWithPrefixedKey)) {
return Collections.emptyMap();
} else {
Map<String, T> result = Maps.newHashMapWithExpectedSize(dataWithPrefixedKey.size());
// 这里不能用 Stream toMap, toMap 不允许 value 是 null
for (Entry<String, T> cacheEntry : dataWithPrefixedKey.entrySet()) {
result.put(removeKeyPrefix(cacheEntry.getKey()), cacheEntry.getValue());
}
return result;
}
}
@Override
public <T> List<T> getList(String cacheKey, Class<T> valueType) {
return getCacheProvider().getList(withKeyPrefix(cacheKey), valueType);
}
public CacheProvider getCacheProvider() {
......
......@@ -7,10 +7,7 @@ import com.schbrain.framework.autoconfigure.cache.exception.CacheException;
import com.schbrain.framework.autoconfigure.cache.provider.CacheProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.CollectionUtils;
......@@ -34,6 +31,14 @@ public class RedisCacheProvider implements CacheProvider {
this.redisTemplate = redisTemplate;
}
/**
* 查询key是否过期
*/
@Override
public boolean isExpired(String cacheKey) {
return !hasKey(cacheKey);
}
/**
* 指定缓存失效时间
*/
......@@ -62,17 +67,6 @@ public class RedisCacheProvider implements CacheProvider {
return Boolean.TRUE.equals(redisTemplate.hasKey(cacheKey));
}
/**
* 删除缓存
*/
@Override
public void del(List<String> cacheKeys) {
if (CollectionUtils.isEmpty(cacheKeys)) {
return;
}
redisTemplate.delete(cacheKeys);
}
/**
* 模糊搜索 key
*/
......@@ -92,35 +86,22 @@ public class RedisCacheProvider implements CacheProvider {
}
/**
* 缓存获取
* 删除缓存
*/
@Override
public <T> T get(String cacheKey, Class<T> type) {
return JacksonUtils.getObjectFromJson(getValueFromRedis(cacheKey), type);
}
@Override
public <T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> type, boolean discardIfValueIsNull) {
Map<String, T> result = Maps.newHashMapWithExpectedSize(cacheKeys.size());
Iterables.partition(cacheKeys, DEFAULT_BATCH_SIZE).forEach(subKeys -> {
List<String> valueList = Objects.requireNonNull(redisTemplate.opsForValue().multiGet(subKeys));
for (int i = 0; i < subKeys.size(); i++) {
T rawValue = JacksonUtils.getObjectFromJson(valueList.get(i), type);
if (discardIfValueIsNull && rawValue == null) {
continue;
}
result.put(subKeys.get(i), rawValue);
public void del(List<String> cacheKeys) {
if (CollectionUtils.isEmpty(cacheKeys)) {
return;
}
});
return result;
redisTemplate.delete(cacheKeys);
}
/**
* list 缓存获取
* 缓存获取
*/
@Override
public <T> List<T> getList(String cacheKey, Class<T> type) {
return JacksonUtils.getListFromJson(getValueFromRedis(cacheKey), type);
public <T> T get(String cacheKey, Class<T> type) {
return JacksonUtils.getObjectFromJson(getValueFromRedis(cacheKey), type);
}
/**
......@@ -140,19 +121,36 @@ public class RedisCacheProvider implements CacheProvider {
byteMap.put(key.getBytes(StandardCharsets.UTF_8), JacksonUtils.writeObjectAsBytes(data.get(key)));
}
connection.mSet(byteMap);
long expirationMillis = expiration.toMillis();
for (byte[] rawKey : byteMap.keySet()) {
connection.pExpire(rawKey, expiration.toMillis());
connection.pExpire(rawKey, expirationMillis);
}
return null;
}));
}
@Override
public <T> Map<String, T> multiGet(Collection<String> cacheKeys, Class<T> type, boolean discardIfValueIsNull) {
Map<String, T> result = Maps.newHashMapWithExpectedSize(cacheKeys.size());
Iterables.partition(cacheKeys, DEFAULT_BATCH_SIZE).forEach(subKeys -> {
List<String> valueList = Objects.requireNonNull(redisTemplate.opsForValue().multiGet(subKeys));
for (int i = 0; i < subKeys.size(); i++) {
T rawValue = JacksonUtils.getObjectFromJson(valueList.get(i), type);
if (discardIfValueIsNull && rawValue == null) {
continue;
}
result.put(subKeys.get(i), rawValue);
}
});
return result;
}
/**
* 查询key是否过期
* list 缓存获取
*/
@Override
public boolean isExpired(String cacheKey) {
return !hasKey(cacheKey);
public <T> List<T> getList(String cacheKey, Class<T> type) {
return JacksonUtils.getListFromJson(getValueFromRedis(cacheKey), type);
}
private String getValueFromRedis(String cacheKey) {
......
......@@ -12,6 +12,9 @@ import com.schbrain.framework.autoconfigure.apollo.event.ConfigLoadedEvent;
import com.schbrain.framework.autoconfigure.apollo.event.listener.GenericConfigLoadedEventListener;
import com.schbrain.framework.autoconfigure.logger.LoggerConfigurationInitializer;
import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import org.springframework.boot.context.logging.LoggingApplicationListener;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
......@@ -48,9 +51,9 @@ public class LoggerConfigLoadedEventListener extends GenericConfigLoadedEventLis
}
/**
* Add {@link org.springframework.boot.context.logging.LoggingApplicationListener#CONFIG_PROPERTY} property to SystemProperty
* Add {@link LoggingApplicationListener#CONFIG_PROPERTY} property to SystemProperty
*
* @see org.springframework.boot.context.logging.LoggingApplicationListener#initializeSystem(ConfigurableEnvironment, org.springframework.boot.logging.LoggingSystem, org.springframework.boot.logging.LogFile)
* @see LoggingApplicationListener#initializeSystem(ConfigurableEnvironment, LoggingSystem, LogFile)
*/
@SuppressWarnings("JavadocReference")
private void configLoggingFileLocation(ConfigurableEnvironment environment, String logConfigNamespace) {
......
......@@ -19,13 +19,13 @@ public abstract class DataSourcePropertiesExtractorSupport implements DataSource
return TypeUtils.isAssignable(supportedType, dataSource.getClass());
}
public abstract Class<? extends DataSource> getSupportedType();
@Override
public Properties extract(DataSource dataSource, Map<String, String> properties) throws SQLException {
return extract(dataSource);
}
protected abstract Class<? extends DataSource> getSupportedType();
protected abstract Properties extract(DataSource dataSource) throws SQLException;
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ import java.util.Properties;
public class DruidDataSourcePropertiesExtractor extends DataSourcePropertiesExtractorSupport {
@Override
public Class<DruidDataSource> getSupportedType() {
protected Class<DruidDataSource> getSupportedType() {
return DruidDataSource.class;
}
......
......@@ -15,7 +15,7 @@ import java.util.Properties;
public class HikariDataSourcePropertiesExtractor extends DataSourcePropertiesExtractorSupport {
@Override
public Class<? extends DataSource> getSupportedType() {
protected Class<? extends DataSource> getSupportedType() {
return HikariDataSource.class;
}
......
package com.schbrain.framework.autoconfigure.xxl;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import com.xxl.job.core.thread.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
/**
* @author liaozan
* @since 2022/4/18
*/
@Slf4j
public class SchbrainXxlJobExecutor extends XxlJobSpringExecutor implements InitializingBean, DisposableBean {
private Field executorRegistryThreadStopField;
private Field jobLogFileCleanThreadStopField;
private Field triggerCallbackThreadStopField;
private volatile boolean started = false;
public SchbrainXxlJobExecutor() {
try {
this.executorRegistryThreadStopField = ExecutorRegistryThread.class.getDeclaredField("toStop");
ReflectionUtils.makeAccessible(executorRegistryThreadStopField);
} catch (Exception e) {
this.executorRegistryThreadStopField = null;
}
try {
this.triggerCallbackThreadStopField = TriggerCallbackThread.class.getDeclaredField("toStop");
ReflectionUtils.makeAccessible(triggerCallbackThreadStopField);
} catch (Exception e) {
this.triggerCallbackThreadStopField = null;
}
try {
this.jobLogFileCleanThreadStopField = JobLogFileCleanThread.class.getDeclaredField("toStop");
ReflectionUtils.makeAccessible(jobLogFileCleanThreadStopField);
} catch (Exception e) {
this.jobLogFileCleanThreadStopField = null;
}
}
@Override
public void start() throws Exception {
afterPropertiesSet();
}
@Override
public void afterPropertiesSet() throws Exception {
if (started) {
return;
}
super.start();
started = true;
log.info("Xxl-job started");
}
@Override
public void destroy() {
if (!started) {
return;
}
super.destroy();
resetThreadsStatus();
started = false;
log.info("Xxl-job destroyed");
}
/**
* Reset xxl-job related thread to make it support restartable
*/
private void resetThreadsStatus() {
ReflectionUtils.setField(executorRegistryThreadStopField, ExecutorRegistryThread.getInstance(), false);
ReflectionUtils.setField(triggerCallbackThreadStopField, TriggerCallbackThread.getInstance(), false);
ReflectionUtils.setField(jobLogFileCleanThreadStopField, JobLogFileCleanThread.getInstance(), false);
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import com.schbrain.framework.autoconfigure.xxl.condition.XxlJobShouldAvailableCondition;
import com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
......@@ -22,10 +23,10 @@ import java.nio.file.Paths;
@EnableConfigurationProperties(XxlJobProperties.class)
public class XxlJobAutoConfiguration {
@Bean
@Bean(initMethod = "start", destroyMethod = "destroy")
@ConditionalOnMissingBean(XxlJobExecutor.class)
public SchbrainXxlJobExecutor schbrainXxlJobSpringExecutor(XxlJobProperties xxlJobProperties, LoggerProperties loggingProperties) {
SchbrainXxlJobExecutor executor = new SchbrainXxlJobExecutor();
public XxlJobSpringExecutor xxlJobSpringExecutor(XxlJobProperties xxlJobProperties, LoggerProperties loggingProperties) {
XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
executor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
executor.setIp(xxlJobProperties.getIp());
executor.setPort(xxlJobProperties.getPort());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment