面试题:Spring 中获取 Bean 的方式有哪些?

文章目录

  • 前言
  • 1、在初始化时保存ApplicationContext对象
  • 2、通过Spring提供的工具类获取ApplicationContext对象
  • 3、实现接口ApplicationContextAware(推荐)
  • 4、继承自抽象类ApplicationObjectSupport
  • 5、继承自抽象类WebApplicationObjectSupport
  • 6、使用BeanFactory直接获取(不推荐)
  • 7、使用ContextLoader提供的getCurrentWebApplicationContext方法
  • 8、实现接口BeanFactoryPostProcessor
  • 扩展
    • BeanFactory
    • ApplicationContext


前言

在这里插入图片描述


1、在初始化时保存ApplicationContext对象

适用于Spring框架的独立应用程序,须要程序通过配置文件初始化Spring。
applicationContext.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="test" class="com.sxtx.bean.Test">
</bean></beans>

代码:

@Test
public void test() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//ApplicationContext applicationContext = new FileSystemXmlApplicationContext("applicationContext.xml"); Test test= (Test) applicationContext.getBean("test");System.out.println(test);
}

2、通过Spring提供的工具类获取ApplicationContext对象

适合于Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象。然后在通过它获取须要的类实例。以下两个工具方式的差别是,前者在获取失败时抛出异常。后者返回null。

ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc); 
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc); 
ac1.getBean("beanId"); 
ac2.getBean("beanId");

3、实现接口ApplicationContextAware(推荐)

实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring初始化时,扫描到该类,就会通过该方法将ApplicationContext对象注入。然后在代码中就可以获取spring容器bean了。
例如:

User bean = SpringUtils.getBean(“user”);

@Component
public class SpringUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringUtils.applicationContext = applicationContext;}public static <T> T getBean(String beanName) {if(applicationContext.containsBean(beanName)){return (T) applicationContext.getBean(beanName);}else{return null;}}public static <T> Map<String, T> getBeansOfType(Class<T> baseType){return applicationContext.getBeansOfType(baseType);}
}

4、继承自抽象类ApplicationObjectSupport

调用父类的getApplicationContext()方法,获取Spring容器对象。

@Service
public class SpringContextHelper extends ApplicationObjectSupport {public Object getBean(String beanName) {return getApplicationContext().getBean(beanName);}
}

5、继承自抽象类WebApplicationObjectSupport

调用getWebApplicationContext()获取WebApplicationContext

@Service
public class SpringContextHelper extends WebApplicationObjectSupport {public Object getBean(String beanName) {return getApplicationContext().getBean(beanName);}
}

6、使用BeanFactory直接获取(不推荐)

使用BeanFactory从工厂中直接获取Bean实例,但是XmlBeanFactory类已经废弃,因此不建议使用。

@Test
public void test() {BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));Test test= (Test) beanFactory.getBean("test");System.out.println(test);
}

7、使用ContextLoader提供的getCurrentWebApplicationContext方法

@Test
public void test() {MockServletContext sc = new MockServletContext("");sc.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, "/applicationContext.xml");ServletContextListener listener = new ContextLoaderListener();ServletContextEvent event = new ServletContextEvent(sc);listener.contextInitialized(event);WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();Test test= (Test) wac.getBean("test");System.out.println(test);
}

8、实现接口BeanFactoryPostProcessor

spring工具类 方便在非spring管理环境中获取bean

@Component
public final class SpringUtilsS implements BeanFactoryPostProcessor
{/** Spring应用上下文环境 */private static ConfigurableListableBeanFactory beanFactory;@Overridepublic 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();}
}

扩展

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

BeanFactory

(1)、是Spring里面最底层的接口(最原始的接口),包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。

(2)、采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

(3)BeanFactory通常以编程的方式被创建。

(4)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

(5) 占用内存小。

ApplicationContext

1、ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:

  • 继承MessageSource,因此支持国际化。
  • 统一的资源文件访问方式。
  • 提供在监听器中注册bean的事件。
  • 同时加载多个配置文件。
  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

2、ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

3、ApplicationContext 占用内存空间大,当程序的配置bean特别多时,程序启动慢。

4、ApplicationContext 能以编程式方式创建,还能能以声明的方式创建,如使用ContextLoader。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python深度学习第二版】学习笔记之——什么是深度学习

机器学习是将输入&#xff08;比如图像&#xff09;映射到目标&#xff08;比如标签“猫”&#xff09;的过程。 这一过程是通过观察许多输入和目标的示例来完成的。 深度神经网络通过一系列简单的数据变换&#xff08;层&#xff09;来实现这种输入到目标的映射&#xff0c;这…

RK3566RK3568 安卓11 在framework层进行串口通信

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

日期对象与节点操作

1.日期对象 1.1实例化 // 实例化const date new Date()console.log(date);// 返回指定时间const date1 new Date(2022-5-1 08:30:00)console.log(date1);1.2日期对象方法 1.3时间戳 三种获取时间戳的方法 const date new Date()console.log(date.getTime());console.log(ne…

MaskDINO环境搭建与模型测试

1、环境搭建 1、构建虚拟环境安装torch conda create -n mmdetsam python3.8 -y conda activate mmdetsampip install torch1.10.0cu102 torchvision0.11.0cu102 torchaudio0.10.0 -f https://download.pytorch.org/whl/torch_stable.html -i http://mirrors.aliyun.com/pypi…

【计算机网络学习之路】序列化,反序列化和初识协议

文章目录 前言一. 序列化和反序列化1.自己实现2. JSON 二. 初识协议结束语 前言 本系列文章是计算机网络学习的笔记&#xff0c;欢迎大佬们阅读&#xff0c;纠错&#xff0c;分享相关知识。希望可以与你共同进步。 本篇博文讲解应用层的序列化和反序列化&#xff0c;还有见一…

uniapp页面使用多个echarts出现数据渲染错乱问题解决

首先&#xff0c;uniapp当中使用echarts是在通过使用renderjs的script模板的前提下实现的&#xff0c;在官方提供的案例当中&#xff0c;核心代码是这一部分&#xff1a; 但如果将其封装为组件&#xff0c;并在一个页面当中引用多次来生成多个charts图标&#xff0c;那么这个时…

字符串哈希

引例 题目描述 给定一个字符串 A A A 和一个字符串 B B B&#xff0c;求 B B B 在 A A A 中的出现次数。 A A A 和 B B B 中的字符均为英语大写字母或小写字母。 A A A 中不同位置出现的 B B B 可重叠。 输入格式 输入共两行&#xff0c;分别是字符串 A A A 和字符串…

企业微信,打造高效私域运营的重要工具!

随着数字时代的来临&#xff0c;私域运营已经成为了企业运营的重要环节。私域运营的核心在于人的运营&#xff0c;如何将目标用户牢牢地锁在自己的阵地上&#xff0c;并能够高效地运转起来&#xff0c;这是私域运营的关键所在。而企业微信&#xff0c;作为连接个人微信和企业微…

linux关于网络的一部分操作

目录 linux系统中一些简单的网络知识以及操作命令 查看ip命令 ping&#xff1a;检测与目标主机的连通性(现在很多服务器允许访问&#xff0c;但不允许ping发送的icmp包&#xff0c;防止探测) netstat&#xff1a;查看当前网络状态信息&#xff0c;包括服务及使用的端口 固定…

大地测量乙级资质申请条件

整理一期关于测绘资质大地测量乙级资质的申请要求 测绘资质是由测绘资质主管部门自然资源部制定的 想要了解标准、正规的申请条件&#xff0c;可以到当地省份的政务网搜索测绘资质办理相关标准&#xff08;例如下图&#xff09; 1、通用标准 http://gi.mnr.gov.cn/202106/P02…

在uniCloud中使用正则表达式进行文本匹配和处理的方法

1. 正则表达式基础 正则表达式是一种用来匹配字符串的模式。它由普通字符&#xff08;例如字符 a 到 z&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;组成。以下是一些基本的正则表达式示例&#xff1a; 匹配邮箱的正则表达式&#xff1a;/^[\w-](\.…

2023关键事件

情境/背景&#xff1a; SAP系统未提供配置BOM解析功能&#xff0c;多个业务部长多次开会强调系统没有配置BOM查询功能&#xff0c;严重影响供应链物料管理。目标/任务&#xff1a; 实现SAP系统中配置BOM解析功能自开发定制程序行动/举措&#xff1a; 花费大量业余时间&#xff…

Python与设计模式--模板模式

23种计模式之 前言 &#xff08;5&#xff09;单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、&#xff08;11&#xff09;策略模式、责任链模式、命令模式、中介者模…

java 鸿鹄云商 SAAS云产品概述 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城免费搭建

【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营…

一秒开挂!纯 Python 开发 Web 应用

你好&#xff0c;我是 EarlGrey&#xff0c;喜欢翻译点东西&#xff0c;偶尔写写代码。 点击下方卡片关注我&#xff0c;一起向上进击&#xff0c;提升自我。后台回复关键词“电子书”&#xff0c;送你一份我收藏的电子书合集。 PyWebIO 是一个用于构建交互式 Web 应用程序的 P…

漫动作杂志漫动作杂志社漫动作编辑部2023年第10期目录

漫步艺海 钟日恒作品欣赏 (0001) 钟日恒 白建宁作品欣赏 (0003) 白建宁 史君仪作品欣赏 (0006) 史君仪 黄韬、时钺博作品欣赏 (0007) 黄韬;时钺博 刘合栋、方晓玲作品欣赏 (0008) 刘合栋;方晓玲 宗家禾作品欣赏 (0009) 宗家禾 漫游美术《漫动作》投稿&…

API网关

API网关的作用 下图显示了详细信息。 步骤 1 - 客户端向 API 网关发送 HTTP 请求。 步骤 2 - API 网关解析并验证 HTTP 请求中的属性。 步骤 3 - API 网关执行允许列表/拒绝列表检查。 步骤 4 - API 网关与身份提供商对话以进行身份​​验证和授权。 步骤 5 - 将速率限制规…

蓝桥杯第一天-----时间显示

文章目录 前言一、题目描述二、测试用例三、题目分析四、具体代码实现总结 前言 本章中将相信介绍蓝桥杯中关于时间显示的题目。 链接&#xff1a;https://www.lanqiao.cn/problems/1452/learning/ 一、题目描述 二、测试用例 三、题目分析 1.输入的时间为毫秒&#xff0c;毫…

大数据学习(26)-spark SQL核心总结

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

浅析linux中的信号

人们往往将信号称为“软件中断”&#xff0c;它提供了异步事件的处理机制&#xff0c;这些事件可以来自系统外部&#xff08;如用户按下ctrlc产生中断符&#xff09;&#xff0c;也可能来自程序或者内核内部的执行动作&#xff08;如进程除零操作&#xff09;。进程收到信号&am…