编程知识扩展 - wtdig/study GitHub Wiki

1、@notnull groups注解的使用

关于@NotNull 注解中groups 的作用
public class User implements Serializable {

@NotNull(message = "primary is not null",groups = {GroupInterface1.class})
private Long id;
}

groups是验证分组,比如我有的验证只有更新的时候做,有的只有添加的时候做,就用这个
javax.validate里有提供一个默认分组Default.class是个接口,不指定分组时都会执行这个,分组是个空的接口
在字段上面指定他们的分组

@NotNull(message = "primary is not null",groups = {GroupInterface1.class})
private Long id;
然后在方法里指定对象用哪些分组验证

public void test(@Validated(GroupInterface1.class) User user) {

}
Java Bean Validation分组校验

 Java Bean Validation使用中,最常见的一个场景是,我们在增加和修改实体的时候,一般都是使用同一个实体类,但是增加和修改操作对实体的参数校验是不同的。Java Bean Validation提供分组校验的功能,可以实现针对不同的场景应用不同的校验规则
 

定义分组类
每个分组类只需要一个接口就可以了

AddGroup
public interface AddGroup {
}
UpdateGroup
public interface UpdateGroup {
}
校验规则上添加分组
@Data
public class Person {
    //添加分组信息:添加的时候不能有id,修改的时候却一定要有id
    @Null(message = "id should be empty", groups = {AddGroup.class})
    @NotNull(message = "id should not be empty", groups = {UpdateGroup.class})
    private Integer id;

    @Length(min = 2, max = 10, message = "name的长度为[2-10]之间")
    @NotBlank(message = "name should not be empty")
    private String name;
}
修改校验接口
由@Valid修改成@Validated 
添加分组{AddGroup.class, Default.class} 
@PostMapping("create")
public WebResult<String> create(@Validated({AddGroup.class, Default.class}) @RequestBody Person person) {
    log.info("person to create: {}", person);
    return new WebResult<>(person.getName());
}

@PutMapping("update")
public WebResult<Void> update(@Validated({UpdateGroup.class, Default.class}) @RequestBody Person person) {
    log.info("person to update: {}", person);
    return WebResult.SUCCESS;
}
注意事项
配置分组的时候,记得不要漏掉默认分组Default.class,否则就只会校验groups = {AddGroup.class}的规则了
参考使用Hibernate-Validator优雅的验证RESTful Web Services的参数

参考资料:https://cloud.tencent.com/developer/article/1426233

2、ApplicationEventPublisher的使用

SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,需要发放优惠券,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发放优惠券的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。
 

参考资料:https://blog.csdn.net/wanping321/article/details/86667216

代码使用案例:

  1、注入对象
 @Autowired
 private ApplicationEventPublisher publisher;

  2、获取反射类
 Class<?> clazz = getClassForName(contentType);

  3、发布事件
 publisher.publishEvent(JSON.parseObject(source, clazz));

 使用的是fastJson的序列号工具

 source为事件内容,clazz为反射的需要监听事件的类

  4、监听事件

 第一个监听事件
 @Component
public class SmsContentEventListener {

    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MessageRecordBiz messageRecordBiz;


    @EventListener
    public void handle(PayloadApplicationEvent<SmsContentMqBean> event) {
        try {
            SmsContentMqBean bean = event.getPayload();
            LOGGER.info("handle begin SmsContentEventListener object:{}", JsonUtil.toJsonString(bean));
            messageRecordBiz.sendSmsContent(bean);
        } catch (Exception e) {
            LOGGER.error("内容消费监听失败", e);
        }
    }
}

第二个监听事件

@Component
public class SmsMarketingEventListener {

    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MessageRecordBiz messageRecordBiz;


    @EventListener
    public void handle(PayloadApplicationEvent<SmsMarketingMqBean> event) {
        try {
            SmsMarketingMqBean bean = event.getPayload();
            LOGGER.info("handle begin SmsMarketingEventListener object:{}", JsonUtil.toJsonString(bean));
            messageRecordBiz.sendMarketingMessage(bean);
        } catch (Exception e) {
            LOGGER.error("营销消费监听失败", e);
        }
    }
}

当clazz传入的类为SmsContentMqBean,SmsContentEventListener获取到监听动作

当clazz传入的类为SmsMarketingMqBean,SmsMarketingEventListener 获取到监听动作

如果需要配置异步的处理,配置异步和线程池

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {

    private final Logger LOGGER = LoggerFactory.getLogger(AsyncConfiguration.class);
    public static final int corePoolSize = 2;
    public static final int maxPoolSize = 50;
    public static final int queueCapacity = 100000;

    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        LOGGER.info("Creating Async Task Executor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("aso-service-Executor-");
        return new ExceptionHandlingAsyncTaskExecutor(executor);
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

3、mybatis-plus-boot-starter使用

⚠️ **GitHub.com Fallback** ⚠️