1 前言
随着SpringBoot的遍及,Spring的应用也越来越广,在某些场景下,咱们无奈通过注解或配置的模式间接获取到某个Bean。比方,在某一些工具类、设计模式实现中须要应用到Spring容器治理的Bean,此时就须要间接获取到对应的Bean。
本文为大家整顿汇总了常见的获取Bean的形式,并提供一些优劣剖析,不便大家在应用到时有更好的抉择。同时,也会为大家适当的遍及和拓展一些相干常识。
2 Spring的IoC容器
在Spring中,Bean的实例化、定位、配置应用程序中的对象及建设对象间的依赖关系,都是在IoC容器中进行的。因而,要在Spring中获取Bean,实质上就是从IoC容器当中获取Bean。
在Spring中,BeanFactory是IoC容器的理论代表者,该接口提供了IoC容器最基本功能。同时,Spring还提供了另外一种类型的容器:ApplicationContext容器。
ApplicationContext容器包含BeanFactory容器的所有性能(BeanFactory的子接口),提供了更多面向利用的性能,它提供了国际化反对和框架事件体系,更易于创立理论利用。
个别状况,咱们称BeanFactory为IoC容器,称ApplicationContext为利用上下文。但有时为了不便,也将ApplicationContext称为Spring容器。
通常不倡议应用BeanFactory,但BeanFactory 依然能够用于轻量级的应用程序,如挪动设施或基于applet的应用程序,其中它的数据量和速度是显著。
2.1 BeanFactory与ApplicationContext的区别
BeanFactory是Spring框架的基础设施,面向Spring自身。ApplicationContext则面向应用Spring框架的开发者,简直所有的利用场景都能够间接应用ApplicationContext,而非底层的BeanFactory。
另外,ApplicationContext的初始化和BeanFactory有一个重大的区别:
BeanFactory在初始化容器时,并未实例化Bean,直到第一次拜访某个Bean时才实例指标Bean。这样,咱们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次应用调用getBean办法才会抛出异样。
而ApplicationContext则在初始化利用上下文时就实例化所有单实例的Bean,绝对应的,ApplicationContext的初始化工夫会比BeanFactory长一些。
理解了上述的根本理论知识之后,咱们就能够尝试从IoC容器当中获取Bean对象了。
3 Bean获取形式
3.1 形式一:通过BeanFactory获取
通过BeanFactory来获取Bean。基于xml配置文件的时代,能够通过如下形式取得BeanFactory,再通过BeanFactory来取得对应的Bean。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(“applicationContext.xml”));
User user = (User) beanFactory.getBean(“user”);
有肯定编程年龄的程序员,应该对此还有一些印象。这种写法预计也只会呈现在古老的我的项目当中。鉴于xml模式配置文件曾经被基于注解模式所代替,同时XmlBeanFactory也被标注为废除。此种形式不举荐应用。
其实,不举荐的理由还有一个,在下面曾经提到,尽量不要应用BeanFactory,而应该应用ApplicationContext。
3.2 形式二 :通过BeanFactoryAware获取
在下面的形式中,XmlBeanFactory曾经被废除,但能够通过其余形式来取得BeanFactory,而后再从BeanFactory中取得指定的Bean。获取BeanFactory实例最简略的形式就是实现BeanFactoryAware接口。
BeanFactoryAware接口源码:
public interface BeanFactoryAware extends Aware {
/**
* 初始化回调办法,Spring会主动将BeanFactory注入进去,接管之后即可应用BeanFactory
*/
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
BeanFactoryAware属于
org.springframework.beans.factory.Aware根标记接口,应用setter注入来在应用程序上下文启动期间获取对象。Aware接口是回调,监听器和观察者设计模式的混合,它示意Bean有资格通过回调形式被Spring容器告诉。
示例如下:
@Component
public class BeanFactoryHelper implements BeanFactoryAware {
private static BeanFactory beanFactory;
/**
* 重写 BeanFactoryAware 接口的办法
* @param beanFactory :参数赋值给本地属性之后即可应用 BeanFactory
* @throws BeansException BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
BeanFactoryHelper.beanFactory = beanFactory;
}
/**
* 依据名称获取容器中的对象实例
* @param beanName :注入的实例必须曾经存在容器中,否则抛异样:NoSuchBeanDefinitionException
* @return Object
*/
public static Object getBean(String beanName) {
return beanFactory.getBean(beanName);
}
/**
* 依据 class 获取容器中的对象实例
* @param requiredType :被注入的必须曾经存在容器中,否则抛异样:NoSuchBeanDefinitionException
* @param <T> Class
* @return 对象
*/
public static <T> T getBean(Class<T> requiredType) {
return beanFactory.getBean(requiredType);
}
/**
* 判断 spring 容器中是否蕴含指定名称的对象
* @param beanName bean名称
* @return 是否存在
*/
public static boolean containsBean(String beanName) {
return beanFactory.containsBean(beanName);
}
//其它需要皆可参考 BeanFactory 接口和它的实现类
}
发表回复