需求:使用 @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 类的更多相关文章

  1. SpringContextHolder类

    1.通常使用SpringContextHolder类获取bean实例: 解决: 如果要在静态方法中调用某一bean的方法,那么该bean必须声明为static的,但正常情况下@Autowired无法注 ...

  2. 类的继承和多态性-编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 getLegs(),设置动物名称的方法 setKind(),获得动物名称的方法 getKind(),获得动物数量的方法 getCount()。定义Fish类,是Animal类的子类,

    编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 ...

  3. KVC在定义Model类中的妙用

    @我们应用程序使用MVC架构的话,对于处理数据类,我们会单独的定义Model类,在里面为要展示的属性进行初始化赋值,一般採用的方法是通过定义相应的属性,挨个赋值.如今我要介绍的就是通过KVC,key- ...

  4. 定义Java类的数组的问题

    定义了一个类: class Student{ private int Id; public int getId() { return Id; } public void setId(int id) { ...

  5. Java TreeSet集合排序 && 定义一个类实现Comparator接口,覆盖compare方法 && 按照字符串长度排序

    package TreeSetTest; import java.util.Iterator; import java.util.TreeSet; import javax.management.Ru ...

  6. applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.

    我用的jeesite框架,在使用定时任务时,出现一些问题,,1.在windows上项目可以在tomcat下,运行2.在linux下项目在tomcatgh下,却出现问题: 15-Dec-2017 15: ...

  7. JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)

    TypeScript方式实现源码 // 特性: // 1. 集合是由一组无序且唯一(即不能重复)的项组成的.这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中. // 2. 也 ...

  8. JAVA 类的定义(定义一个类,来模拟“学生”)

    package Code413;/*定义一个类,来模拟“学生”属性 (是什么) 姓名 年龄行为(能做什么) 吃饭 睡觉 学习对应到Java的类当中 成员变量(属性) String nanme; //姓 ...

  9. 【C++ Primer 第15章】定义派生类析构函数

    学习资料 • 基类和派生类析构函数执行顺序 定义派生类析构函数 [注意]定义一个对象时先调用基类的构造函数.然后调用派生类的构造函数:析构的时候恰好相反:先调用派生类的析构函数.然后调用基类的析构函数 ...

  10. 【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符

    学习资料 • 派生类的赋值运算符/赋值构造函数也必须处理它的基类成员的赋值 • C++ 基类构造函数带参数的继承方式及派生类的初始化 定义拷贝构造函数 [注意]对派生类进行拷贝构造时,如果想让基类的成 ...

随机推荐

  1. SourceInsight4破解

    2017/10/18 更新 1. 安装原版软件:Source Insight Version 4.0.0092 -  March 20, 2018 2. 下载激活程序:sourceinsight_40 ...

  2. idea中的快捷键

  3. <小李飞刀>系列 随笔

    1.多情剑客无情剑 古龙的作品在电视上只看过电影版的陆小凤传奇,对古龙的作品也没有过系统的了解,初读时听到了李寻欢的名字,突然感觉可惜.觉得如此早就读到这种级别的小说有些暴殄天物,不过也算是以白纸状态 ...

  4. elementUI el-tree报错 Cannot read property ‘setCheckedKeys’ of undefined"

    给树节点赋值时,执行下面代码会报错,原因是:DOM元素未加载完成. 以下为错误写法. handleRowClick(row) { this.$refs.tree.setCheckedKeys(ids) ...

  5. java 操作 zookeeper

    pom.xml<dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</a ...

  6. ext表单合并行

    在js里加入方法 /*** 合并Grid的数据列* @param grid {Ext.Grid.Panel} 需要合并的Grid* @param colIndexArray {Array} 需要合并列 ...

  7. day01学习小记

    # Markdown学习 ## 标题 ### 三级标题 #### 四级标题 ## 字体 Hellow,World! Hellow,world hellow,world! hellow,world ## ...

  8. 解决VSCode无法显示Unity代码提示和源代码

    1,先删除项目目录下的配置文件,也可以理解为除文件夹外的其他文件 2,先把vscode选中,下拉框中没有vscode的找到文件就可以导进来再选中.然后红框里的不要勾选,因为我是这么做的,你也可以试着勾 ...

  9. Qt打印不同颜色

    qCritical()<<"\033[47;31m"<<"打印的字符串"<<"\033[m"; \033 ...

  10. JavaScript基础学习之二

    目录 JavaScript HTML DOM事件 事件触发1 事件触发2 addEventListener() 事件冒泡或事件捕获? 事件委托 removeEventListener() 方法 事件对 ...