在工程中会存在一些未被纳入Spring框架管理的类,想调用Spring容器中的bean时可以通过SpringContextHolder工具类的getBean方法来获取指定的bean,比如过滤器、拦截器、自动任务等
实现 ApplicationContextAware 接口,以静态变量保存 Spring ApplicationContext。
可在任何代码任何地方任何时候中取出 ApplicaitonContext。
如此就不能不说说 org.springframework.context.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)");
}
}
}
如果不是采用注解的方式配置 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。
温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。