乐趣区

关于后端:Spring容器获取Bean的9种方式

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 接口和它的实现类
}
退出移动版