我們經常需要獲取各種 bean , 需要用到 context。
下面的類可以方便的使用 context , 獲取 bean 等。
import java.io.File; import java.util.ArrayList; import java.util.List; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; /** * 單例上下文對象,配合 spring 使用, 用於獲取 Bean * @author YangYxd * @see 在配置中(applicationContext.xml) 加入 * <bean id="SpringApplicationContext" class="包名.ContextHelper"></bean> */ public class ContextHelper implements ApplicationContextAware { private static String XMLName = "applicationContext.xml"; private static ApplicationContext applicationContext = null; private static class ApplicationContextHolder { // 初始化 Context, 嘗試搜索常用的存放 ApplicationContext.xml 的位置 public static ApplicationContext Init() { ApplicationContext context = null; try { context = new ClassPathXmlApplicationContext(XMLName); } catch (Exception e) {} // 在當前項目中搜索配置文件 if (context == null) { try { String fileName = findFile(System.getProperty("user.dir"), XMLName); if (fileName != null) context = new FileSystemXmlApplicationContext(fileName); } catch (Exception e) {} } return context; } } // 私有化的構造方法,保證外部的類不能通過構造器來實例化。 private ContextHelper() {} /** 設定 XML 名稱 */ synchronized public static void setXmlName(String name) { XMLName = name; } // 獲取單例對象實例 synchronized public static ApplicationContext getInstance() { if (applicationContext != null) return applicationContext; applicationContext = ApplicationContextHolder.Init(); return applicationContext; } /** * 如果BeanFactory包含一個與所給名稱匹配的bean定義,則返回true * @param name * @return boolean */ public static boolean containsBean(String name) { return getInstance().containsBean(name); } /** * @param name * @return Class 注冊對象的類型 */ public static Class<?> getType(String name) { try { return getInstance().getType(name); } catch (Exception e) { return null; } } /** * 如果給定的bean名字在bean定義中有別名,則返回這些別名 * @param name * @return */ public static String[] getAliases(String name) { try { return getInstance().getAliases(name); } catch (Exception e) { return null; } } /** * 判斷以給定名字注冊的bean定義是一個singleton還是一個prototype。 * 如果與給定名字相應的bean定義沒有被找到,也會返回 false * @param name * @return boolean */ public static boolean isSingleton(String name) { try { return getInstance().isSingleton(name); } catch (Exception e) { return false; } } @SuppressWarnings("static-access") @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; System.out.println("ApplicationContextHelper setApplicationContext OK."); } /** * 查找文件 * @param baseDirName 查找的文件夾路徑 * @param targetFileName 需要查找的文件名 */ public static String findFile(String baseDirName, String targetFileName) { List<File> files = new ArrayList<File>(); findFiles(baseDirName, targetFileName, files, true); if (files.isEmpty()) return null; return files.get(0).getPath(); } /** * 遞歸查找文件 * @param baseDirName 查找的文件夾路徑 * @param targetFileName 需要查找的文件名 * @param fileList 查找到的文件集合 * @param onlyFirst 是否是查找第一個 */ public static void findFiles(String baseDirName, String targetFileName, List<File> fileList, Boolean onlyFirst) { File baseDir = new File(baseDirName); // 創建一個File對象 if (!baseDir.exists() || !baseDir.isDirectory()) { // 判斷目錄是否存在 System.out.println("文件查找失敗:" + baseDirName + "不是一個目錄!"); } String tempName = null; //判斷目錄是否存在 File tempFile; File[] files = baseDir.listFiles(); for (int i = 0; i < files.length; i++) { tempFile = files[i]; if(tempFile.isDirectory()){ findFiles(tempFile.getAbsolutePath(), targetFileName, fileList, onlyFirst); }else if(tempFile.isFile()){ tempName = tempFile.getName(); if (tempName != null && tempName.equalsIgnoreCase(targetFileName)) { // 匹配成功,將文件名添加到結果集 fileList.add(tempFile.getAbsoluteFile()); if (onlyFirst) return; } } } } /** * 獲取 Bean * @param beanName * @return */ @SuppressWarnings("unchecked") public static <T extends Object> T getBean(String beanName) { try { return (T)getInstance().getBean(beanName); } catch (BeansException e) { e.printStackTrace(); return null; } } /** * 獲取 Bean * @param beanName * @param clazz * @return */ public static <T extends Object> T getBean(String beanName , Class<T>clazz) { return getInstance().getBean(beanName , clazz); } /** * @param clazz 通過類模板獲取該類 * @return 該類的實例,默認單例 */ public static <T extends Object> T getBean(Class<T> clazz){ try { return getInstance().getBean(clazz); } catch (BeansException e) { e.printStackTrace(); return null; } } }
在單元測試中使用:
package com.yxd.example.bean; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; import org.springframework.test.context.ContextConfiguration; @RunWith(BlockJUnit4ClassRunner.class) @ContextConfiguration({"classpath:applicationContext.xml"}) public class SpringTest { @Test public void enumBeans() { //獲取spring裝配的bean個數 int beanCount = ContextHelper.getInstance().getBeanDefinitionNames().length; //逐個打印出spring自動裝配的bean。根據我的測試,類名第一個字母小寫即bean的名字 for(int i=0; i<beanCount; i++){ System.out.println(ContextHelper.getInstance().getBeanDefinitionNames()[i]); } } }
在這個測試類中,加入ContextConfiguration注解后,會自動加載配置文件。