我们经常需要获取各种 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注解后,会自动加载配置文件。