Spring中ApplicationContextAware接口的作用

x33g5p2x  于2022-02-24 转载在 Spring  
字(2.3k)|赞(0)|评价(0)|浏览(318)

当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有 bean。换句话说,就是这个类可以直接获取 Spring 配置文件中,所有有引用到的 Bean 对象。

在某些特殊的场景下,Bean需要实现某个功能,但该功能必须借助于Spring容器中的其他Bean才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能。为了让Bean获取它所在的Spring容器,可以让该Bean实现ApplicationContextAware接口。

  1. import org.apache.commons.lang3.Validate;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  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. @Component
  9. public class SpringContext implements ApplicationContextAware, DisposableBean {
  10. private static final Logger logger = LoggerFactory.getLogger(SpringContext.class);
  11. private static ApplicationContext applicationContext;
  12. /**
  13. * 获取存储在静态变量中的 ApplicationContext
  14. * @return
  15. */
  16. public static ApplicationContext getApplicationContext() {
  17. assertContextInjected();
  18. return applicationContext;
  19. }
  20. /**
  21. * 从静态变量 applicationContext 中获取 Bean,自动转型成所赋值对象的类型
  22. * @param name
  23. * @param <T>
  24. * @return
  25. */
  26. public static <T> T getBean(String name) {
  27. assertContextInjected();
  28. return (T) applicationContext.getBean(name);
  29. }
  30. /**
  31. * 从静态变量 applicationContext 中获取 Bean,自动转型成所赋值对象的类型
  32. * @param clazz
  33. * @param <T>
  34. * @return
  35. */
  36. public static <T> T getBean(Class<T> clazz) {
  37. assertContextInjected();
  38. return applicationContext.getBean(clazz);
  39. }
  40. /**
  41. * 实现 DisposableBean 接口,在 Context 关闭时清理静态变量
  42. * @throws Exception
  43. */
  44. public void destroy() throws Exception {
  45. logger.debug("清除 SpringContext 中的 ApplicationContext: {}", applicationContext);
  46. applicationContext = null;
  47. }
  48. /**
  49. * 实现 ApplicationContextAware 接口,注入 Context 到静态变量中
  50. * @param applicationContext
  51. * @throws BeansException
  52. */
  53. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  54. SpringContext.applicationContext = applicationContext;
  55. }
  56. /**
  57. * 断言 Context 已经注入
  58. */
  59. private static void assertContextInjected() {
  60. Validate.validState(applicationContext != null, "applicationContext 属性未注入,请在 spring-context.xml 配置中定义 SpringContext");
  61. }
  62. }

总结: Spring容器会检测容器中的所有Bean,如果发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContext()方法,调用该方法时,会将容器本身作为参数传给该方法——该方法中的实现部分将Spring传入的参数(容器本身)赋给该类对象的applicationContext实例变量,因此接下来可以通过该applicationContext实例变量来访问容器本身。

思考: spring容器在初始化时,与加载bean的顺序有关,写在前面的bean先加载,写在后面的bean后加载。

相关文章