在引入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. NoSQL入门第一天——NoSQL入门与基本概述

    一.课程大纲 二.入门概述 1.为什么用NoSQL 单机MySQL的年代: 一个网站的访问量一般都不大,用单个数据库完全可以轻松应付. 我们来看看数据存储的瓶颈是什么? 1.数据量的总大小 一个机器放 ...

  2. 20155215 2016-2017-2 《Java程序设计》第4周学习总结

    20155215 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 第六章 继承,避免多个类间重复定义共同行为.子类继承父类,再扩充(extends)其他行为. ...

  3. 20155232 2016-2017-2 《Java程序设计》第1周学习总结

    20155232 2016-2017-2 <Java程序设计>第1周学习总结 认真学习考核方式,理解成绩构成 100分构成: 翻转课堂考核12次(60分) 实验5次(15分) 团队项目(2 ...

  4. 201555301 2016-2017-2《Java程序设计》课程总结

    20155301 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:我对师生关系的思考 预备作业2:从现有技能获取的经验应用于JAVA中 预备作业 ...

  5. 【原创】user.id字段

    odoo中User.ID 字段是用户登录表 res_users 中的字段,所以要关联某个用户或是判断某个用户,可以利用该字段. 例如:在某个 界面中的domain中,要求显示的是关联某用户的单子,则如 ...

  6. 使GDAL库支持中文路径或中文文件名的处理方法

    之前生成的gdal 2.1.1动态库,在通过命令行执行时,遇到有中文路径或中文图像名时,GDALOpen函数不能正确的被调用,如下图: 解决方法: 1.      在所有使用GDALAllRegist ...

  7. Jlink v8仿真器在64位系统上刷固件

    1. 安装软件sam-ba_2.16.exe.本次主要是Jlink v8在64位系统下面的刷固件方法. 2. J-link通过USB连接至电脑,短接PCB上标号为ERASE的焊盘5秒,断开ERASE两 ...

  8. 【转】bash: ssh: command not found解决方法(linux)

    原文转自:http://www.cnblogs.com/ahauzyy/archive/2013/04/25/3043699.html 今天在搭建hadoop的开发环境中,用的是centsos6.0的 ...

  9. Maven学习(四)-----Maven中央存储库

    Maven中央存储库 当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库获得 Maven 的本地资源库依赖资源,如果没 ...

  10. python全栈开发-前方高能-内置函数2

    python_day_15 一.今日主要内容 1. lambda 匿名函数 语法: lambda 参数:返回值 不能完成复杂的操作 2. sorted() 函数 排序. 1. 可迭代对象 2. key ...