key过期事件订阅配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class RedisCacheConfigure extends CachingConfigurerSupport {
/**
* key过期事件订阅需要
*
* @param redisConnectionFactory
* @return {@link RedisMessageListenerContainer}
*/
RedisMessageListenerContainer container(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
return container;
}
}监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
@Autowired
private OrderApplication orderApplication;
@Autowired
private OrderService orderService;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
String channel = new String(message.getChannel(), StandardCharsets.UTF_8);
// 过期的key
String key = new String(message.getBody(), StandardCharsets.UTF_8);
// 判断是否是订单的主键
if (key.startsWith(BizConstant.ORDER_CODE_REDIS_KEY_PREFIX)) {
OrderVo orderVo = orderService.detail(key);
if (!Objects.isNull(orderVo)) {
// 取消订单
CancelOrderDto cancelOrderDto = new CancelOrderDto();
cancelOrderDto.setOrderId(key);
cancelOrderDto.setCancelReason(BizConstant.SYSTEM_CANCEL);
cancelOrderDto.setAddShoppingCard(BizConstant.N);
cancelOrderDto.setUserId(orderVo.getUserId());
orderApplication.cancelOrder(cancelOrderDto);
}
}
log.info("redis key 过期:pattern={},channel={},key={}", new String(pattern), channel, key);
}
}mybaits plus 创建时间更新时间自动填充
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@Component
public class TimeFill implements MetaObjectHandler {
/**
* 插入时的填充策略
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
/**
* 更新时的填充策略
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}自定义参数检验
1
2
3
4
5
6
7
8
9
10
11
12@Target({TYPE, ANNOTATION_TYPE,PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {AttributeValidation.AttributeIdValidator.class})
@Documented
public @interface CheckAttributeIdExist {
String message() default "属性ID不存在!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}校验实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class AttributeValidation<T extends Annotation> implements ConstraintValidator<T, AttributeEntity> {
protected AttributeMapper attributeMapper;
Predicate<AttributeEntity> predicate = c -> true;
public boolean isValid(AttributeEntity value, ConstraintValidatorContext context) {
return value == null || predicate.test(value);
}
public static class AttributeIdValidator extends AttributeValidation<CheckAttributeIdExist> {
public void initialize(CheckAttributeIdExist constraintAnnotation) {
predicate = c -> attributeMapper.selectById(c.getId()) != null;
}
}
public static class AttributeNoDuplicationValidator extends AttributeValidation<CheckAttributeNoDuplication> {
public void initialize(CheckAttributeNoDuplication constraintAnnotation) {
predicate = c -> attributeMapper.selectOne(Wrappers.<AttributeEntity>lambdaQuery().eq(AttributeEntity::getName, c.getName())) == null;
}
}
}spring 事件监听
1
2@Async
@TransactionalEventListenerredis 锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18RedisLockRegistry
Lock lock = redisLockRegistry.obtain("APP:GOODS:ATTRIBUTE:" + dto.getName());
if (lock.tryLock()) {
try {
AttributeEntity entity = attributeTransfer.toModel(dto);
if (StringUtils.isEmpty(entity.getId())) {
attributeService.insert(entity);
} else {
attributeService.modify(entity);
}
return entity.getId();
} finally {
lock.unlock();
}
} else {
throw new BaseException(BaseCode.NO_LOCK_ACQUIRED);
}基于注解的拦截参数注入
1
2
3
4
5
6@Pointcut("@annotation(com.mmplanet.cloud.app.security.annotation.Authorization)")
public void pointCut() {
}
@Around("pointCut() && @annotation(authorization)")
public Object around(ProceedingJoinPoint point, Authorization authorization) throws Throwable {}