使用监听器对Spring bean id进行唯一校验过程解析

背景

项目中用到了多数据源,不同的数据源根据业务不同配置在不同的工程中,由maven来统一聚合。但是前几天在开发过程中突然发现项目前台工程的事务配置不起作用了,在之前明明测试过事务功能,当时是生效的。

然后检查了一下配置文件中事务部分的配置,发现没什么改动。为了排除其它因素的干扰,采用了单元测试重新测试了一次,结果发现当前数据源事务正常。根据这个分析可能是当前的事务配置被其它配置干扰了,仔细检查了一下后发现罪魁祸首是另外的一个数据源事务配置(在另外的一个配置文件中)的bean id名称和当前的事务配置bean id重复了。

我们都知道,Spring会对同一份配置文件中的bean进行校验,也就是说在同一份配置文件中不允许出现相同的bean定义,会提示报错。但是Spring IOC容器在加载时并不会显示对不同配置文件中重复的bean id进行报错提示,当遇到有重复的bean定义时,Spring采取的策略是把后面加载的配置覆盖前面加载的配置,没有任何警告和提示。

这样很容易造成一个问题是当我们团队进行开发时可能会不小心覆盖别人定义的bean,导致系统出现不可预知的错误和异常。

怎么解决这个问题呢?我们可以配置监听器,在Spring容器启动时对重复的bean进行校验,如果有重复的bean,则报错提示。

因为Spring IOC容器启动加载时会检查bean定义是否有重复,如果有重复则会根据AbstractRefreshableApplicationContext类中的allowBeanDefinitionOverriding属性值进行判断,如果值为true,则把后加载的bean覆盖前面加载的bean定义,如果为false则抛出BeanDefinitionStoreException异常。

所以,解决这个问题的办法就比较简单了,只要将这个allowBeanDefinitionOverriding值在spring初始化的时候设置为false就行了。具体步骤如下:

1.自定义一个ContextLoader

/**
 * ClassName:MyContextLoader <br/>
 * Function: 自定义ContextLoader. <br/>
 * Date:  2013-1-18 下午03:53:16 <br/>
 * @author chenzhou
 * @version
 * @since JDK 1.6
 */
public class MyContextLoader extends ContextLoader {
 /**
  * 设置allowBeanDefinitionOverriding属性为false,spring ioc容器在加载bean的过程中会去判断beanName 是否有重复,. <br/>
  * 如果发现重复的话再根据allowBeanDefinitionOverriding 这个成员变量,. <br/>
  * 如果是false的话则抛出BeanDefinitionStoreException 这个异常,如果为true的话就会覆盖这个bean的定义. <br/>
  * @see org.springframework.web.context.ContextLoader#customizeContext(javax.servlet.ServletContext,
  *  org.springframework.web.context.ConfigurableWebApplicationContext)
  */
 @Override
 protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext){
  super.customizeContext(servletContext, applicationContext);
  XmlWebApplicationContext context = (XmlWebApplicationContext) applicationContext;
  //设置allowBeanDefinitionOverriding属性为false
  context.setAllowBeanDefinitionOverriding(false);
 }
} 

2.自定义一个ContextLoaderListener

/**
 * ClassName:MyContextLoaderListener <br/>
 * Function: 自定义ContextLoaderListener. <br/>
 * Date:  2013-1-18 下午04:12:00 <br/>
 * @author chenzhou
 * @version
 * @since JDK 1.6
 */
public class MyContextLoaderListener extends ContextLoaderListener {
 @Override
 protected ContextLoader createContextLoader(){
  return new MyContextLoader();
 }
} 

3.修改web.xml文件的监听器配置

<!-- 自定义的ContextLoaderListener -->
<listener>
 <listener-class>com.chenzhou.examples.erm.util.listener.MyContextLoaderListener</listener-class>
</listener> 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • IDEA基于支付宝小程序搭建springboot项目的详细步骤

    服务端 在平台上创建springboot小程序应用 创建小程序 登录蚂蚁金服开放平台,扫码登录填写信息后,点击支付宝小程序,选择立即接入 > 同意个人公测 > 开始创建 . 填写好小程序基本信息后,点击创建按钮,创建名为xxx小程序. PS:一个账号下最多可以创建10个小程序:未提交过审核的小程序可以删除,删除的小程序不在计数范围. 创建云应用后端服务 在小程序页面选择刚创建的小程序,点击查看,进入开发者页面. 在左侧导航栏选择云服务(免费),点击创建云服务,选择创建云应用,技术栈选Sprin

  • 解决idea不支持SpringBoot yml文件的图文教程

    再初用SpringBoot时肯定会遇到这样的问题: 为什么idea不支持yml? 为什么idea的yml文件没有提示? 为什么idea的yml不识别? 第一个问题解答  1.安装YAML插件 2.再Settings中找到File Types然后找YAML看看是否有yml后缀名 第二个问题为什么没有提示? 1.安装插件SnakeYAML plugin即可 第三个问题:大坑! 以上问题还是不能解决,那么 1.看看你项目的结构你的resource是一个文件夹还是一个resource的包 2.是否是id

  • Spring Boot的listener(监听器)简单使用实例详解

    监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean(){ ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean

  • SpringBoot 在IDEA中实现热部署步骤详解(实用版)

    好的热部署让开发调试事半功倍,这样的"神技能"怎么能错过呢, 使用过IDEA的童鞋赶紧进来撸一把吧. 学习目标 快速学会在项目中使用热部署插件运行项目,提高开发效率. 具体步骤 一.开启IDEA的自动编译(静态) 具体步骤:打开顶部工具栏  File -> Settings -> Default Settings -> Build -> Compiler  然后勾选 Build project automatically . 二.开启IDEA的自动编译(动态)

  • Spring boot通过HttpSessionListener监听器统计在线人数的实现代码

    首先说下,这个统计在线人数有个缺陷,一个人在线可以同时拥有多个session,导致统计有一定的不准确行. 接下来,开始代码的编写, 第一步:实现HttpSessionListener中的方法,加上注解@WebListener @WebListener public class SessionListener implements HttpSessionListener{ public void sessionCreated(HttpSessionEvent arg0) { // TODO Aut

  • 详解Spring Boot整合Mybatis实现 Druid多数据源配置

    一.多数据源的应用场景 目前,业界流行的数据操作框架是 Mybatis,那 Druid 是什么呢? Druid 是 Java 的数据库连接池组件.Druid 能够提供强大的监控和扩展功能.比如可以监控 SQL ,在监控业务可以查询慢查询 SQL 列表等.Druid 核心主要包括三部分: 1. DruidDriver 代理 Driver,能够提供基于 Filter-Chain 模式的插件体系. 2. DruidDataSource 高效可管理的数据库连接池 3. SQLParser 当业务数据量达

  • 详解Spring Boot工程集成全局唯一ID生成器 UidGenerator的操作步骤

    Spring Boot中全局唯一流水号ID生成器集成实验 概述 流水号生成器(全局唯一 ID生成器)是服务化系统的基础设施,其在保障系统的正确运行和高可用方面发挥着重要作用.而关于流水号生成算法首屈一指的当属 Snowflake 雪花算法,然而 Snowflake本身很难在现实项目中直接使用,因此实际应用时需要一种可落地的方案. UidGenerator 由百度开发,是Java实现的, 基于 Snowflake算法的唯一ID生成器.UidGenerator以组件形式工作在应用项目中, 支持自定义

  • 使用监听器对Spring bean id进行唯一校验过程解析

    背景 项目中用到了多数据源,不同的数据源根据业务不同配置在不同的工程中,由maven来统一聚合.但是前几天在开发过程中突然发现项目前台工程的事务配置不起作用了,在之前明明测试过事务功能,当时是生效的. 然后检查了一下配置文件中事务部分的配置,发现没什么改动.为了排除其它因素的干扰,采用了单元测试重新测试了一次,结果发现当前数据源事务正常.根据这个分析可能是当前的事务配置被其它配置干扰了,仔细检查了一下后发现罪魁祸首是另外的一个数据源事务配置(在另外的一个配置文件中)的bean id名称和当前的事

  • Spring bean 加载执行顺序实例解析

    本文研究的主要是Spring bean 加载执行顺序的相关内容,具体如下. 问题来源: 有一个bean为A,一个bean为B.想要A在容器实例化的时候的一个属性name赋值为B的一个方法funB的返回值. 如果只是在A里单纯的写着: private B b; private String name = b.funb(); 会报错说nullpointException,因为这个时候b还没被set进来,所以为null. 解决办法为如下代码,同时学习下spring中 InitializingBean

  • Spring Boot 实现字段唯一校验功能(实例代码)

    目录 1 Maven依赖 2 实现代码 2.1 UniqueCheck 2.2 UniqueCheckDetail 2.3 UniqueCheckArgs 2.4 UniqueCheckService 2.5 AbstractUniqueCheckService 3 调试代码 3.1 UserCheckArgs 3.2 UserUniqueCheckVo 3.3 UserUniqueCheckService 3.4 UniqueCheckEnum 3.5 单元测试代码 4 调试结果 注: 1 M

  • spring boot整合shiro安全框架过程解析

    这篇文章主要介绍了spring boot整合shiro安全框架过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些问题记录下来,作为自己的学习心得.在这先感谢群主TyCoding的Tumo项目,虽然本人实在太菜了,好些地方看不懂,但还是使我受益

  • Spring AOP AspectJ使用及配置过程解析

    这篇文章主要介绍了Spring AOP AspectJ使用及配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持.因为Spring1.0的时候Aspectj还未出现; AspectJ1.5中新增了对注解的支持,允许直接在Bean类中定义切面.新版本的Spring框架建 议我们都使用AspectJ方式来开发AOP,并提供了非常灵活且

  • Spring Boot2配置服务器访问日志过程解析

    这篇文章主要介绍了Spring Boot2配置服务器访问日志过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Tomcat控制台中看到的日志是服务器的日志,而服务器访问日志则是记录服务处理的请求信息. 开发环境:IntelliJ IDEA 2019.2.2 Spring Boot版本:2.1.8 1.新建一个名称为demo的Spring Boot项目. 2.application.yml 添加配置 server: tomcat: base

  • 基于spring security实现登录注销功能过程解析

    这篇文章主要介绍了基于spring security实现登录注销功能过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependenc

  • spring boot加入拦截器Interceptor过程解析

    这篇文章主要介绍了spring boot加入拦截器Interceptor过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.spring boot拦截器默认有 HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationInterceptor LocaleChangeInterceptor ThemeChangeInterceptor 2.配置spring

  • Spring Cloud基于zuul实现网关过程解析

    这篇文章主要介绍了Spring Cloud基于zuul实现网关过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 利用zuul网关统一向外暴露接口 1.新建项目 spring-zuul 2.引入pom <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuu

  • Spring MVC处理方法返回值过程解析

    这篇文章主要介绍了Spring MVC处理方法返回值过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 对于Spring MVC处理方法支持支持一系列的返回方式: (1)ModelAndView (2)Model (3)ModelMap (4)Map (5)View (6)String (7)Void (8)Object 一,ModelAndView @RequestMapping("/threadRequest*") publi

随机推荐