spring中的DisposableBean和InitializingBean,ApplicationContextAware的用法
在spring容器初始化bean和销毁bean的以前的操作有很多种,
目前我知道的有:在xml中定义的时候用init-method和destory-method,还有一种就是定义bean的时候实现DisposableBean和InitializingBean 这两个接口,打开InitializingBean 的源码:
public interface InitializingBean { /** * Invoked by a BeanFactory after it has set all bean properties supplied * (and satisfied BeanFactoryAware and ApplicationContextAware). * <p>This method allows the bean instance to perform initialization only * possible when all bean properties have been set and to throw an * exception in the event of misconfiguration. * @throws Exception in the event of misconfiguration (such * as failure to set an essential property) or if initialization fails. */ void afterPropertiesSet() throws Exception; }
根据注解很清楚的可以看出,afterPropertiesSet()表示在资源加载完以后,初始化bean之前执行的方法,我猜想spring底层应该会在初始化bean的时候,应该会使用(bean instanceof InitializingBean)判断是不是实现了这个接口,其实在很多框架中都是这么干的,但是因为没研究过spring源码,暂且还不知道底层原理。这样我们就可以在初始化的时候,做一些自己想要做的事了。
同理,DisposableBean就是在一个bean被销毁的时候,spring容器会帮你自动执行这个方法,估计底层原理也是差不多的,对于一些使用完之后需要释放资源的bean,我们都会实现这个接口,或者是配置destory-method方法。源码也基本是相似的,只是把afterPropertiesSet改为destroy。
ApplicationContextAware
其实我们看到---Aware就知道是干嘛用的了,就是属性注入的,但是这个ApplicationContextAware的不同地方在于,实现了这个接口的bean,当spring容器初始化的时候,会自动的将ApplicationContext注入进来:
import org.apache.commons.lang.Validate; import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; /** * applicationContext静态化 * 使用了ApplicationContextAware接口的类,如果受spring容器管理的 * 话,那么就会自动的调用ApplicationContextAware中的setApplicationContext方法 * @author Hotusm * */ @Service @Lazy(false) public class SpringContextHolder implements ApplicationContextAware,DisposableBean{ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextHolder.applicationContext=applicationContext; } //清空applicationContext 设置其为null @Override public void destroy() throws Exception { SpringContextHolder.clearHolder(); } //获得applicationContext public static ApplicationContext getApplicationContext() { //assertContextInjected(); return applicationContext; } public static void clearHolder(){ applicationContext=null; } //获取Bean public static <T> T getBean(Class<T> requiredType){ //assertContextInjected(); return (T) getApplicationContext().getBean(requiredType); } @SuppressWarnings("unchecked") public static <T> T getBean(String name){ assertContextInjected(); return (T) getApplicationContext().getBean(name); } //判断application是否为空 public static void assertContextInjected(){ Validate.isTrue(applicationContext==null, "application未注入 ,请在springContext.xml中注入SpringHolder!"); } }
因为我们在做开发的时候,并不是说在每一个地方都能将属性注入到我们想要的地方去的,比如在Utils使用到dao,我们就不能直接注入了,这个时候就是我们需要封装springContext的时候了,而ApplicationContextAware就起了关键性的作用。
3:还有一种是注解的用法:
在指定方法上加上@PostConstruct或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了