📖SpringContextHolder工具类自由获取Bean

发布: 2017-05-19
热度: 68
趋势: 68
权重: 5
🎯

在工程中会存在一些未被纳入Spring框架管理的类,想调用Spring容器中的bean时可以通过SpringContextHolder工具类的getBean方法来获取指定的bean,比如过滤器、拦截器、自动任务等

工具类实现

实现 ApplicationContextAware 接口,以静态变量保存 Spring ApplicationContext。

可在任何代码任何地方任何时候中取出 ApplicaitonContext。

如此就不能不说说 org.springframework.context.ApplicationContextAware 这个接口。

ApplicationContextAware 接口

当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得 ApplicationContext 中的所有 bean。

换句话说,就是这个类可以直接获取 spring 配置文件中,所有有引用到的 bean 对象。

除了以上 SpringContextHolder 类之外,还有不需要多次加载 spring 配置文件就可以取得 bean 的类。

Spring 容器会检测容器中的所有 Bean,如果发现某个 Bean 实现了 ApplicationContextAware 接口,Spring 容器会在创建该 Bean 之后,自动调用该 Bean 的 setApplicationContextAware()方法,调用该方法时,会将容器本身作为参数传给该方法。

该方法中的实现部分将 Spring 传入的参数(容器本身)赋给该类对象的 applicationContext 实例变量,因此接下来可以通过该 applicationContext 实例变量来访问容器本身。

代码示例

/*
 * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean
 * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext
 */
//如果使用注解的方式,需要而配置@Lazy(false)表示不延迟加载(系统启动即刻加载)
@Component
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware {

	private static ApplicationContext applicationContext;

	//实现ApplicationContextAware接口的context注入函数, 将其存入静态变量
	public void setApplicationContext(ApplicationContext applicationContext) {
		SpringContextHolder.applicationContext = applicationContext;
	}

	//取得存储在静态变量中的ApplicationContext
	public static ApplicationContext getApplicationContext() {
		checkApplicationContext();
		return applicationContext;
	}

	//从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		checkApplicationContext();
		return (T) applicationContext.getBean(name);
	}

	//从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型
	//如果有多个Bean符合Class, 取出第一个
	public static <T> T getBean(Class<T> requiredType) {
		checkApplicationContext();
		return applicationContext.getBean(requiredType); 
	}

	//清除applicationContext静态变量
	public static void cleanApplicationContext() {
		applicationContext = null;
	}

	//检查是否存在
	private static void checkApplicationContext() {
		if (applicationContext == null) {
			throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder或配置@Lazy(false)");
		}
	}
}

XML 配置形式

如果不是采用注解的方式配置 Spring 则需要在 spring-context.xml,添加 bean:

<bean id="springContextHolder" class="com.mebugs.utils.SpringContextHolder" lazy-init="false"/>

实际调用示例

private UserService userService= SpringContextHolder.getBean(UserService.class);

报错处理

启动项目后报错 "applicaitonContext 属性为 null,请检查是否注入了 SpringContextHolder!"

SpringContextHolder 这个 bean 没有在实际调用类加载前进行加载,导致没有加载完成。

所以我们需要在配置文件中首先加载 SpringContextHolder。

  • XML 配置方式:
    把 bean 配置放在配置文件的第一行,务必要配置不延迟加载(等同于 @Lazy(false))
  • 注解配置方式:
    实际需要被调用的 bean(如 UserService),类上添加注解 @DependsOn("springContextHolder"),用于确保加载此 bean 之前 SpringContextHolder 类已加载
当前文章暂无讨论,留下脚印吧!
大纲
  • 工具类实现
  • ApplicationContextAware 接口
  • 代码示例
    • XML 配置形式
  • 实际调用示例
  • 报错处理
提交成功,请等待审核通过后全面展示!

发表评论

昵称
邮箱
链接
签名
评论

温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。

选择头像