前言
因为spring中的bean默认是单例的(当然可以通过@Scope(“prototype”)来设置多例)但是在有些需求场景是不交给spring管理最好,又想获取spring的bena对象怎么办?
方法一(不推荐)
还记得刚刚学spring的时候就是这么获取的。
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = ac.getBean("peo",People.class);
但是这样就会存在一个问题:因为它会重新装载applicationContext-common.xml并实例化上下文bean,如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次。一次是web容器初始化时启动,另一次是上述代码显示的实例化了一次。当于重新初始化一遍!!!!这样就产生了冗余。
我觉得方法一还不如自己直接new 一个比较实在。
方法二(推荐)
不用类似new ClassPathXmlApplicationContext()的方式,从已有的spring上下文取得已实例化的bean。通过ApplicationContextAware接口进行实现。
当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
注:在spring的配置文件中,注册方法类SpringUtil 。之所以方法类SpringUtil 能够灵活自如地获取ApplicationContext,就是因为spring能够为我们自动地执行了setApplicationContext,所以SpringUtil 这个类要交给spring管理。这里我们使用@Component来进行注册
这样当需要用到spring管理的bean又不行交个spring管理的时候就用SpringUtil的getBean方法就可以实现了。