news 2026/4/23 11:33:24

SpringBoot获取bean的几种方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot获取bean的几种方式

目录

一、BeanFactory与ApplicationContext的区别

二、通过BeanFactory获取

三、通过BeanFactoryAware获取

四、启动获取ApplicationContext

五、通过继承ApplicationObjectSupport

六、通过继承WebApplicationObjectSupport

七、通过WebApplicationContextUtils

八、通过ApplicationContextAware

九、通过ContextLoader

十、通过BeanFactoryPostProcessor

十一、通过工具类获取


一、BeanFactory与ApplicationContext的区别

BeanFactory是Spring框架的基础设施,面向Spring本身。ApplicationContext则面向使用Spring框架的开发者,几乎所有的应用场景都可以直接使用ApplicationContext,而非底层的BeanFactory。

ApplicationContext的初始化和BeanFactory有一个重大的区别:

BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean,相对应的,ApplicationContext的初始化时间会比BeanFactory长一些。

二、通过BeanFactory获取

通过BeanFactory来获取Bean。

基于xml配置文件:(不推荐使用)

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); User user = (User) beanFactory.getBean("user");
三、通过BeanFactoryAware获取

获取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 接口和它的实现类 }

上述基于BeanFactoryAware的特性,获得了BeanFactory,然后再通过BeanFactory来获得指定的Bean。

四、启动获取ApplicationContext

在项目启动时先获取ApplicationContext对象,然后将其存储在一个地方,以便后续用到时进行使用。

这里提供两种场景的获取:

1.基于xml配置bean的形式,适用于比较古老的项目,已经很少使用了;

2.基于SpringBoot启动时获取ApplicationContext对象;

基于xml的形式实现:

// 其中applicationContext.xml 为配置容器的xml,不过现在一般很少使用了 ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");

基于SpringBoot启动实现:

@SpringBootApplication public class ExampleApplication { ????public static void main(String[] args) { ????????// 启动时,保存上下文,并保存为静态 ????????ConfigurableApplicationContext ac = SpringApplication.run(ExampleApplication.class, args); ????????SpringContextUtil.setApplicationContext(ac); ????} }

对应的SpringContextUtil类如下:

public class SpringContextUtil1 { ????private static ApplicationContext ac; ????public static <T>? T getBean(String beanName, Class<T> clazz) { ????????T bean = ac.getBean(beanName, clazz); ????????return bean; ????} ????public static void setApplicationContext(ApplicationContext applicationContext){ ????????ac = applicationContext; ????} }
五、通过继承ApplicationObjectSupport

此种方式依旧是先获得ApplicationContext容器,然后从中获取Bean对象,只不过是基于继承ApplicationObjectSupport类实现的。

具体实现代码:SpringContextUtil类需要实例化。

@Component public class SpringContextUtil extends ApplicationObjectSupport { ?public <T> T getBean(Class<T> clazz) { ??ApplicationContext ac = getApplicationContext(); ??if(ac == null){ ???return null; ??} ??return ac.getBean(clazz); ?} }

ApplicationObjectSupport类图入下,我们看到它实现了ApplicationContextAware接口,在Spring容器初始化过程中回调方法setApplicationContext来完成ApplicationContext的赋值。

六、通过继承WebApplicationObjectSupport

WebApplicationObjectSupport是ApplicationObjectSupport的一个实现类,提供了Web相关的支持。实现原理与ApplicationObjectSupport一样。

具体实现代码如下:

@Component public class SpringContextUtil extends WebApplicationObjectSupport { ?public <T> T getBean(Class<T> clazz) { ??ApplicationContext ac = getApplicationContext(); ??if(ac == null) ???return null; ??} ??return ac.getBean(clazz); ?} }

通过类图我们可以看到它是ApplicationObjectSupport的实现子类,此方式除了继承对象不同外,没有其他区别,都是基于getApplicationContext方法来获取。

七、通过WebApplicationContextUtils

Spring提供了工具类WebApplicationContextUtils,通过该类可获取WebApplicationContext对象。

具体实现代码如下:

public class SpringContextUtil2 { ?public static <T> T getBean(ServletContext request, String name, Class<T> clazz){ ??WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request); ??// 或者 ??WebApplicationContext webApplicationContext1 = WebApplicationContextUtils.getWebApplicationContext(request); //??????? webApplicationContext1.getBean(name, clazz) ??T bean = webApplicationContext.getBean(name, clazz); ??return bean; ?} }

这个方法很常见于SpringMVC构建的Web项目中,适用于Web项目的B/S结构。

八、通过ApplicationContextAware

通过实现ApplicationContextAware接口,在Spring容器启动时将ApplicationContext注入进去,从而获取ApplicationContext对象,这种方法也是常见的获取Bean的一种方式,推荐使用。

具体实现代码如下:

@Component public class SpringContextUtil3 implements ApplicationContextAware { ?private static ApplicationContext ac; ?@Override ?public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ??ac = applicationContext; ?} ?public static <T> T getBean(Class<T> clazz) { ??T bean = ac.getBean(clazz); ??return bean; ?} }
九、通过ContextLoader

使用ContextLoader提供的getCurrentWebApplicationContext方法,也是常用的获取WebApplicationContext的一种方法。

具体实现代码如下:

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); wac.getBean(beanID);

该方法常见于SpringMVC实现的Web项目中。该方式是一种不依赖于Servlet,不需要注入的方式。但是需要注意一点,在服务器启动时和Spring容器初始化时,不能通过该方法获取Spring容器。

十、通过BeanFactoryPostProcessor

Spring工具类,方便在非Spring管理环境中获取Bean。

@Component public final class SpringUtils implements BeanFactoryPostProcessor{ ????/** Spring应用上下文环境 */ ????private static ConfigurableListableBeanFactory beanFactory; ????@Override ????public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException{ ????????SpringUtilsS.beanFactory = beanFactory; ????} ????/** ?????* 获取对象 ?????* ?????* @param name ?????* @return Object 一个以所给名字注册的bean的实例 ?????* @throws BeansException ?????* ?????*/ ????@SuppressWarnings("unchecked") ????public static <T> T getBean(String name) throws BeansException{ ????????return (T) beanFactory.getBean(name); ????} ????/** ?????* 获取类型为requiredType的对象 ?????* ?????* @param clz ?????* @return ?????* @throws BeansException ?????* ?????*/ ????public static <T> T getBean(Class<T> clz) throws BeansException{ ????????T result = (T) beanFactory.getBean(clz); ????????return result; ????} ????/** ?????* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true ?????* ?????* @param name ?????* @return boolean ?????*/ ????public static boolean containsBean(String name){ ????????return beanFactory.containsBean(name); ????} ????/** ?????* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) ?????* ?????* @param name ?????* @return boolean ?????* @throws NoSuchBeanDefinitionException ?????* ?????*/ ????public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException{ ????????return beanFactory.isSingleton(name); ????} ????/** ?????* @param name ?????* @return Class 注册对象的类型 ?????* @throws NoSuchBeanDefinitionException ?????* ?????*/ ????public static Class<?> getType(String name) throws NoSuchBeanDefinitionException{ ????????return beanFactory.getType(name); ????} ????/** ?????* 如果给定的bean名字在bean定义中有别名,则返回这些别名 ?????* ?????* @param name ?????* @return ?????* @throws NoSuchBeanDefinitionException ?????* ?????*/ ????public static String[] getAliases(String name) throws NoSuchBeanDefinitionException{ ????????return beanFactory.getAliases(name); ????} ????/** ?????* 获取aop代理对象 ?????* ?????* @param invoker ?????* @return ?????*/ ????@SuppressWarnings("unchecked") ????public static <T> T getAopProxy(T invoker){ ????????return (T) AopContext.currentProxy(); ????} }

其中ConfigurableListableBeanFactory接口,也属于BeanFactory的子接口。

十一、通过工具类获取
  • RequestContextUtils.findWebApplicationContext(HttpServletRequest request)
  • WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)

controller中获取:

public String test(HttpServletRequest request,HttpServletRequest response) { WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request); wc.getBean("beanName"); WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()); wc2.getBean("beanName"); }

在service中或者其他后端服务中获取:

HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request); WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()); wc.getBean("beanName"); wc2.getBean("beanName");
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 8:03:21

WaveTools鸣潮工具箱:3分钟掌握游戏性能优化技巧

WaveTools鸣潮工具箱&#xff1a;3分钟掌握游戏性能优化技巧 【免费下载链接】WaveTools &#x1f9f0;鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools WaveTools鸣潮工具箱是一款专为《鸣潮》玩家设计的游戏优化工具&#xff0c;能够显著提升帧率表…

作者头像 李华
网站建设 2026/4/18 15:14:39

老旧设备性能修复与系统优化指南:让老Mac重获新生

老旧设备性能修复与系统优化指南&#xff1a;让老Mac重获新生 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 还在为2013年的MacBook Pro卡顿而烦恼吗&#xff1f;想让你的…

作者头像 李华
网站建设 2026/4/22 0:44:19

鸣潮自动化工具终极配置指南:5分钟快速上手攻略

鸣潮自动化工具终极配置指南&#xff1a;5分钟快速上手攻略 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸上锁合成 自动肉鸽 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 还在为重复的游…

作者头像 李华
网站建设 2026/4/18 5:15:59

PDF-Extract-Kit应用场景:电商评论分析预处理

PDF-Extract-Kit应用场景&#xff1a;电商评论分析预处理 1. 引言&#xff1a;从PDF文档中挖掘用户声音 在电商平台日益激烈的竞争环境下&#xff0c;用户评论数据已成为产品优化、服务改进和市场策略制定的核心依据。然而&#xff0c;大量有价值的用户反馈往往以非结构化形式…

作者头像 李华
网站建设 2026/4/22 13:59:39

QMC解码器:轻松破解QQ音乐加密格式的终极工具

QMC解码器&#xff1a;轻松破解QQ音乐加密格式的终极工具 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 还在为QQ音乐下载的音频文件无法在其他播放器上播放而困扰吗&…

作者头像 李华
网站建设 2026/4/22 10:51:21

OBS虚拟摄像头:3步实现专业直播画面任意切换

OBS虚拟摄像头&#xff1a;3步实现专业直播画面任意切换 【免费下载链接】obs-virtual-cam obs-studio plugin to simulate a directshow webcam 项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam 想让你的Zoom会议、微信视频聊天瞬间拥有专业直播间的视觉…

作者头像 李华