获取Spring ApplicationContext容器上下文对象实例
Spring ApplicationContext 容器可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。另外,它增加了企业所需要的功能,比如,从属性文件中解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface 接口中定义。
ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有这样的缺陷了。
传统的获取ApplicationContext的方式有很多种,下面小编简单地介绍几种常用的方式!在获取ApplicationContext实例后,就可以调用getBean(beanName)返回Bean了。
为了验证,假设已经构建了Spring Boot项目,在包com.eg.wiener.config中新增测试类。
package com.eg.wiener.config; import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service; @Service
public class BeanTest { @Bean
public BeanTest getBeanObj() {
BeanTest bean = new BeanTest();
System.out.println("调用方法:" + bean);
return bean;
} }
直接注入
@Autowired
private ApplicationContext ctx; @GetMapping("/getContext")
public String getContext(){
Object bean1 = ctx.getBean("getBeanObj");
return String.format(" ctx 打印bean %s", bean1);
}
启动项目,可以找到日志:
2020-06-27 10:50:16.879 INFO 12272 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2187 ms
调用方法:com.eg.wiener.config.BeanTest@3c74aa0d
说明bean已经被注入Spring容器,默认bean的名称就是其方法名。在浏览器访问函数getContext() 时,会返回bean【getBeanObj】的信息:
ctx 打印bean com.eg.wiener.config.BeanTest@3c74aa0d
和启动时日志打印的bean 信息一致,而且,没有执行方法getBeanObj()。
实现ApplicationContextAware接口
创建一个实体类并实现ApplicationContextAware接口,重写接口内的setApplicationContext方法来完成获取ApplicationContext实例的方法,代码如下所示:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; @Component
public class ApplicationContextProvider implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private ApplicationContext applicationContext; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} /**
* 获取applicationContext
*
* @return
*/
public ApplicationContext getApplicationContext() {
return applicationContext;
} /**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public Object getBean(String name) {
return getApplicationContext().getBean(name);
} /**
* 通过class获取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
} /**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
在拿到ApplicationContext对象实例后就可以获取Bean的注入实例对象,在ApplicationContextProvider类内简单的实现了几个方法来获取指定的Bean实例,也可以添加更多的方法来完成更多的业务逻辑。
这里要注意ApplicationContextProvider类上的@Component注解是不可以去掉的,去掉后Spring就不会自动调用setApplicationContext方法来为我们设置上下文实例。我简单的创建了一个API,以便测试,效果可以达到要求,代码如下:
@Autowired
private ApplicationContextProvider provider; @GetMapping("/getContextProd")
public String getContextProd(){
Object bean = provider.getBean("getBeanObj");
return String.format(" ApplicationContextProvider 打印bean %s", bean);
}
在自定义AutoConfiguration中获取
有时候我们需要实现自定义的Spring starter,并在自定义的AutoConfiguration中使用ApplicationContext,Spring在初始化AutoConfiguration时会自动传入ApplicationContext,这时我们就可以使用下面的方式来获取ApplicationContext:
@Configuration
@EnableFeignClients("com.yidian.data.interfaces.client")
public class FeignAutoConfiguration { FeignAutoConfiguration(ApplicationContext context) {
// 在初始化AutoConfiguration时会自动传入ApplicationContext
doSomething(context);
}}
启动时获取ApplicationContext
在启动Spring Boot项目时,需要调用SpringApplication.run()方法,而run()方法的返回值就是ApplicationContext,我们可以把run()方法返回的ApplicationContext对象保存下来,方便随时使用。下面使用这个返回示例获取Bean示例:
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(WienerApplication.class, args);
Object bean1 = applicationContext.getBean("getBeanObj");
System.out.println(String.format("打印bean1 %s", bean1));
bean1 = applicationContext.getBean("getBeanObj");
System.out.println(String.format("打印bean2 %s", bean1));
}
项目启动后,在日志中可以发现如下三条记录:
调用方法:com.eg.wiener.config.BeanTest@3c74aa0d
打印bean1 com.eg.wiener.config.BeanTest@3c74aa0d
打印bean2 com.eg.wiener.config.BeanTest@3c74aa0d
通过WebApplicationContextUtils获取
Spring提供了一个工具类WebApplicationContextUtils用于获取ApplicationContext对象,它是Spring框架基础包中的类,该方法必须依赖Servlet容器。
WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
测试用例:
关于以上5种获取ApplicationContext上下文对象实例的方式,大家有什么看法,欢迎留言讨论,也希望大家多多点赞,祝各位生活愉快。
Reference
https://www.jianshu.com/p/ef7739a01cb0
获取Spring ApplicationContext容器上下文对象实例的更多相关文章
- Spring ApplicationContext 容器
Spring ApplicationContext 容器 Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文. Application Con ...
- ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题
想要实现的功能:SSH环境下,数据层都交由Spring管理:在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来. 系统初始化类需要实现两个接口: ServletContex ...
- 使用Arthas 获取Spring ApplicationContext还原问题现场
## 背景 最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成Java 代码来实现 ``` 1#!/bin/bash 2URL="http ...
- spring中容器和对象的创建流程
容器和对象的创建流程 1.先创建容器 2.加载配置文件,封装成BeanDefinition 3.调用执行BeanFactoryPostProcessor 准备工作: 准备BeanPostProcess ...
- spring-从普通java类取得注入spring Ioc容器的对象的方案
1.启动服务时通过spring容器的监听器(继承ContextLoaderListener 监听器的方法) public class ListenerSpringContext extends Con ...
- Spring的IoC容器-Spring ApplicationContext容器
Application Context是spring中较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean. 另外,它 ...
- document.querySelector获取不到html标签对象实例的原因
官方给出的HTML中的ID的命名规范: 1.必须以字母 A-Z 或 a-z 开头2.其后的字符:字母(A-Za-z).数字(0-9).连字符("-").下划线("_&qu ...
- 获取spring applicationcontext数据连接connection
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ...
- 【Spring】非Spring IOC容器下获取Spring IOC上下文的环境
前言 在Spring Web项目中,有些特殊的时候需要在非Spring IOC容器下获取Spring IOC容器的上下文环境,比如获取某个bean. 版本说明 声明POM文件,指定需引入的JAR. & ...
- JAVA获取Spring上下文
1. 添加监听 public class SpringContextListener implements ServletContextListener { //获取spring注入的bean对象 p ...
随机推荐
- 质数测试——Fermat素数测试和MillerRabin素数测试
质数测试 今天我来填坑了,之前我在数学基础算法--质数篇这篇文章中提到我要单独讲一下MillerRabin算法,最近已经有许多粉丝在催了,所以我马不停蹄的来出这篇文章了,顺便把Fermat素数测试也讲 ...
- RSA算法详解及相关数学原理解析
RSA算法详解及相关数学原理解析 前言 为了记录自己学习密码学的过程,也是为了便于个人应付相关课程的考核,故写此博客. 本博客总结了怎么用C++手搓一个RSA算法,以及补补欠缺的一些数学知识和可能 ...
- Ubuntu Nvidia driver驱动安装(新)
前言 英伟达更新了安装驱动的方式,更新一下文档 旧文:Ubuntu Nvidia driver驱动安装及卸载 下载官方驱动安装 1.安装驱动前一定要更新软件列表和安装必要软件.依赖(必须) sudo ...
- markdown设置目录、锚点
目录 在编辑时正确使用标题,在段首输入[toc]即可 锚点 创建到命名锚记的链接的过程分为两步: 首先是建立一个跳转的连接: [说明文字](#jump) 然后标记要跳转到什么位置,注意id要与之前(# ...
- http状态码413,并提示Request Entity Too Large的解决办法
使用wordpress的用户经常遇到的问题,就是在后台上传多媒体文件的时候,发现文件大小是有限制的,通常是2M.如图: 如果上传的文件超过2M,服务端返回的状态码会是413,同时提示上传失败.实际上, ...
- ORA-01779: cannot modify a column which maps to a non-key-preserved table
Oracle中试图对一个子查询进行更新时可能会出现ORA-01779错误.该错误的内容为: ORA-01779: cannot modify a column which maps to a non- ...
- datasnap的监督功能【1】-服务端获取客户端连接信息
在服务端获取连接的客户端相关info: TDBXClientInfo = recoed IpAddress : String; ClientPort : String; Protocol : Stri ...
- 我要成为node_modules大师!(一):包管理器选择,依赖关系分析
好家伙 1.npm曾经的一些问题 1. 依赖地狱(Dependency Hell) 嵌套依赖结构:早期版本的 npm 采用嵌套的 node_modules 结构,依赖层级极深,容易导致路径过长问题(尤 ...
- Excel百万数据如何快速导入?
前言 今天要讨论一个让无数人抓狂的话题:如何高效导入百万级Excel数据. 去年有家公司找到我,他们的电商系统遇到一个致命问题:每天需要导入20万条商品数据,但一执行就卡死,最长耗时超过3小时. 更魔 ...
- AoP的相关术语
一.Joinpoint(连接点): 所谓连接点是指那些被拦截到的点.在 spring 中,这些所谓的点指就是方法,因为 spring 只支持方法类型的连接点. 二.Pointcut(切入点): 所谓切 ...