网店版重生系列:都是Spring配置中自动注入惹的祸

Invalid property 'mediaTypes' of bean class Spring mvc4.2.5本 与 3.2配置配置不同导致以下错误信息错误信息:2018-04-24 23:19:10,348 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Finished creating instance of bean 'org.spring... 阅读详情

在对Spring Container管理的bean进行配置时,有一个很好用的功能就是自动注入,可以根据不同规则对bean所依赖的bean进行自动set,相信最常用的就是设置default-autowire="byName"这种方式啦;这样我们在进行配置时就可以减少很多的xml代码、当我们在Java代码中新增或减少bean的注入时就无需再对xml配置进行同步变更(针对采取xml配置的方式,若采用Annotation的方式则不存在该问题),从而提高了编码效率;

一般情况下采取这种自动注入的方式MS也没啥问题,但是在一些特殊情况下可能会导致莫名其妙的问题,从而要花费大量的时间去排错;在最近的一个项目中就被我遇上了;问题大概是这样的:以前的应用基于Oracle单数据源进行开发,Spring配置采取byName自动注入;但由于数据量剧增导致Oracle服务器不堪重负,小型机扩容成本太高,于是我们决定将原有应用改造成基于Mysql的按用户水平划分的分布式DB结构;这样的话,就需要修改DAO层关于datasource相关的一些配置,在调整过程中,问题就产生了;

原有与datasource相关的大致配置如下:

所有的DAO配置中都设置parent="daoDefinition",并在Java实现中extends SqlMapClientDaoSupport;

应用改造时,我们采用了基于Spring的AbstractRoutingDataSource来实现动态数据源的加载,但由于应用中只有部分表的数据能进行分库,所以改造后的系统中将会存在两种类型的数据源,其一仍然为原Oracle主库,通过JNDI访问、其二为新增的Mysql分库,通过动态ds访问;

由于AbstractRoutingDataSource从当前线程中获取绑定的用户信息,而在同一次用户的操作中,可能会存在既访问原来的Oracle主库、又访问Mysql分库的情况,所以动态ds中需要兼容这种情况,并且在每次DB操作完成之后需要清空当前线程中绑定的变量,这样主要是为了避免所有的DAO层都进行变动,但在哪里自动完成当前线程绑定变量的清空操作呢?当然是在SqlMapClientTemplate中,因为所有的DAO操作都是通过这个template封装接口进行访问的,所以需要继承该类并对所有的method进行扩展;新的配置如下:

涉及到访问Mysql分库的DAO均设置parent="ddbDaoDefinition",并在Java实现中extends DdbSqlMapClientDaoSupport;

这样的配置MS没有问题,template中已经明确设置采用动态ds,DAO实现类中也已明确继承新的template类!后来经跟踪代码发现:还是Spring的自动注入惹的祸
原因如下:

SqlMapClientDaoSupport中可以自动注入3个bean:datasource、sqlMapClient、sqlMapClientTemplate;而这3个bean的注入是有先后顺序的,其实datasource、sqlMapClient都是设置到sqlMapClientTemplate中的!问题就出现在这里了;
在我们的配置中,parent中显示设置了sqlMapClientTemplate,而没有设置其他两个属性;按照Spring自动注入的默认规则,首先会将显示set的bean注入,此时的sqlMapClientTemplate是被设置了动态ds的正确的bean,但是显示set注入完成之后,Spring还会根据是否自动注入扫描bean里面的set方法,完成非显示bean的注入,此时问题就出现了,Spring根据默认datasource这个name找到了原有的基于JNDI的那个bean进行注入了,于是sqlMapClientTemplate中的datasource就被覆盖了,也即原来正确的动态ds被替换回了原有的基于JNDI的Oracle主库的datasource!

原因找到之后问题就好解决了,方法很多,比如:

  1. 在ddbDaoDefinition配置中增加显示设置<property name="dataSource" ref="mixedDdbDatasource"/>;
    注意:为保险起见,这个显示datasource的set放在sqlMapClientTemplate之后,因为Spring会按照设置的先后顺序进行注入,若放在sqlMapClientTemplate之前,则会被后者覆盖掉,具体依赖于被注入bean内set方法的实现;
  2. 去掉DAO配置文件中的自动注入;其实DAO层一般不会依赖于其他的bean,都是被依赖的,所以这个自动注入完全没有必要,反而给应用带来隐患;
org.springframework.beans.factory.BeanCreationException Error creating bean with name 'sqlSessionFactory' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Cannot resolve reference to bean 'myInterceptor' while setting bean property 'plugins' with key [0]; nested exception is org.springfram 阅读详情

相关推荐

springmvc报错“org.springframework.beans.factory.BeanCreationException: Error creating bean with name”

报错信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0’: Initialization of be...

zbreezeH的博客 3304

Maven依赖的配置

简单的依赖配置一个依赖声明可以包含以下元素: 根元素project下的dependencies可以包含一个或者多个dependency元素,可以声明一个或者多个项目依赖。每个依赖可以包含的元素有: groupId、artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,maven根据坐标才能找到需要的依赖。 type:依赖的类型,对应项目坐标定义的packa

C. 701

Spring 基于 xml 配置的声明式事务

1.测试一个没有事务的insert语句 首先测试一个没有事务的insert语句,测试插入一条数据,测试成功,如下图所示,大家可以随便找一个之前的SSM来进行插入测试,这里测试的是 private ClassService classService;的insert方法。 分析一下日志,如下所示,日志的全部分析见附录。 --- 创建了数据库连接池 DEBUG [...

学习笔记 1841

Spring MVC 启动异常,@Autowired注入失败。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.facto

qq_30059235的博客 1万+

Spring生命周期-InitializingBean,DisposableBean

IOC容器的组件除通过声明自定义初始化和销毁方法外,可以实现InitializingBean接口和DisposableBean接口,在实现内中完成初始化和销毁的逻辑; InitializingBean的接口定义如下: package org.springframework.beans.factory; public interface InitializingBean { /** ...

luojinbai的专栏 1265

使用spring boot 改造老项目,多个数据源问题

使用spring boot 改造老项目,因为数据源有多个,启动时一直报如下错误 Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single m

terry7的博客 2万+

Java中用HttpsURLConnection访问Https链接的问题

在web应用交互过程中,有很多场景需要保证通信数据的安全;在前面也有好多篇文章介绍了在Web Service调用过程中用WS-Security来保证接口交互过程的安全性,值得注意的是,该种方式基于的传输协议仍然是Http,采用这种方式可扩展性和数据交互效率比较高;另外一种实现方式就是用Https,他是在协议层对Http的再次封装,加入了SSL/TLS,采用该协议进行通信的数据全部都会被加密,由于目

老唐 的专栏 5万+

Spring中集成Quartz时遭遇Failure obtaining db row lock异常

今天在一个新的项目中用Spring集成Quartz来进行任务调度,和以往一样,配置好JobDetail、Trigger、SchedulerFactoryBean启动,却遭遇到如下异常信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name sfb defined in UR

老唐 的专栏 3万+

遭遇OutOfMemoryError

这几天,网店系统基础架构进行了一次大的升级,升级之后例行的进行了压力测试,以前几次大的项目发布压力测试都没有任何问题,没想到这次出事故啦,而且是内存泄露?系统运行环境:硬件:Intel(R) Xeon(R) CPU 2.0G、4G RAM、Linux 2.6.9-42.ELsmp #1 SMP 软件:jboss-4.0.5.GA [Java HotSpot(TM) Server VM (bui

老唐 的专栏 3万+

23种经典设计模式UML类图汇总

最近下载了一本由Jason McDonald整理的超精简《设计模式》;看了之后感觉非常的爽,在此和大家share下;习惯了厚厚的砖头,看到这本精简电子书,着实兴奋了下,书中内容非常精炼,主要涉及23种设计模式的UML类图、目标、应用场景、应用实例;这对于日常查询或者是总体浏览比较等等非常的方便;下面就把书中最重要的各种设计模式的UML类图贴图说明:

老唐 的专栏 2万+

Quartz中扩展MethodInvokingJobDetailFactoryBean实现对任务调度的拦截

利用Quartz来实现对任务的调度已经被广泛地应用了,一个利用Quartz来进行任务调度的典型配置如下:<bean id="xxJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> false

老唐 的专栏 2万+

基于Spring打造简单高效通用的异步任务处理系统

背景随着应用系统功能的不断新增,而某些功能的实现对实时性要求并不是那么高,但是逻辑却很复杂、执行比较耗时,比如涉及外部系统调用、多数据源等等;此时,我们就希望可以让这些复杂的业务逻辑放在后台执行,而前台与用户的交互可以不用等待,从而提高用户体验;另外,从系统架构这个层面来说,我们也希望按照不同功能来拆分,以保持各个系统之间的低耦合,当一个系统出现问题时不会影响到其他系统,并且对于独立的各个

老唐 的专栏 2万+
上一篇: 基于Spring打造简单高效通用的异步任务处理系统
下一篇: 网店版重生系列:回头看Jboss配置项CatchSystemOut、Java2ClassLoadingCompliance、UseJBossWebLoader
sfdev
博客等级 码龄22年 467粉丝 134原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值