在引入Spring的Validated时,需要声明如下bean:
 
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
出于偷懒,放在了如下的一个初始化中:
@Configuration
public class ConfigService implements WebMvcConfigurer { ......... @Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
} ......... }
配置好后,@Validated生效了,但是aop,事务等出现异常。启动日志如下:
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'org.springframework.boot.context.properties.ConversionServiceDeducer$Factory' of type [org.springframework.boot.context.properties.ConversionServiceDeducer$Factory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties' of type [org.mybatis.spring.boot.autoconfigure.MybatisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' of type [org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$f57f05de] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:09 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'dataSource' of type [com.zaxxer.hikari.HikariDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:10 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-25 20:03:10 [INFO] [main] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker][328] Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
从日志提示的地方看到如下代码:
        @Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
"] is not eligible for getting processed by all BeanPostProcessors " +
"(for example: not eligible for auto-proxying)");
}
}
return bean;
}
因为问题的引入是已知的,所以,在这里打了断点测试了下进入的条件。发现在加上MethodValidationPostProcessor的bean时,this.beanFactory.getBeanPostProcessorCount()获取到的值为10,不加这个bean时,获取到的值为21.那有问题,肯定是构造完成后,处理流程差异导致的问题。从构造函数开始寻找BeanPostProcessorChecker的初始化地点。
从这里找到PostProcessorRegistrationDelegate的registerBeanPostProcessors方法,
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
从注释中可以看出,在初始化BeanPostProcessorChecker后,又继续初始化高优先级的,有顺序要求的,然后是剩下的BeanPostProcessor。
往下看:
        // First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors.
在初始化高优先的BeanPostProcessor后,开始load带有顺序条件的BeanPostProcessor,准备初始化。
回到最开始,我们的MethodValidationPostProcessor的父类实现了Ordered接口。故也在这个for循环的加载过程中load进来,此时,在加载的时候出现问题。
在如下代码块中
@Configuration
public class ConfigService implements WebMvcConfigurer {
@Resource
private LogService logService; @Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
我们注入了业务定义的bean,而这些bean是由最低优先级的BeanPostProcessor来加载并完成初始化的。但此时,为了加载其中的MethodValidationPostProcessor,导致不得不优先装载低优先级bean,此时,aop处理器,数据库处理器等都未完成装载,故由这部分业务bean牵扯到的相关逻辑的aop初始化,注解事务初始化,都事实上失败了。但spring就提示了一个INFO级别的提示,然后剩下的bean由最低优先级的BeanPostProcessor正常处理。
 
问题找到后,解决的方式很简单,由框架层初始化的bean,不要牵扯到业务层。不然即便初始化成功,也会导致一些模块因为顺序的缘故,未完成合适的处理流程,比如aop。
针对我这里的问题,如下解决:
@Configuration
public class MethodValidation { @Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
重新创建一个类,单独初始化此类即可。 

记一次Spring配置事故的更多相关文章

  1. 记一次 Spring 事务配置踩坑记

    记一次 Spring 事务配置踩坑记 问题描述:(SpringBoot + MyBatisPlus) 业务逻辑伪代码如下.理论上,插入数据 t1 后,xxService.getXxx() 方法的查询条 ...

  2. Spring配置c3p0数据源时出错报:java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

    今天在使用Spring配置c3p0数据源时,使用的数据库是mysql,服务器是tomcat,运行时报了一个 java.lang.NoClassDefFoundError: com/mchange/v2 ...

  3. spring配置详解

    1.前言 公司老项目的后台,均是基于spring框架搭建,其中还用到了log4j.jar等开源架包.在新项目中,则是spring和hibernate框架均有使用,利用了hibernate框架,来实现持 ...

  4. Spring配置汇总

    现在主流的JavaWeb应用几乎都会用到Spring,以下是Spring的配置,以及结合Web的SpringMVC配置的汇总. jar包的引入 与Web项目集成 Spring配置文件 SpringMV ...

  5. spring配置属性的两种方式

    spring配置属性有两种方式,第一种方式通过context命名空间中的property-placeholder标签 <context:property-placeholder location ...

  6. 解决eclipse spring配置报错:cvc-elt.1: Cannot find the declaration of element

    解决eclipse spring配置报错:cvc-elt.1: Cannot find the declaration of element 'beans'.Referenced file conta ...

  7. memcached 学习 1—— memcached+spring配置

    memcached 学习目录: memcached 学习 1—— memcached+spring配置 这几天自己搭建项目环境,解决问题如下: 有关常见的配置这里没有列出,中间遇到的搭建问题比较顺利g ...

  8. 解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException

    解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException这个问题出现的原因:一般在使用annotation的方式注入spring的bean 出现的,具体 ...

  9. spring配置中,properties文件以及xml文件配置问题

    spring方便我们的项目快速搭建,功能强大,自然也会是体系复杂! 这里说下配置文件properties管理的问题. 一些不涉及到代码逻辑,仅仅只是配置数据,可以放在xxxx.properties文件 ...

随机推荐

  1. WPF Color、String、Brush转换

    原文:WPF Color.String.Brush转换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/detai ...

  2. 1130: [POI2008]POD Subdivision of Kingdom

    1130: [POI2008]POD Subdivision of Kingdom https://lydsy.com/JudgeOnline/problem.php?id=1130 分析: 有效状态 ...

  3. 【MYSQL命令】查看日志是否开启及日志过期天数

    show variables like 'log_%';show variables like '%expire_logs_days%'

  4. JDBC处理大数据

    1.处理大文本 package com.demo; import java.io.File; import java.io.FileNotFoundException; import java.io. ...

  5. 心中忐忑的跨进了Python的大门!

    Hello!大家好,我是Jmmy 作为一个python初学者,抱着一种忐忑的心里走进了这扇让我有些胆怯的大门,因为零基础的缘故让我不得不再三去考虑学这门语言,英语.数学都是个渣的我,也许注定会止步门外 ...

  6. ZT-----用javascrip写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  7. PHP核心技术——魔术方法

    魔术方法: 魔术方法是以两个下画线开头.具有特殊作用的一些方法,可以看做PHP的"语法糖". set和get方法: class Account{ private $user=1; ...

  8. 算法与AI的暗黑面:3星|《算法的陷阱:超级平台、算法垄断与场景欺骗》

    算法的陷阱:超级平台.算法垄断与场景欺骗 全书讲算法与AI的暗黑面:价格歧视.导致算法军备竞赛.导致商家降价冲动降低.平台作恶(向劣质商家收费导致品质下降.与开发商一起分析用户隐私)等. 作者从商业. ...

  9. linux上open-vswitch安装和卸载

    一. ovs 从源码编译安装: 安装依赖项: # apt-get install make # apt-get install gcc # apt-get install build-essentia ...

  10. asp.net mvc同一个view展示多个不同列表思路

    asp.net mvc一个模型一个view容易展示,可是遇到像首页那样,要同时调用好几个不同表的内容一小部分展示时,该怎么是好呢? 下边根据我的测试,用的是mvc access数据测试 先建立一个强类 ...