在最近的項目中,有個地方我們不得不實用getBean的方法,自己從Spring context中獲取bean進行數據庫操作。
方法一(效率低,極易出現bug,不推薦使用):
剛剛開始的時候,我們使用這中方式,但是在應用過程中發現此方式效率低下,而且極易出現bug。 在我們系統中會生成ehcache_auto_created_時間戳文件夾,
<!-- lang: java -->
String[] xmlCfg = new String[] {"classpath:/spring/applicationContext-service.xml",
"classpath:/spring/applicationContext-util.xml",
"classpath:/spring/applicationContext.xml"};
ApplicationContext context = new FileSystemXmlApplicationContext(xmlCfg);
// 獲取inspectionUtil bean
inspectionUtil = (InspectionUtil) context.getBean("inspectionUtil");
所以我google了一下,改用其他方法。
方法二(效率高,靈活性高,可復用,推薦使用): 創建一個工具類SpringContextsUtil ,通過實現Spring中的ApplicationContextAware接口,在applicationContext.xml中注入bean后Spring會自動調用setApplicationContext方法。此時我們就可以獲取到Spring context。
<!-- lang: java -->
public class SpringContextsUtil implements ApplicationContextAware{
private static ApplicationContext applicationContext; //Spring應用上下文環境
/**
- 實現ApplicationContextAware接口的回調方法,設置上下文環境
- @param applicationContext
- @throws BeansException
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextsUtil.applicationContext = applicationContext;
}
/**
- @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
- 獲取對象
- @param name
- @return Object 一個以所給名字注冊的bean的實例
- @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
/**
- 獲取類型為requiredType的對象
- 如果bean不能被類型轉換,相應的異常將會被拋出(BeanNotOfRequiredTypeException)
- @param name bean注冊名
- @param requiredType 返回對象類型
- @return Object 返回requiredType類型對象
- @throws BeansException
*/
public static Object getBean(String name, Class requiredType) throws BeansException {
return applicationContext.getBean(name, requiredType);
}
/**
- 如果BeanFactory包含一個與所給名稱匹配的bean定義,則返回true
- @param name
- @return boolean
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
/**
- 判斷以給定名字注冊的bean定義是一個singleton還是一個prototype。
- 如果與給定名字相應的bean定義沒有被找到,將會拋出一個異常(NoSuchBeanDefinitionException)
- @param name
- @return boolean
- @throws NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
/**
- @param name
- @return Class 注冊對象的類型
- @throws NoSuchBeanDefinitionException
*/
public static Class getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
/**
- 如果給定的bean名字在bean定義中有別名,則返回這些別名
- @param name
- @return
- @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
調用方法:
<!-- lang: java -->
// 獲取inspectionUtil bean
inspectionUtil = (InspectionUtil) SpringContextUtil.getBean("inspectionUtil");
注:
1、使用時會出現無法獲取applicationContext,並拋出NullPointerException。 原因:使用此方法必須在spring applicationContext.xml中注入bean。否則spring無法自動調用setApplicationContext。如下
<!-- lang: xml -->
<bean id="springContextsUtil" class="com.sinosoft.sepmis.util.SpringContextsUtil" ></bean>
2、如果注入后仍然出現這個問題。 則修改<beans default-autowire="byName" default-lazy-init="true">中的default-lazy-init="false"。 或者是修改bean注入屬性
<!-- lang: xml -->
<bean id="springContextsUtil" class="com.sinosoft.sepmis.util.SpringContextsUtil" lazy-init="false"></bean>
<div class="ad-wrap" style="margin-top: 12px;">
<div data-traceid="blog_down_1" data-tracepid="blog_down" style="text-align:center">
<!-- oschina-blog-728x90 -->
<ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-7090564139599510" data-ad-slot="5590362768"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<script type="text/javascript">
function googleAdJSAtOnload() {
var element = document.createElement("script");
element.src = "//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener("load", googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent("onload", googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}
</script>