`

使用静态变量缓存ApplicationContext

阅读更多

第一种方法:

1: 声明如下类:

 

package com.rayoo.tech.core.utils.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext.
 * 
 */
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

	private static ApplicationContext applicationContext = null;

	private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);

	/**
	 * 实现ApplicationContextAware接口, 注入Context到静态变量中.
	 */
	public void setApplicationContext(ApplicationContext applicationContext) {
		logger.debug("注入ApplicationContext到SpringContextHolder:" + applicationContext);

		if (SpringContextHolder.applicationContext != null) {
			logger.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
		}

		SpringContextHolder.applicationContext = applicationContext; //NOSONAR
	}

	/**
	 * 实现DisposableBean接口,在Context关闭时清理静态变量.
	 */
	@Override
	public void destroy() throws Exception {
		SpringContextHolder.clear();
	}

	/**
	 * 取得存储在静态变量中的ApplicationContext.
	 */
	public static ApplicationContext getApplicationContext() {
		assertContextInjected();
		return applicationContext;
	}

	/**
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		assertContextInjected();
		return (T) applicationContext.getBean(name);
	}

	/**
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	public static <T> T getBean(Class<T> requiredType) {
		assertContextInjected();
		return applicationContext.getBean(requiredType);
	}

	/**
	 * 清除SpringContextHolder中的ApplicationContext为Null.
	 */
	public static void clear() {
		logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
		applicationContext = null;
	}

	/**
	 * 检查ApplicationContext不为空.
	 */
	private static void assertContextInjected() {
		if (applicationContext == null) {
			throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
		}
	}
}

 

 2:

在applicationContext.xml中定义如下:

 

<!-- 使用 静态变量缓存applicationContext -->
<bean class="com.rayoo.tech.core.utils.spring.SpringContextHolder" lazy-init="false"/>

 

 

第二种方法:

 

1:声明类如下:

 

package com.rayoo.tech.listener.cache;

import javax.servlet.ServletContextEvent;

import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class CacheListener extends ContextLoaderListener {

	private static WebApplicationContext context = null;

	@Override
	public void contextInitialized(ServletContextEvent event) {
		CacheListener.context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
	}
}
  

2: 在web.xml中定义如下:

 

<listener>
	<listener-class>com.rayoo.tech.listener.CacheListener</listener-class>
</listener>
分享到:
评论

相关推荐

    Android应用程序如何避免内存泄漏

    长时间持有Activity的引用,如在静态变量中存储,会导致Activity无法正常销毁,进而引发内存泄漏。例如,将Context传给静态对象或在非静态内部类中使用Activity作为上下文,都会增加泄漏的风险。在上述代码示例中,...

    Android Volley,AsyncTask,FinalHttp 请求对比内存泄漏

    4. **避免静态变量持有Activity引用**:静态变量的生命周期贯穿整个应用程序,如果持有Activity引用,会导致Activity无法被回收。 5. **使用Application Context**:在非Activity上下文中,如Service或...

    java知识储备.docx

    - **线程共享**:堆(存储对象实例),方法区(存储类信息、常量、静态变量)。 - **线程私有**:程序计数器(记录执行的指令地址),JVM栈(存储方法调用信息),本地方法栈(为JNI方法服务)。 这些知识涵盖了...

    2024跳槽涨薪必备精选面试题.pdf

    - 静态变量、方法区中的类信息、栈帧中的本地变量表等。 ### 框架相关 #### 16. Spring中的Bean创建的生命周期 - Bean的生命周期包括初始化前、初始化后、销毁前等阶段,可以通过接口或注解自定义Bean的生命周期...

    Android Application类的详细介绍

    - 生命周期管理:继承Application的类,其生命周期随应用程序的销毁而结束,避免了静态类或静态变量可能导致的数据残留问题。 - 初始化操作:在Application的onCreate()方法中可以进行全局的初始化操作,确保所有...

    云析学院-字节跳动2020第1季度面试题.pdf

    GC Roots包括静态变量、线程栈、JNI引用等。 9. **Volatile**:确保多线程环境下的可见性和有序性,防止指令重排序。 10. **synchronized**:用于控制并发,保证线程安全,可修饰方法和代码块。 11. **并发包中的...

    freemarker实例下载

    本实例“freemarker生成静态html”提供了一个具体的使用Freemarker进行静态页面生成的演示。下载后的压缩包内包含了必要的框架和配置文件,方便用户快速理解和部署。"springdemo"这个文件名暗示了该实例可能基于...

    2018安卓面试题大全

    - **内存泄漏**:常见于静态变量持有Activity引用、Handler持有外部对象引用等情况。 7. **四大组件及其生命周期** - **Activity、Service、BroadcastReceiver、ContentProvider**各自有不同的生命周期方法,理解...

    Java Web程序设计教程

    11.5.2使用applicationcontext 238 11.6项目实战——spring问候程序 239 本章小结 241 课后练习 241 第12章springaop 242 12.1aop基础 242 12.1.1aop与oop的比较 242 12.1.2aop的核心概念 243 12.1.3java...

    MemoryAnalyze

    - Spring框架中的ApplicationContext未关闭,导致Bean实例无法被回收。 5. **优化建议** - 使用WeakReference或SoftReference,让对象能在适当的时候被垃圾收集器回收。 - 及时关闭数据库连接、网络连接等资源。...

    字节跳动面试题.pdf

    7. **ApplicationContext的初始化过程**:Spring的ApplicationContext在初始化时会加载配置文件,创建Bean实例,处理依赖注入,并在检测到循环依赖时使用三级缓存策略解决。 8. **GC收集器**:Java垃圾回收使用多种...

    (2024)跳槽涨薪必备精选面试题.pdf

    - 方法区(Metaspace):存放类的信息、常量、静态变量等。 - 堆(Heap):所有线程共享的区域,用于存放对象实例。 2. **JVM中哪些可以作为gc root** - 方法区中的类静态属性引用的对象。 - 方法区中的常量...

    java程序员面试大纲错过了金三银四你还要错过2018吗.docx

    14. **Spring Controller并发安全**:通过线程安全的设计原则,如避免在控制器中使用实例变量,使用`ThreadLocal`等方法确保控制器的线程安全。 #### 五、Netty框架 1. **BIO、NIO和AIO**:阻塞I/O(BIO)、非阻塞...

    讲解JAVA设计模式中的单例模式

    这种模式通常用于创建那些昂贵的对象,比如数据库连接、线程池或者缓存服务等。 ### 实现方式 单例模式有多种实现方式,主要包括: 1. **饿汉式(静态常量)**:在类加载时就完成了初始化,所以没有线程安全问题,...

    跳槽涨薪涨薪必备精选面试题.pdf

    14. JVM中的线程共享区包括堆内存和方法区,GC Roots包括全局静态变量、JNI引用、系统运行时数据区等。 15. 类加载器的双亲委派模型:自定义类加载器先委托给父加载器,直至Bootstrap ClassLoader,找不到再由...

    Java面试可能问的问题.docx

    8. **Redis数据结构**:Redis支持多种数据结构,如String、Hash、List、Set、Sorted Set,以及更复杂的数据结构如HyperLogLog、Bitmaps等,适用于缓存、计数、发布订阅等多种场景。 9. **反射**:Java反射机制允许...

    Spring-Reference_zh_CN(Spring中文参考手册)

    8.3.1. Context管理和缓存 8.3.2. 测试fixture的依赖注入 8.3.3. 事务管理 8.3.4. 方便的变量 8.3.5. 示例 8.3.6. 运行集成测试 8.4. 更多资源 II. 中间层数据访问 9. 事务管理 9.1. 简介 9.2. 动机 9.3. 关键抽象 ...

    JAVA面试八股文.pptx

    - **线程共享区和GC Roots**: 共享区包括堆和方法区,GC Roots包括虚拟机栈中的局部变量表、静态字段、常量池引用等。 - **JVM问题排查**: 使用`jstack`查看线程状态,`jmap`分析内存,`jconsole`或`VisualVM`监控...

    面试题问题合集.docx

    - **方法区**:方法区(也称永久代)是唯一不会发生内存溢出的区域,因为它主要存放的是类的信息、常量、静态变量等数据,这些数据在类加载阶段就已经确定。 #### 垃圾回收机制 JVM 的垃圾回收机制主要是指自动...

    JAVA面试题2019

    5. **LinkedHashMap**:使用场景和特点,如有序性和缓存机制。 6. **异常处理**:异常的分类、捕获和处理机制。 7. **线程同步**:`wait`与`sleeep`的区别,如是否释放锁资源等。 ### Java并发 #### 关键知识点: ...

Global site tag (gtag.js) - Google Analytics