• key过期事件订阅配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Configuration
    public class RedisCacheConfigure extends CachingConfigurerSupport {
    /**
    * key过期事件订阅需要
    *
    * @param redisConnectionFactory
    * @return {@link RedisMessageListenerContainer}
    */
    @Bean
    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
    23
    public class AttributeValidation<T extends Annotation> implements ConstraintValidator<T, AttributeEntity> {
    @Autowired
    protected AttributeMapper attributeMapper;

    Predicate<AttributeEntity> predicate = c -> true;

    @Override
    public boolean isValid(AttributeEntity value, ConstraintValidatorContext context) {
    return value == null || predicate.test(value);
    }
    public static class AttributeIdValidator extends AttributeValidation<CheckAttributeIdExist> {
    @Override
    public void initialize(CheckAttributeIdExist constraintAnnotation) {
    predicate = c -> attributeMapper.selectById(c.getId()) != null;
    }
    }
    public static class AttributeNoDuplicationValidator extends AttributeValidation<CheckAttributeNoDuplication> {
    @Override
    public void initialize(CheckAttributeNoDuplication constraintAnnotation) {
    predicate = c -> attributeMapper.selectOne(Wrappers.<AttributeEntity>lambdaQuery().eq(AttributeEntity::getName, c.getName())) == null;
    }
    }
    }
  • spring 事件监听

    1
    2
    @Async
    @TransactionalEventListener
  • redis 锁

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    RedisLockRegistry

    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 {}