场景: 在spring cloud 微服务当中 我在测试某个服务接口的时候发现 validation的校验规则是每一条都选择校验完成后才抛出异常,照例老规矩百度一下基本都是以下配置解决问题:
@Bean
public Validator validator() {
try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
// 快速失败模式
.failFast(true)
.buildValidatorFactory()) {
return validatorFactory.getValidator();
}
}
事实却是在添加完配置类以后,问题得到了解决!
可是想着我可能会多个服务都需要以上配置(想的真多...),寻思将其通过spring boot spi的方式放到公共依赖中,问题就来了:
测试接口竟然没有生效,然后我在换回服务内配置,又生效了,反复几次,我开始以为配置类并没有加载进去,当我将两个配置类都配置上提示错误信息:
我确定已经加载进去了(spring boot 错误提示有时候还挺不错!!!).
于是只能跟踪源码来看,跟踪了很久并没有发现有哪些地方不一样(此时心很凉);
于是我想到了spring boot 自动装配都是xxxAutoCoxxx,于是ValidationAutoConfiguration
被我第一时间找到
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnMissingBean(Validator.class)
public static LocalValidatorFactoryBean defaultValidator(ApplicationContext applicationContext) {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory(applicationContext);
factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
return factoryBean;
}
很明显@ConditionalOnMissingBean(Validator.class)很显眼,于是我就猜测是不是配置文件的加载顺序在自动装配之后导致失效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>compile</scope>
</dependency>
在公共模块配置和服务模块配置之间来回切换,偶然发下,服务内的配置并不会走自动装配,于是我就将自动装配类排除:
接口进行测试,发现配置生效,至此问题得到解决!
在解决spring boot时区问题时,我发现出现同样的问题,就是怎么我自定义的自动装备类,总是在spring boot 自动装配的后实例化,我想总不能一直排除对应的自动装配类吧(有的你还不能排除),当然spring boot 也提供对应的注解 ,我只列出了我使用到的注解
@AutoConfigureBefore @AutoConfigureOrder
*配置完成记得重新编译一下