关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:

第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作

第二种是:通过在xml中定义init-method 和destory-method方法

第三种是:通过bean实现InitializingBean和 DisposableBean接口

例如:TransactionTemplate实现InitializingBean接口,主要是判断transactionManager是否已经初始化,如果没有则抛出异常。源码如下:

  1. public void afterPropertiesSet() {
  2. if (this.transactionManager == null) {
  3. throw new IllegalArgumentException("Property 'transactionManager' is required");
  4. }
  5. }

目前我知道的有:在xml中定义的时候用init-method和destory-method,还有一种就是定义bean的时候实现DisposableBean和InitializingBean 这两个接口,打开InitializingBean 的源码:

  1. public interface InitializingBean {
  2.  
  3. /**
  4. * Invoked by a BeanFactory after it has set all bean properties supplied
  5. * (and satisfied BeanFactoryAware and ApplicationContextAware).
  6. * <p>This method allows the bean instance to perform initialization only
  7. * possible when all bean properties have been set and to throw an
  8. * exception in the event of misconfiguration.
  9. * @throws Exception in the event of misconfiguration (such
  10. * as failure to set an essential property) or if initialization fails.
  11. */
  12. void afterPropertiesSet() throws Exception;
  13.  
  14. }

根据注解很清楚的可以看出,afterPropertiesSet()表示在资源加载完以后,初始化bean之前执行的方法,我猜想spring底层应该会在初始化bean的时候,应该会使用(bean instanceof InitializingBean)判断是不是实现了这个接口,其实在很多框架中都是这么干的,但是因为没研究过spring源码,暂且还不知道底层原理。这样我们就可以在初始化的时候,做一些自己想要做的事了。
同理,DisposableBean就是在一个bean被销毁的时候,spring容器会帮你自动执行这个方法,估计底层原理也是差不多的,对于一些使用完之后需要释放资源的bean,我们都会实现这个接口,或者是配置destory-method方法。源码也基本是相似的,只是把afterPropertiesSet改为destroy。

  1. public interface DisposableBean {
  2.  
  3. /**
  4. * Invoked by a BeanFactory on destruction of a singleton.
  5. * @throws Exception in case of shutdown errors.
  6. * Exceptions will get logged but not rethrown to allow
  7. * other beans to release their resources too.
  8. */
  9. void destroy() throws Exception;
  10.  
  11. }

ApplicationContextAware
  其实我们看到---Aware就知道是干嘛用的了,就是属性注入的,但是这个ApplicationContextAware的不同地方在于,实现了这个接口的bean,当spring容器初始化的时候,会自动的将ApplicationContext注入进来:

  1. import org.apache.commons.lang.Validate;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.beans.factory.DisposableBean;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.ApplicationContextAware;
  6. import org.springframework.context.annotation.Lazy;
  7. import org.springframework.stereotype.Service;
  8. /**
  9. * applicationContext静态化
  10. * 使用了ApplicationContextAware接口的类,如果受spring容器管理的
  11. * 话,那么就会自动的调用ApplicationContextAware中的setApplicationContext方法
  12. * @author Hotusm
  13. *
  14. */
  15. @Service
  16. @Lazy(false)
  17. public class SpringContextHolder implements ApplicationContextAware,DisposableBean{
  18.  
  19. private static ApplicationContext applicationContext;
  20.  
  21. @Override
  22. public void setApplicationContext(ApplicationContext applicationContext)
  23. throws BeansException {
  24.  
  25. SpringContextHolder.applicationContext=applicationContext;
  26. }
  27. //清空applicationContext 设置其为null
  28. @Override
  29. public void destroy() throws Exception {
  30. SpringContextHolder.clearHolder();
  31. }
  32. //获得applicationContext
  33. public static ApplicationContext getApplicationContext() {
  34. //assertContextInjected();
  35. return applicationContext;
  36. }
  37.  
  38. public static void clearHolder(){
  39. applicationContext=null;
  40. }
  41. //获取Bean
  42. public static <T> T getBean(Class<T> requiredType){
  43. //assertContextInjected();
  44. return (T) getApplicationContext().getBean(requiredType);
  45. }
  46. @SuppressWarnings("unchecked")
  47. public static <T> T getBean(String name){
  48. assertContextInjected();
  49. return (T) getApplicationContext().getBean(name);
  50. }
  51. //判断application是否为空
  52. public static void assertContextInjected(){
  53. Validate.isTrue(applicationContext==null, "application未注入 ,请在springContext.xml中注入SpringHolder!");
  54. }
  55.  
  56. }

因为我们在做开发的时候,并不是说在每一个地方都能将属性注入到我们想要的地方去的,比如在Utils使用到dao,我们就不能直接注入了,这个时候就是我们需要封装springContext的时候了,而ApplicationContextAware就起了关键性的作用。

 

spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入的更多相关文章

  1. Spring扩展:替换IOC容器中的Bean组件 -- @Replace注解

    1.背景:     工作中是否有这样的场景?一个软件系统会同时有多个不同版本部署,比如我现在做的IM系统,同时又作为公司的技术输出给其他银行,不同的银行有自己的业务实现(比如登陆验证.用户信息查询等) ...

  2. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  3. spring扩展点之四:Spring Aware容器感知技术,BeanNameAware和BeanFactoryAware接口,springboot中的EnvironmentAware

    aware:英 [əˈweə(r)] 美 [əˈwer] adj.意识到的;知道的;觉察到的 XXXAware在spring里表示对XXX感知,实现XXXAware接口,并通过实现对应的set-XXX ...

  4. 🙈羞,Spring Bean 初始化/销毁竟然有这么多姿势

    文章来源:http://1t.click/bfHN 一.前言 日常开发过程有时需要在应用启动之后加载某些资源,或者在应用关闭之前释放资源.Spring 框架提供相关功能,围绕 Spring Bean ...

  5. 【spring源码学习】spring的IOC容器之自定义xml配置标签扩展namspaceHandler向IOC容器中注册bean

    [spring以及第三方jar的案例]在spring中的aop相关配置的标签,线程池相关配置的标签,都是基于该种方式实现的.包括dubbo的配置标签都是基于该方式实现的.[一]原理 ===>sp ...

  6. spring autowired还需要在xml中申明bean ?

    如果未自动扫描spring管理的类,则需要在xml中申明.如果自动扫描包下的类,则不需要 (如果配置了自动扫描,还是不行还需要进行手动在xml中声明,则就是工程建立的有问题,包的路径等问题)

  7. FastJson序列化Json自定义返回字段,普通类从spring容器中获取bean

    前言: 数据库的字段比如:price:1 ,返回需要price:1元. 这时两种途径修改: ① 比如sql中修改或者是在实体类转json前遍历修改. ②返回json,序列化时候修改.用到的是fastj ...

  8. Spring核心技术(七)——Spring容器的扩展

    本文将讨论如何关于在Spring生命周期中扩展Spring中的Bean功能. 容器的扩展 通常来说,开发者不需要通过继承ApplicationContext来实现自己的子类扩展功能.但是Spring ...

  9. spring扩展点整理

    本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...

随机推荐

  1. [luogu3359]改造异或树

    [luogu3359]改造异或树 luogu 和之前某道题类似只有删边的话考虑倒着加边 但是怎么统计答案呢? 我们考虑以任意点为根dfs一遍求出每个点到根的路径异或和s[i] 这样任意两点x,y的路径 ...

  2. mysql(root用户密码设置)

    root密码重置 修改root用户的密码: /*登录mysql*/ mysql -uroot -p123 /*切换数据库*/ use mysql /*修改root用户的密码*/ update user ...

  3. Dubbo,ZooKeeper,Redis,FastDFS,ActiveMQ,Keepalived,Nginx,Hudson

    获取[下载地址]   QQ: 313596790   [免费支持更新] 三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体 [新录针对本系统的视频教程,手 ...

  4. 坑爹的Hibernate 映射文件错误提示org.xml.sax.SAXParseException

    今天整整一个上午都在和hibernate做斗争,早上一来,继续昨天的项目开发,发现spring项目不能启动,从错误中看是hibernate错误,多半是hibernate配置有错误,关键是错误提示中显示 ...

  5. 每天一个Linux命令(8)cat命令

    cat命令连接文件并打印到标准输出设备上,cat经常用来显示文件的内容,类似于下的type命令. 注意:当文件较大时,文本在屏幕上迅速闪过(滚屏),用户往往看不清所显示的内容.因此,一般用more等命 ...

  6. pygame躲敌人的游戏

    #first.py# coding=utf- import pygame from pygame.locals import * from sys import exit from util impo ...

  7. 【leetcode刷题笔记】Subsets II

    Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: ...

  8. zabbix实现mysql数据库的监控(二)

    上章我们把zabbix的服务端和客户端都部署完成了,本章接着进行两部分的设置: 1  添加对mysql数据库主机的监控 2  添加对mysql数据库的监控 一.对数据库服务器主机监控 1 创建主机 步 ...

  9. android 电池(三):android电池系统【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8709838 一.电池系统结构 Android中的电池使用方式主要有三种:AC.USB. ...

  10. nginx expires缓存提升网站负载

    语法: expires [time|epoch|max|off]默认值: expires off作用域: http, server, location使用本指令可以控制HTTP应答中的“Expires ...