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);

测试用例:

@GetMapping("/getMyBean")
public String getMyBean(HttpServletRequest request)throws Exception{
  ServletContext sc = request.getSession().getServletContext();
  ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
  BeanTest bean = ac.getBean("getBeanObj");
  return String.format(" 当前bean是 %s", bean);
}

关于以上5种获取ApplicationContext上下文对象实例的方式,大家有什么看法,欢迎留言讨论,也希望大家多多点赞,祝各位生活愉快。

Reference

https://www.jianshu.com/p/ef7739a01cb0

获取Spring ApplicationContext容器上下文对象实例的更多相关文章

  1. Spring ApplicationContext 容器

    Spring ApplicationContext 容器 Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文. Application Con ...

  2. ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题

    想要实现的功能:SSH环境下,数据层都交由Spring管理:在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来. 系统初始化类需要实现两个接口: ServletContex ...

  3. 使用Arthas 获取Spring ApplicationContext还原问题现场

    ## 背景 最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成Java 代码来实现 ``` 1#!/bin/bash 2URL="http ...

  4. spring中容器和对象的创建流程

    容器和对象的创建流程 1.先创建容器 2.加载配置文件,封装成BeanDefinition 3.调用执行BeanFactoryPostProcessor 准备工作: 准备BeanPostProcess ...

  5. spring-从普通java类取得注入spring Ioc容器的对象的方案

    1.启动服务时通过spring容器的监听器(继承ContextLoaderListener 监听器的方法) public class ListenerSpringContext extends Con ...

  6. Spring的IoC容器-Spring ApplicationContext容器

    Application Context是spring中较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean. 另外,它 ...

  7. document.querySelector获取不到html标签对象实例的原因

    官方给出的HTML中的ID的命名规范: 1.必须以字母 A-Z 或 a-z 开头2.其后的字符:字母(A-Za-z).数字(0-9).连字符("-").下划线("_&qu ...

  8. 获取spring applicationcontext数据连接connection

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ...

  9. 【Spring】非Spring IOC容器下获取Spring IOC上下文的环境

    前言 在Spring Web项目中,有些特殊的时候需要在非Spring IOC容器下获取Spring IOC容器的上下文环境,比如获取某个bean. 版本说明 声明POM文件,指定需引入的JAR. & ...

  10. JAVA获取Spring上下文

    1. 添加监听 public class SpringContextListener implements ServletContextListener { //获取spring注入的bean对象 p ...

随机推荐

  1. 记录网站从http升级到https遇到的问题

    1.静态资源(js.css)引入问题 在使用http是之后,如果你的站点出现引入外部的js.css等,你需要修改你的资源引入,cdn的话可以写成://cdn.bootscdn.com/jquery.m ...

  2. Golang入门:Linux上的go语言安装与配置

    Tips:本文以本文撰写时的 Go 语言最新版本,也就是 go.1.19.2 版本为例. Linux 发行版本使用 Ubuntu 22.04.1 LTS 为例来做演示. 安装 C 工具 Go 的工具链 ...

  3. 如何在 Github 上获得 1000 star?

    作为程序员,Github 是第一个绕不开的网站.我们每天都在上面享受着开源带来的便利,我相信很多同学也想自己做一个开源项目,从而获得大家的关注.然而,理想很丰满,现实却是开发了很久的项目仍然无人问津. ...

  4. pagehelper的失效问题

    pagehelper是常用的分页插件,代码中常用到,使用简便且对代码侵入性较小,很多人都喜欢使用.不过有时会遇到分页失败问题,输出结果没有分页,日志输出sql语句没有分页关键字及分页参数,目测是pag ...

  5. 深入理解Hadoop读书笔记-4

    背景 公司的物流业务系统目前实现了使用storm集群进行过门事件的实时计算处理,但是还有一个需求,我们需要存储每个标签上传的每条明细数据,然后进行定期的标签报表统计,这个是目前的实时计算框架无法满足的 ...

  6. 【SpringCloud】版本选择

    版本选择 从2.2.x和H版开始说起 SpringBoot版本选择 git源码地址 https:github.com/spring-projects/spring-boot/releases/ Spr ...

  7. Docker 初始镜像 scratch

    初识 scratch 有那么一天,我们在这里邂逅了镜像scratch... 先来搜索下这个镜像 docker search scratch NAME DESCRIPTION STARS OFFICIA ...

  8. CoreOS 重启策略

    对于已经启动了的 CoreOS 集群,可以通过编辑/etc/coreos/update.conf文件来修改重启策略. 重启策略有以下4种: best-effort(默认):如果 etcd 运行正常则相 ...

  9. 《机器人SLAM导航核心技术与实战》先导课:SLAM的应用价值与技术难点

    <机器人SLAM导航核心技术与实战>先导课:SLAM的应用价值与技术难点 视频讲解 [先导课]3.SLAM的应用价值与技术难点-视频讲解 [先导课]3.1.SLAM的应用价值与技术难点-S ...

  10. 配置QtJambi编译环境

    所有代码都是以C++ GUI Qt 4编程(第二版)为准,只是重新用Java + QtJambi重写了. 当前编译IDE是intellij idea 2024, 系统win 11 LTSC.需要配置的 ...