https://blog.csdn.net/weixin_38361347/article/details/89304414

https://www.jianshu.com/p/9ea13b00b1d9

https://blog.csdn.net/zsw12013/article/details/51701671

____________________________________________________________________________________________________________________________

SpringBoot中获取ApplicationContext的三种方式
ApplicationContext是什么?

简单来说就是Spring中的容器,可以用来获取容器中的各种bean组件,注册监听事件,加载资源文件等功能。

Application Context获取的几种方式

1 直接使用Autowired注入
@Component
public class Book1 {

@Autowired
private ApplicationContext applicationContext;

public void show (){
System.out.println(applicationContext.getClass());
}
}

2 利用 spring4.3 的新特性
使用spring4.3新特性但是存在一定的局限性,必须满足以下两点:

1 构造函数只能有一个,如果有多个,就必须有一个无参数的构造函数,此时,spring会调用无参的构造函数

2 构造函数的参数,必须在spring容器中存在

@Component
public class Book2 {

private ApplicationContext applicationContext;

public Book2(ApplicationContext applicationContext){
System.out.println(applicationContext.getClass());
this.applicationContext=applicationContext;
}

public void show (){
System.out.println(applicationContext.getClass());
}

}

3 实现spring提供的接口 ApplicationContextAware
spring 在bean 初始化后会判断是不是ApplicationContextAware的子类,调用setApplicationContext()方法, 会将容器中ApplicationContext传入进去

@Component
public class Book3 implements ApplicationContextAware {

private ApplicationContext applicationContext;

public void show (){
System.out.println(applicationContext.getClass());
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

结果获取三次:

class org.springframework.context.annotation.AnnotationConfigApplicationContext
class org.springframework.context.annotation.AnnotationConfigApplicationContext
class org.springframework.context.annotation.AnnotationConfigApplicationContext

---------------------
版权声明:本文为CSDN博主「A 是小阿怪啊」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38361347/article/details/89304414

___________________________________________________________________________________________________

在项目中我们经常会碰到这么一个场景,某些普通的JAVA类,这个类并没有被Spring所管理,但是我们需要再这个类中调用到某些方法,是ioc容器中对象的方法,我们没法再普通的JAVA类中通过spring的注解@Autowired和@Resource注入对象,在这种场景下,我么就可以使用方法获取到ioc中的实例,并使用其方法。


在项目中获取获取beand方法多种多样,这里大致列举几种

  1. 在初始化时保存ApplicationContext对象
  2. 通过Spring提供的utils类获取ApplicationContext对象
  3. 继承自抽象类ApplicationObjectSuppor
  4. 继承自抽象类WebApplicationObjectSupport
  5. 实现接口ApplicationContextAware
  6. 通过Spring提供的ContextLoader

如果想了解每一种的用法可以参考此篇博文:https://blog.csdn.net/zsw12013/article/details/51701671

本片博文只具体展示一种配置,也是自身项目中遇到的获取方式,就是第五中方式实现接口ApplicationContextAware,这种获取方式适用于大多数项目内业务接口不方便注入的时候的调用


实现ApplicationContextAware接口的类必须要被spring所管理,要么在代码中标记为ioc组件(类的路径必须要被spring扫描到),要么在applicationContext.xml spring的配置文件配置为bean,不然会获取不到上下文对象,调用这个类的普通JAVA类是没有限制的。

工具类代码

package com.wzh.config.utils;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; /**
* <从Spring IOC容器中获取Bean对象> <功能详细描述>
* @author wzh
* @version 2018-09-23 19:32
* @see [相关类/方法] (可选)
**/
@Component("beanHeader")
public class BeanHeader implements ApplicationContextAware
{ private static Logger log = Logger.getLogger(BeanHeader.class); // 上下文对象
private static ApplicationContext applicationContext; /**
* 实现ApplicationContextAware接口的回调方法,注入上下文对象
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
BeanHeader.applicationContext = applicationContext;
} /**
* 获取上下文对象
* @return applicationContext
*/
public static ApplicationContext getApplicationContext()
{
return applicationContext;
} /**
* 判断上下文对象是否为空
*
* @return
*/
public static boolean checkapplicationContext()
{
boolean flag = getApplicationContext() != null;
if (!flag)
{
log.error("applicaitonContext未注入,实现ApplicationContextAware的类必须被spring管理");
}
return flag;
} /**
* 根据name获取bean
* @param name
* @param <T>
* @return
*/
public static <T> T getBean(String name)
{
if (checkapplicationContext())
{
return (T)getApplicationContext().getBean(name);
}
else
{
return null;
}
} /**
* 根据class 获取bean
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz)
{
if (checkapplicationContext())
{
return getApplicationContext().getBean(clazz);
}
else
{
return null;
}
} /**
* 根据name,以及Clazz返回指定的Bean
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz)
{
if (checkapplicationContext())
{
return getApplicationContext().getBean(name, clazz);
}
else
{
return null;
}
}
}

下面我们来测试一下

首先是一个简单的service 被spring管理

package com.wzh.demo.service.impl;

import com.wzh.demo.service.SystemOutService;
import org.springframework.stereotype.Service; /**
* <简单的输出测试,没有功能>
* <功能详细描述>
* @author wzh
* @version 2018-09-23 23:11
* @see [相关类/方法] (可选)
**/
@Service("systemOutService")
public class SystemOutServiceImp implements SystemOutService{ @Override
public void sysout() {
System.out.println("调用systemOutService 成功");
}
}

junit 测试基类

package base;

import com.wzh.application.Application;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration; /**
* junit 测试基类
*/
//SpringJUnit支持,由此引入Spring-Test框架支持!
@RunWith(SpringJUnit4ClassRunner.class)
//启动类,启用随即端口
@SpringBootTest(classes = Application.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//web项目支持,webEnvironment属性使用后不能用webAppconfiguration注解
//@WebAppConfiguration
public class BaseJunit { @Test
public void runJunitTest()
{
System.out.println("Junit 启动测试");
}
}

junit 测试类

import base.BaseJunit;
import com.wzh.config.utils.BeanHeader;
import com.wzh.demo.service.SystemOutService;
import org.junit.Test; /**
* <一句话功能描述>
* <功能详细描述>
* @author wzh
* @version 2018-09-23 23:18
* @see [相关类/方法] (可选)
**/
public class BeanHeaderTest extends BaseJunit { @Test
public void testBeanHeader()
{
SystemOutService service = BeanHeader.getBean("systemOutService");
service.sysout();
}
}

运行方法,控制台输出

 
image.png

_____________________________________________________________________________________________

获取ApplicationContext进而获取Ioc实例方法

 

在正常情况下 spring管理的类可直接调用Ioc容器中的实例,但在一些特殊情况下(例如拦截器中获取dao实例),Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,

spring提供了ApplicationContextAware接口,容器会自动检索实现该接口的类进行spring上下文注入

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; @Slf4j
@Component
public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
log.info("ApplicationContext config success");
} // 获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
} // 通过name获取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
} // 通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
} // 通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
} }

使用例子,拦截器中获取 redis缓存实例

public class AccessInterceptor implements HandlerInterceptor {

    private IStringCacheService cache = SpringUtil.getBean(IStringCacheService.class);

    ......
......
......
......
......
}

Spring Spring boot 获取IOC中的bean,ApplicationContext的更多相关文章

  1. Spring入门2. IoC中装配Bean

    Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...

  2. Spring:获取容器中的Bean

    某些情况下我们要获取 IOC 容器中指定注解.类型.名字的 Bean 要获取 IOC 容器中指定条件的 Bean 可以通过 ApplicationContext 相应的方法 @Autowired pr ...

  3. 在Bean中获取spring 容器 并通过容器获取容器中其他bean

    spring 提供了Awear 接口去 让bean 能感受到外界的环境.Awear 接口有很多实现,常用的有 ApplicationContextAware (可以通过实现这个接口去获取Applica ...

  4. Spring MVC如何获取请求中的参数

    目录 一.获取URL中路径参数 1.1 @PathVariable 注解 1.2 @PathParam 注解 二.获取请求参数: 2.1 GET请求 2.1.1 获取请求中的单个参数:@Request ...

  5. spring中获取容器中的Bean为什么前转成接口而不是实现类

    简单介绍一下上下文,userService是服务层接口有一个save方法,userServiceImpl是该接口的实现类重写了save方法. applicationContext.xml如图: 后台代 ...

  6. 【spring mvc】application context中【bean】的生命周期

    生命周期过程 主要分为四部分: 一.实例化 1. 当调用者通过 getBean( name )向 容器寻找Bean 时,如果容器注册了org.springframework.beans.factory ...

  7. 从零开始学spring源码之ioc预热:bean的拓展和beanProcessor注册

    上篇聊完了bean的解析,说起来做的事情很简单,把xml文件里面配置的标签全部解析到spring容器里面,但是spring做的时候,花了那么大代价去做,后面看看到底值不值得呢. 接下来看看prepar ...

  8. Spring容器 从XML 文件中读取bean的定义,并实例化bean?

    解释Spring框架中bean的生命周期. Spring根据bean的定义填充所有的属性. 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanN ...

  9. spring 普通类获取四大作用域request、applicationContext、session、page

    几乎所有web应用容器都提供了四种类似Map的结构:application session request page,Jsp或者Servlet通过向着这四个对象放入数据,从而实现Jsp和Servlet ...

随机推荐

  1. c博客作业01--顺序分支结构

    0.展示PTA总分 1.本章学习总结 1.1 学习内容总结 1.运算符需注意的要点 '/'的左右两边如果均为整型数,其结果也为整型:'%'的左右两边只能为整型数: 优先级:逻辑运算符<关系运算符 ...

  2. QML学习(一)——<简要概念知识点>

    转载:https://www.cnblogs.com/dengyg0710/p/10644936.html 1.一个 QML 文档有且只有一个根元素. 2.QML 元素名后所有内容使用 {} 包围起来 ...

  3. Java串口通信--------基于RXTX (附带资源地址)

    最近帮老师做了一个小项目,一个牧场公司想用传感器收集一些环境信息,记录到数据库里去,然后加以分析查看.这里面和传感器通信用到了串口通信,我也是接触了一下,把用到的东西分享出来. 准备工作: RXTX: ...

  4. GIT 安装和升级

    git 安装: http://git-scm.com/download/mac git 升级: $ git clone git://git.kernel.org/pub/scm/git/git.git

  5. Java 12 骚操作, String居然还能这样玩!

    Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 栈长之前在Java技术栈微信公众号分享过<Java 11 已发布,String 还能这样玩!> ...

  6. SQL优化:一些简单的又实用的SQL优化方案【转】

    面试过程中,面试官有极高的频率会问道数据库的优化,SQL语句的优化,网上关于SQL优化的教程很多,但是鱼目混杂,显得有些杂乱不堪.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请 ...

  7. 工具系列 | VScode Remote 远程开发与调试(告别SSH)

    简介 最近VScode发布了远程编程与调试的插件Remote Development,使用这个插件可以在很多情况下代替vim直接远程修改与调试服务器上的代码,同时具备代码高亮与补全功能,就和在本地使用 ...

  8. GIS地理处理脚本案例教程——批量栅格分割-批量栅格裁剪-批量栅格掩膜-深度学习样本批量提取

    GIS地理处理脚本案例教程--批量栅格分割-批量栅格裁剪-批量栅格掩膜-深度学习样本批量提取 商务合作,科技咨询,版权转让:向日葵,135-4855_4328,xiexiaokui#qq.com 关键 ...

  9. Intellij idea 告警:'while' statement cannot complete without throwing an exception

    有时候这个告警是多余的,例如我们手写的监控线程. 如果有消除告警强迫症.在线程的执行方法上加入注解. @SuppressWarnings("InfiniteLoopStatement&quo ...

  10. word/wps 制作下拉列表

    准备: 1.数据页 2.项目名称sheet 3.问题类型sheet 开始制作: 数据 --- 有效性 --- 允许“序列” --- 来源 -- 其他sheet页“单元格”选择范围 回车.确定 即可