面试题: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;这…

日期对象与节点操作

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;那么这个时…

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

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

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

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

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

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

API网关

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

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

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

浅析linux中的信号

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

AcWing 2816. 判断子序列

文章目录 AcWing 2816. 判断子序列我的思路CODE 欣赏大神代码给点思考 AcWing 2816. 判断子序列 题目链接&#xff1a;https://www.acwing.com/activity/content/problem/content/2981/ 我的思路 直接硬套模版&#xff0c;把两个指针两层循环写上如果匹配&#xff0c;记录数组…

汽车内饰灯不亮问题修复

车内饰灯不亮问题修复 最近换后座阅读灯火光闪了一下&#xff0c;保险丝短路&#xff0c;导致车内所有灯光&#xff0c;包括前后座阅读灯、后备箱灯都不亮了。 因为是所有灯都不亮&#xff0c;所以排除灯泡问题&#xff0c;网上查了下大概率是保险丝烧了。于是查了自己更换保…

idea下载与安装,以及创建一个项目写HelloWorld

1.idea下载 Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com) Ultimate为旗舰版&#xff0c;功能全面&#xff0c;插件丰富&#xff0c;按年收费。 Community为社区版&#xff0c;免费试用&#xff0c;功能相对而言不是很丰富&#xff0c;但是不影…

Linux系统---环境变量+内核进程调度队列(选学)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、环境变量 1.基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数&#xff0c;如: 我们在编写CI/…

Python 分解IP段获取所有IP(子网掩码)

需求 192.168.1.0/24,192.168.2.1-192.168.2.254,192.168.3.3 IP段格式已 "," 分割&#xff0c;获取所有IP 注意 1. 判断 IP 是否合规 2. 去除多余的字符&#xff0c;例如空格、换行符 3. 去重 代码 import re import ipaddressdef isIP(ip):p re.compile(^((…

考虑区域多能源系统集群协同优化的联合需求侧响应模型程序代码!

本程序参考中国电机工程学报论文《考虑区域多能源系统集群协同优化的联合需求侧响应模型》&#xff0c;文章使用关系矩阵来表示电、热、气的耦合关系&#xff0c;使用NSGA2方法对多目标优化方法进行求解&#xff0c;文章中考虑环境因素是目前研究的热点。程序中算例丰富&#x…

LINUX入门篇【11】---进程篇【3】---进程优先级,进程切换,进程调度

前言&#xff1a; 有了前面知识点的铺垫&#xff0c;本篇我们将围绕进程的三个方面来展开&#xff0c;即进程优先级&#xff0c;进程切换以及进程调度的问题&#xff0c;这里的进程调度其实本质就是CPU是如何去调度进程的。 进程优先级&#xff1a; 优先级的概念&#xff1a…

[Linux ] sed文本处理和免交互

一、sed 1.1 sed是什么 sed 是一种流编辑器&#xff08;stream editor&#xff09;&#xff0c;用于对文本数据进行文本转换和处理。它通常被用于在命令行中执行文本编辑任务&#xff0c;可以对输入的文本进行搜索、替换、删除等操作&#xff0c;并将结果输出。sed 是一个非交…

10.点赞 + 我收到的赞

1.点赞 点赞&#xff1a;支持对帖子、评论点赞&#xff1b;第1次点赞&#xff0c;第2次取消点赞首页点赞数量&#xff1a;统计帖子的点赞数量详情页点赞数量&#xff1a;统计点赞数量、显示点赞状态 1.1 生成 redis 工具类 将数据存入到 redis 中&#xff0c;以 key 为关键&…