使用監(jiān)聽器對Spring bean id進(jìn)行唯一校驗過程解析
背景
項目中用到了多數(shù)據(jù)源,不同的數(shù)據(jù)源根據(jù)業(yè)務(wù)不同配置在不同的工程中,由maven來統(tǒng)一聚合。但是前幾天在開發(fā)過程中突然發(fā)現(xiàn)項目前臺工程的事務(wù)配置不起作用了,在之前明明測試過事務(wù)功能,當(dāng)時是生效的。
然后檢查了一下配置文件中事務(wù)部分的配置,發(fā)現(xiàn)沒什么改動。為了排除其它因素的干擾,采用了單元測試重新測試了一次,結(jié)果發(fā)現(xiàn)當(dāng)前數(shù)據(jù)源事務(wù)正常。根據(jù)這個分析可能是當(dāng)前的事務(wù)配置被其它配置干擾了,仔細(xì)檢查了一下后發(fā)現(xiàn)罪魁禍?zhǔn)资橇硗獾囊粋€數(shù)據(jù)源事務(wù)配置(在另外的一個配置文件中)的bean id名稱和當(dāng)前的事務(wù)配置bean id重復(fù)了。
我們都知道,Spring會對同一份配置文件中的bean進(jìn)行校驗,也就是說在同一份配置文件中不允許出現(xiàn)相同的bean定義,會提示報錯。但是Spring IOC容器在加載時并不會顯示對不同配置文件中重復(fù)的bean id進(jìn)行報錯提示,當(dāng)遇到有重復(fù)的bean定義時,Spring采取的策略是把后面加載的配置覆蓋前面加載的配置,沒有任何警告和提示。
這樣很容易造成一個問題是當(dāng)我們團(tuán)隊進(jìn)行開發(fā)時可能會不小心覆蓋別人定義的bean,導(dǎo)致系統(tǒng)出現(xiàn)不可預(yù)知的錯誤和異常。
怎么解決這個問題呢?我們可以配置監(jiān)聽器,在Spring容器啟動時對重復(fù)的bean進(jìn)行校驗,如果有重復(fù)的bean,則報錯提示。
因為Spring IOC容器啟動加載時會檢查bean定義是否有重復(fù),如果有重復(fù)則會根據(jù)AbstractRefreshableApplicationContext類中的allowBeanDefinitionOverriding屬性值進(jìn)行判斷,如果值為true,則把后加載的bean覆蓋前面加載的bean定義,如果為false則拋出BeanDefinitionStoreException異常。
所以,解決這個問題的辦法就比較簡單了,只要將這個allowBeanDefinitionOverriding值在spring初始化的時候設(shè)置為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 {
/**
* 設(shè)置allowBeanDefinitionOverriding屬性為false,spring ioc容器在加載bean的過程中會去判斷beanName 是否有重復(fù),. <br/>
* 如果發(fā)現(xiàn)重復(fù)的話再根據(jù)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;
//設(shè)置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文件的監(jiān)聽器配置
<!-- 自定義的ContextLoaderListener --> <listener> <listener-class>com.chenzhou.examples.erm.util.listener.MyContextLoaderListener</listener-class> </listener>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- spring中bean id相同引發(fā)故障的分析與解決
- Spring實戰(zhàn)之容器中的工程Bean用法示例
- Spring實戰(zhàn)之抽象Bean和子Bean定義與用法示例
- Spring實戰(zhàn)之調(diào)用實例工廠方法創(chuàng)建Bean操作示例
- Spring實戰(zhàn)之使用靜態(tài)工廠方法創(chuàng)建Bean操作示例
- Spring如何使用注解的方式創(chuàng)建bean
- Spring實戰(zhàn)之注入嵌套Bean操作示例
- Java類獲取Spring中bean的5種方式
- Spring的自動裝配Bean的三種方式
- Spring實戰(zhàn)之獲得Bean本身的id操作示例
相關(guān)文章
Mybatis操作數(shù)據(jù)時出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?c
這篇文章主要介紹了Mybatis操作數(shù)據(jù)時出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?column?'XXX'?in?'field?list',需要的朋友可以參考下2023-04-04
Java守護(hù)線程實例詳解_動力節(jié)點Java學(xué)院整理
在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護(hù)線程) 。下面通過本文給大家分享java守護(hù)線程實例詳解,需要的朋友參考下吧2017-06-06

