升级SpringBoot 2.3.0
This commit is contained in:
@@ -19,6 +19,26 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
@@ -27,18 +47,6 @@
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.macro.mall.common.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import com.macro.mall.common.service.RedisService;
|
||||
import com.macro.mall.common.service.impl.RedisServiceImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* Redis基础配置
|
||||
* Created by macro on 2020/6/19.
|
||||
*/
|
||||
public class BaseRedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisSerializer<Object> serializer = redisSerializer();
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(serializer);
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(serializer);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisSerializer<Object> redisSerializer() {
|
||||
//创建JSON序列化器
|
||||
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
//必须设置,否则无法将JSON转化为对象,会转化成Map类型
|
||||
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
serializer.setObjectMapper(objectMapper);
|
||||
return serializer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
|
||||
//设置Redis缓存有效期为1天
|
||||
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1));
|
||||
return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public RedisService redisService(){
|
||||
return new RedisServiceImpl();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.macro.mall.common.config;
|
||||
|
||||
import com.macro.mall.common.domain.SwaggerProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Swagger基础配置
|
||||
* Created by macro on 2020/7/16.
|
||||
*/
|
||||
public abstract class BaseSwaggerConfig {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
SwaggerProperties swaggerProperties = swaggerProperties();
|
||||
Docket docket = new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo(swaggerProperties))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getApiBasePackage()))
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
if (swaggerProperties.isEnableSecurity()) {
|
||||
docket.securitySchemes(securitySchemes()).securityContexts(securityContexts());
|
||||
}
|
||||
return docket;
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
|
||||
return new ApiInfoBuilder()
|
||||
.title(swaggerProperties.getTitle())
|
||||
.description(swaggerProperties.getDescription())
|
||||
.contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail()))
|
||||
.version(swaggerProperties.getVersion())
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<ApiKey> securitySchemes() {
|
||||
//设置请求头信息
|
||||
List<ApiKey> result = new ArrayList<>();
|
||||
ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
|
||||
result.add(apiKey);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SecurityContext> securityContexts() {
|
||||
//设置需要登录认证的路径
|
||||
List<SecurityContext> result = new ArrayList<>();
|
||||
result.add(getContextByPath("/*/.*"));
|
||||
return result;
|
||||
}
|
||||
|
||||
private SecurityContext getContextByPath(String pathRegex) {
|
||||
return SecurityContext.builder()
|
||||
.securityReferences(defaultAuth())
|
||||
.forPaths(PathSelectors.regex(pathRegex))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<SecurityReference> defaultAuth() {
|
||||
List<SecurityReference> result = new ArrayList<>();
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
result.add(new SecurityReference("Authorization", authorizationScopes));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义Swagger配置
|
||||
*/
|
||||
public abstract SwaggerProperties swaggerProperties();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.macro.mall.common.domain;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* Swagger自定义配置
|
||||
* Created by macro on 2020/7/16.
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Builder
|
||||
public class SwaggerProperties {
|
||||
/**
|
||||
* API文档生成基础路径
|
||||
*/
|
||||
private String apiBasePackage;
|
||||
/**
|
||||
* 是否要启用登录认证
|
||||
*/
|
||||
private boolean enableSecurity;
|
||||
/**
|
||||
* 文档标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 文档描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 文档版本
|
||||
*/
|
||||
private String version;
|
||||
/**
|
||||
* 文档联系人姓名
|
||||
*/
|
||||
private String contactName;
|
||||
/**
|
||||
* 文档联系人网址
|
||||
*/
|
||||
private String contactUrl;
|
||||
/**
|
||||
* 文档联系人邮箱
|
||||
*/
|
||||
private String contactEmail;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.macro.mall.common.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* Controller层的日志封装类
|
||||
* Created by macro on 2018/4/26.
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class WebLog {
|
||||
/**
|
||||
* 操作描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 操作用户
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
private Long startTime;
|
||||
|
||||
/**
|
||||
* 消耗时间
|
||||
*/
|
||||
private Integer spendTime;
|
||||
|
||||
/**
|
||||
* 根路径
|
||||
*/
|
||||
private String basePath;
|
||||
|
||||
/**
|
||||
* URI
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 请求类型
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
private Object parameter;
|
||||
|
||||
/**
|
||||
* 返回结果
|
||||
*/
|
||||
private Object result;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package com.macro.mall.common.log;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.macro.mall.common.domain.WebLog;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import net.logstash.logback.marker.Markers;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 统一日志处理切面
|
||||
* Created by macro on 2018/4/26.
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(1)
|
||||
public class WebLogAspect {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class);
|
||||
|
||||
@Pointcut("execution(public * com.macro.mall.controller.*.*(..))||execution(public * com.macro.mall.*.controller.*.*(..))")
|
||||
public void webLog() {
|
||||
}
|
||||
|
||||
@Before("webLog()")
|
||||
public void doBefore(JoinPoint joinPoint) throws Throwable {
|
||||
}
|
||||
|
||||
@AfterReturning(value = "webLog()", returning = "ret")
|
||||
public void doAfterReturning(Object ret) throws Throwable {
|
||||
}
|
||||
|
||||
@Around("webLog()")
|
||||
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
//获取当前请求对象
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
//记录请求信息(通过Logstash传入Elasticsearch)
|
||||
WebLog webLog = new WebLog();
|
||||
Object result = joinPoint.proceed();
|
||||
Signature signature = joinPoint.getSignature();
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
if (method.isAnnotationPresent(ApiOperation.class)) {
|
||||
ApiOperation log = method.getAnnotation(ApiOperation.class);
|
||||
webLog.setDescription(log.value());
|
||||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
String urlStr = request.getRequestURL().toString();
|
||||
webLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
|
||||
webLog.setIp(request.getRemoteUser());
|
||||
webLog.setMethod(request.getMethod());
|
||||
webLog.setParameter(getParameter(method, joinPoint.getArgs()));
|
||||
webLog.setResult(result);
|
||||
webLog.setSpendTime((int) (endTime - startTime));
|
||||
webLog.setStartTime(startTime);
|
||||
webLog.setUri(request.getRequestURI());
|
||||
webLog.setUrl(request.getRequestURL().toString());
|
||||
Map<String,Object> logMap = new HashMap<>();
|
||||
logMap.put("url",webLog.getUrl());
|
||||
logMap.put("method",webLog.getMethod());
|
||||
logMap.put("parameter",webLog.getParameter());
|
||||
logMap.put("spendTime",webLog.getSpendTime());
|
||||
logMap.put("description",webLog.getDescription());
|
||||
// LOGGER.info("{}", JSONUtil.parse(webLog));
|
||||
LOGGER.info(Markers.appendEntries(logMap), JSONUtil.parse(webLog).toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据方法和传入的参数获取请求参数
|
||||
*/
|
||||
private Object getParameter(Method method, Object[] args) {
|
||||
List<Object> argList = new ArrayList<>();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
//将RequestBody注解修饰的参数作为请求参数
|
||||
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
|
||||
if (requestBody != null) {
|
||||
argList.add(args[i]);
|
||||
}
|
||||
//将RequestParam注解修饰的参数作为请求参数
|
||||
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
|
||||
if (requestParam != null) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
String key = parameters[i].getName();
|
||||
if (!StringUtils.isEmpty(requestParam.value())) {
|
||||
key = requestParam.value();
|
||||
}
|
||||
map.put(key, args[i]);
|
||||
argList.add(map);
|
||||
}
|
||||
}
|
||||
if (argList.size() == 0) {
|
||||
return null;
|
||||
} else if (argList.size() == 1) {
|
||||
return argList.get(0);
|
||||
} else {
|
||||
return argList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.macro.mall.common.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* redis操作Service
|
||||
* Created by macro on 2020/3/3.
|
||||
*/
|
||||
public interface RedisService {
|
||||
|
||||
/**
|
||||
* 保存属性
|
||||
*/
|
||||
void set(String key, Object value, long time);
|
||||
|
||||
/**
|
||||
* 保存属性
|
||||
*/
|
||||
void set(String key, Object value);
|
||||
|
||||
/**
|
||||
* 获取属性
|
||||
*/
|
||||
Object get(String key);
|
||||
|
||||
/**
|
||||
* 删除属性
|
||||
*/
|
||||
Boolean del(String key);
|
||||
|
||||
/**
|
||||
* 批量删除属性
|
||||
*/
|
||||
Long del(List<String> keys);
|
||||
|
||||
/**
|
||||
* 设置过期时间
|
||||
*/
|
||||
Boolean expire(String key, long time);
|
||||
|
||||
/**
|
||||
* 获取过期时间
|
||||
*/
|
||||
Long getExpire(String key);
|
||||
|
||||
/**
|
||||
* 判断是否有该属性
|
||||
*/
|
||||
Boolean hasKey(String key);
|
||||
|
||||
/**
|
||||
* 按delta递增
|
||||
*/
|
||||
Long incr(String key, long delta);
|
||||
|
||||
/**
|
||||
* 按delta递减
|
||||
*/
|
||||
Long decr(String key, long delta);
|
||||
|
||||
/**
|
||||
* 获取Hash结构中的属性
|
||||
*/
|
||||
Object hGet(String key, String hashKey);
|
||||
|
||||
/**
|
||||
* 向Hash结构中放入一个属性
|
||||
*/
|
||||
Boolean hSet(String key, String hashKey, Object value, long time);
|
||||
|
||||
/**
|
||||
* 向Hash结构中放入一个属性
|
||||
*/
|
||||
void hSet(String key, String hashKey, Object value);
|
||||
|
||||
/**
|
||||
* 直接获取整个Hash结构
|
||||
*/
|
||||
Map<Object, Object> hGetAll(String key);
|
||||
|
||||
/**
|
||||
* 直接设置整个Hash结构
|
||||
*/
|
||||
Boolean hSetAll(String key, Map<String, Object> map, long time);
|
||||
|
||||
/**
|
||||
* 直接设置整个Hash结构
|
||||
*/
|
||||
void hSetAll(String key, Map<String, ?> map);
|
||||
|
||||
/**
|
||||
* 删除Hash结构中的属性
|
||||
*/
|
||||
void hDel(String key, Object... hashKey);
|
||||
|
||||
/**
|
||||
* 判断Hash结构中是否有该属性
|
||||
*/
|
||||
Boolean hHasKey(String key, String hashKey);
|
||||
|
||||
/**
|
||||
* Hash结构中属性递增
|
||||
*/
|
||||
Long hIncr(String key, String hashKey, Long delta);
|
||||
|
||||
/**
|
||||
* Hash结构中属性递减
|
||||
*/
|
||||
Long hDecr(String key, String hashKey, Long delta);
|
||||
|
||||
/**
|
||||
* 获取Set结构
|
||||
*/
|
||||
Set<Object> sMembers(String key);
|
||||
|
||||
/**
|
||||
* 向Set结构中添加属性
|
||||
*/
|
||||
Long sAdd(String key, Object... values);
|
||||
|
||||
/**
|
||||
* 向Set结构中添加属性
|
||||
*/
|
||||
Long sAdd(String key, long time, Object... values);
|
||||
|
||||
/**
|
||||
* 是否为Set中的属性
|
||||
*/
|
||||
Boolean sIsMember(String key, Object value);
|
||||
|
||||
/**
|
||||
* 获取Set结构的长度
|
||||
*/
|
||||
Long sSize(String key);
|
||||
|
||||
/**
|
||||
* 删除Set结构中的属性
|
||||
*/
|
||||
Long sRemove(String key, Object... values);
|
||||
|
||||
/**
|
||||
* 获取List结构中的属性
|
||||
*/
|
||||
List<Object> lRange(String key, long start, long end);
|
||||
|
||||
/**
|
||||
* 获取List结构的长度
|
||||
*/
|
||||
Long lSize(String key);
|
||||
|
||||
/**
|
||||
* 根据索引获取List中的属性
|
||||
*/
|
||||
Object lIndex(String key, long index);
|
||||
|
||||
/**
|
||||
* 向List结构中添加属性
|
||||
*/
|
||||
Long lPush(String key, Object value);
|
||||
|
||||
/**
|
||||
* 向List结构中添加属性
|
||||
*/
|
||||
Long lPush(String key, Object value, long time);
|
||||
|
||||
/**
|
||||
* 向List结构中批量添加属性
|
||||
*/
|
||||
Long lPushAll(String key, Object... values);
|
||||
|
||||
/**
|
||||
* 向List结构中批量添加属性
|
||||
*/
|
||||
Long lPushAll(String key, Long time, Object... values);
|
||||
|
||||
/**
|
||||
* 从List结构中移除属性
|
||||
*/
|
||||
Long lRemove(String key, long count, Object value);
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.macro.mall.common.service.impl;
|
||||
|
||||
import com.macro.mall.common.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* redis操作实现类
|
||||
* Created by macro on 2020/3/3.
|
||||
*/
|
||||
public class RedisServiceImpl implements RedisService {
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Override
|
||||
public void set(String key, Object value, long time) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String key, Object value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean del(String key) {
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long del(List<String> keys) {
|
||||
return redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expire(String key, long time) {
|
||||
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasKey(String key) {
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long incr(String key, long delta) {
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decr(String key, long delta) {
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object hGet(String key, String hashKey) {
|
||||
return redisTemplate.opsForHash().get(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hSet(String key, String hashKey, Object value, long time) {
|
||||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
return expire(key, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hSet(String key, String hashKey, Object value) {
|
||||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> hGetAll(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hSetAll(String key, Map<String, Object> map, long time) {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return expire(key, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hSetAll(String key, Map<String, ?> map) {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hDel(String key, Object... hashKey) {
|
||||
redisTemplate.opsForHash().delete(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hHasKey(String key, String hashKey) {
|
||||
return redisTemplate.opsForHash().hasKey(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hIncr(String key, String hashKey, Long delta) {
|
||||
return redisTemplate.opsForHash().increment(key, hashKey, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hDecr(String key, String hashKey, Long delta) {
|
||||
return redisTemplate.opsForHash().increment(key, hashKey, -delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> sMembers(String key) {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sAdd(String key, Object... values) {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sAdd(String key, long time, Object... values) {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
expire(key, time);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean sIsMember(String key, Object value) {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sSize(String key) {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sRemove(String key, Object... values) {
|
||||
return redisTemplate.opsForSet().remove(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> lRange(String key, long start, long end) {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lSize(String key) {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lIndex(String key, long index) {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPush(String key, Object value) {
|
||||
return redisTemplate.opsForList().rightPush(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPush(String key, Object value, long time) {
|
||||
Long index = redisTemplate.opsForList().rightPush(key, value);
|
||||
expire(key, time);
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPushAll(String key, Object... values) {
|
||||
return redisTemplate.opsForList().rightPushAll(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPushAll(String key, Long time, Object... values) {
|
||||
Long count = redisTemplate.opsForList().rightPushAll(key, values);
|
||||
expire(key, time);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lRemove(String key, long count, Object value) {
|
||||
return redisTemplate.opsForList().remove(key, count, value);
|
||||
}
|
||||
}
|
||||
196
mall-common/src/main/resources/logback-spring.xml
Normal file
196
mall-common/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration>
|
||||
<configuration>
|
||||
<!--引用默认日志配置-->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<!--使用默认的控制台日志输出实现-->
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
|
||||
<!--应用名称-->
|
||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
|
||||
<!--日志文件保存路径-->
|
||||
<property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
|
||||
<!--LogStash访问host-->
|
||||
<springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>
|
||||
|
||||
<!--DEBUG日志输出到文件-->
|
||||
<appender name="FILE_DEBUG"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--输出DEBUG以上级别日志-->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<!--设置为默认的文件日志格式-->
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!--设置文件命名格式-->
|
||||
<fileNamePattern>${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
|
||||
<!--设置日志文件大小,超过就重新生成文件,默认10M-->
|
||||
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
|
||||
<!--日志文件保留天数,默认30天-->
|
||||
<maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!--ERROR日志输出到文件-->
|
||||
<appender name="FILE_ERROR"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--只输出ERROR级别的日志-->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<encoder>
|
||||
<!--设置为默认的文件日志格式-->
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!--设置文件命名格式-->
|
||||
<fileNamePattern>${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
|
||||
<!--设置日志文件大小,超过就重新生成文件,默认10M-->
|
||||
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
|
||||
<!--日志文件保留天数,默认30天-->
|
||||
<maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!--DEBUG日志输出到LogStash-->
|
||||
<appender name="LOG_STASH_DEBUG" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<destination>${LOG_STASH_HOST}:4560</destination>
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
</timestamp>
|
||||
<!--自定义日志输出格式-->
|
||||
<pattern>
|
||||
<pattern>
|
||||
{
|
||||
"project": "mall",
|
||||
"level": "%level",
|
||||
"service": "${APP_NAME:-}",
|
||||
"pid": "${PID:-}",
|
||||
"thread": "%thread",
|
||||
"class": "%logger",
|
||||
"message": "%message",
|
||||
"stack_trace": "%exception{20}"
|
||||
}
|
||||
</pattern>
|
||||
</pattern>
|
||||
</providers>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--ERROR日志输出到LogStash-->
|
||||
<appender name="LOG_STASH_ERROR" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<destination>${LOG_STASH_HOST}:4561</destination>
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
</timestamp>
|
||||
<!--自定义日志输出格式-->
|
||||
<pattern>
|
||||
<pattern>
|
||||
{
|
||||
"project": "mall",
|
||||
"level": "%level",
|
||||
"service": "${APP_NAME:-}",
|
||||
"pid": "${PID:-}",
|
||||
"thread": "%thread",
|
||||
"class": "%logger",
|
||||
"message": "%message",
|
||||
"stack_trace": "%exception{20}"
|
||||
}
|
||||
</pattern>
|
||||
</pattern>
|
||||
</providers>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--业务日志输出到LogStash-->
|
||||
<appender name="LOG_STASH_BUSINESS" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<destination>${LOG_STASH_HOST}:4562</destination>
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
</timestamp>
|
||||
<!--自定义日志输出格式-->
|
||||
<pattern>
|
||||
<pattern>
|
||||
{
|
||||
"project": "mall",
|
||||
"level": "%level",
|
||||
"service": "${APP_NAME:-}",
|
||||
"pid": "${PID:-}",
|
||||
"thread": "%thread",
|
||||
"class": "%logger",
|
||||
"message": "%message",
|
||||
"stack_trace": "%exception{20}"
|
||||
}
|
||||
</pattern>
|
||||
</pattern>
|
||||
</providers>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--接口访问记录日志输出到LogStash-->
|
||||
<appender name="LOG_STASH_RECORD" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<destination>${LOG_STASH_HOST}:4563</destination>
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
</timestamp>
|
||||
<!--自定义日志输出格式-->
|
||||
<pattern>
|
||||
<pattern>
|
||||
{
|
||||
"project": "mall",
|
||||
"level": "%level",
|
||||
"service": "${APP_NAME:-}",
|
||||
"class": "%logger",
|
||||
"message": "%message"
|
||||
}
|
||||
</pattern>
|
||||
</pattern>
|
||||
</providers>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--控制框架输出日志-->
|
||||
<logger name="org.slf4j" level="INFO"/>
|
||||
<logger name="springfox" level="INFO"/>
|
||||
<logger name="io.swagger" level="INFO"/>
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<logger name="org.hibernate.validator" level="INFO"/>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_DEBUG"/>
|
||||
<appender-ref ref="FILE_ERROR"/>
|
||||
<appender-ref ref="LOG_STASH_DEBUG"/>
|
||||
<appender-ref ref="LOG_STASH_ERROR"/>
|
||||
</root>
|
||||
|
||||
<logger name="com.macro.mall.common.log.WebLogAspect" level="DEBUG">
|
||||
<appender-ref ref="LOG_STASH_RECORD"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.macro.mall" level="DEBUG">
|
||||
<appender-ref ref="LOG_STASH_BUSINESS"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user