使用 ApplicationContextAware 定义 SpringContextHolder 类
需求:使用 @autowired注入一些对象,但发现不可以直接使用@Autowired,因为方法是static的,要使用该方法当前对象也必须是static,正常情况下@Autowired无法注入静态的bean,于是发现项目中用到了springContextHolder,通过使用
private T t= SpringContextHolder.getBean(T.class);
或者我们在刚开始学习的时候,会使用如下这种方式来获取 Bean。但是这样就会存在一个问题,因为它需要重新装载 spring-core.xml 文件,并实例化上下文bean,如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次。一次是 web容器初始化时启动,另一次是上述代码显示的实例化了一次。这样就产生了冗余。下面就来说说解决方案。
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-core.xml");
T t = (T)appContext.getBean("t");
一、SpringContextHolder 工具类
自定义 SpringContextHolder 工具类,全网统一模板。需要将该类注入到 Spring IOC 中。因此路径很重要。
1 package com.zzx.utils;
2
3 import lombok.extern.slf4j.Slf4j;
4 import org.springframework.beans.BeansException;
5 import org.springframework.beans.factory.DisposableBean;
6 import org.springframework.context.ApplicationContext;
7 import org.springframework.context.ApplicationContextAware;
8
9 /**
10 * @author
11 * @date
12 */
13 @Component
14 @Slf4j
15 public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
16
17 private static ApplicationContext applicationContext = null;
18
19 /**
20 * 取得存储在静态变量中的ApplicationContext.
21 */
22 public static ApplicationContext getApplicationContext() {
23 assertContextInjected();
24 return applicationContext;
25 }
26
27 /**
28 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
29 */
30 public static <T> T getBean(String name) {
31 assertContextInjected();
32 return (T) applicationContext.getBean(name);
33 }
34
35 /**
36 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
37 */
38 public static <T> T getBean(Class<T> requiredType) {
39 assertContextInjected();
40 return applicationContext.getBean(requiredType);
41 }
42
43 /**
44 * 检查ApplicationContext不为空.
45 */
46 private static void assertContextInjected() {
47 if (applicationContext == null) {
48 throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
49 ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
50 }
51 }
52
53 /**
54 * 清除SpringContextHolder中的ApplicationContext为Null.
55 */
56 public static void clearHolder() {
57 log.debug("清除SpringContextHolder中的ApplicationContext:"
58 + applicationContext);
59 applicationContext = null;
60 }
61
62 @Override
63 public void destroy() throws Exception {
64 SpringContextHolder.clearHolder();
65 }
66
67 @Override
68 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
69 if (SpringContextHolder.applicationContext != null) {
70 log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
71 }
72 SpringContextHolder.applicationContext = applicationContext;
73 }
74 }
二、ApplicationContextAware接口
Spring容器初始化的时候会检测容器中的所有Bean,如果发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该 Bean的 setApplicationContextAware()方法,调用该方法时,会将容器本身作为参数传给该方法,该方法将 Spring传入的参数(容器本身)赋给该类对象的 applicationContext实例变量,因此接下来可以通过该applicationContext实例变量来访问容器本身。
使用 ApplicationContextAware 定义 SpringContextHolder 类的更多相关文章
- SpringContextHolder类
1.通常使用SpringContextHolder类获取bean实例: 解决: 如果要在静态方法中调用某一bean的方法,那么该bean必须声明为static的,但正常情况下@Autowired无法注 ...
- 类的继承和多态性-编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 getLegs(),设置动物名称的方法 setKind(),获得动物名称的方法 getKind(),获得动物数量的方法 getCount()。定义Fish类,是Animal类的子类,
编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 ...
- KVC在定义Model类中的妙用
@我们应用程序使用MVC架构的话,对于处理数据类,我们会单独的定义Model类,在里面为要展示的属性进行初始化赋值,一般採用的方法是通过定义相应的属性,挨个赋值.如今我要介绍的就是通过KVC,key- ...
- 定义Java类的数组的问题
定义了一个类: class Student{ private int Id; public int getId() { return Id; } public void setId(int id) { ...
- Java TreeSet集合排序 && 定义一个类实现Comparator接口,覆盖compare方法 && 按照字符串长度排序
package TreeSetTest; import java.util.Iterator; import java.util.TreeSet; import javax.management.Ru ...
- applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.
我用的jeesite框架,在使用定时任务时,出现一些问题,,1.在windows上项目可以在tomcat下,运行2.在linux下项目在tomcatgh下,却出现问题: 15-Dec-2017 15: ...
- JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)
TypeScript方式实现源码 // 特性: // 1. 集合是由一组无序且唯一(即不能重复)的项组成的.这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中. // 2. 也 ...
- JAVA 类的定义(定义一个类,来模拟“学生”)
package Code413;/*定义一个类,来模拟“学生”属性 (是什么) 姓名 年龄行为(能做什么) 吃饭 睡觉 学习对应到Java的类当中 成员变量(属性) String nanme; //姓 ...
- 【C++ Primer 第15章】定义派生类析构函数
学习资料 • 基类和派生类析构函数执行顺序 定义派生类析构函数 [注意]定义一个对象时先调用基类的构造函数.然后调用派生类的构造函数:析构的时候恰好相反:先调用派生类的析构函数.然后调用基类的析构函数 ...
- 【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符
学习资料 • 派生类的赋值运算符/赋值构造函数也必须处理它的基类成员的赋值 • C++ 基类构造函数带参数的继承方式及派生类的初始化 定义拷贝构造函数 [注意]对派生类进行拷贝构造时,如果想让基类的成 ...
随机推荐
- 梯度下降算法VS正规方程算法
梯度下降算法的大家族: ①批量梯度下降:有N个样本,求梯度的时候就用了N个样本的梯度数据 优点:准确 缺点:速度慢 ②随机梯度下降:和批量梯度下降算法原理相似,区别在于求梯度时没有用所有的N歌样本数据 ...
- Linux 使用ssh服务管理远程主机
配置网络服务 配置网卡的4种方法: 创建网络会话 RHEL和CentOS系统默认使用NetworkManager来提供网络服务,这是一种动态管理网络配置的守护进程,能够让网络设备保持连接状态.可以使用 ...
- Jmeter五、jmeter中的逻辑控制器
1.simple controller 提供一个块的结构和控制.更方便,更清晰. 嵌套其他的controller 2.loop controller 循环控制器 控制循环次数 可以使用变量 ${__t ...
- C 语言 scanf 格式化输入函数
C 语言 scanf 格式化输入函数 函数概要 scanf 函数从标准输入流中读取格式化字符串.与 printf 格式化输出函数相反,scanf 函数是格式化输入函数. 函数原型 #include & ...
- 《动态规划学习笔记》Day1-数字金字塔
这是一道经典的洛谷水题了,虽说是IOI的(但毕竟很古老了),然后我提供一下我的思路吧. 链接洛谷题面:https://www.luogu.com.cn/problem/P1216 首先,金字塔的输入规 ...
- tp 获取器的使用中应该怎么append 自定义数据
$data = model('organization_area')->getListByNoPage($where, 'create_time asc');foreach ($data as ...
- 5ppm高精度自动同步标准化考场时钟系统
自动同步标准化考场时钟系统------专业LED时钟厂家![点击进入] 学校考场医院车站GPS/NTP网络校时之组联网对时精度达5ppm原理剖析. 时间精度是根据各个用户所要求对LE ...
- Spring系列之类路径扫描和注册组件-8
目录 类路径扫描和注册组件 `@Component` 使用元注释和组合注释 自动检测类和注册 Bean 定义 使用过滤器自定义扫描 在组件中定义 Bean 元数据 命名自动检测到的组件 为自动检测的组 ...
- windows 切换路径
- Linux用户管理2
passwd给用户修改密码 用户自己给自己设置密码直接passwd root用户给普通用户设置密码passwd 用户名 --stdin从标准输入获取信息 echo "1" | pa ...