编程知识扩展 - wtdig/study GitHub Wiki
关于@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
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();
}
}