content: /**
   * Copyright &copy; 2015 <a href="https://git.oschina.net/luckyben/webook">WeBook</a> All rights reserved.
   */
  package com.qihoo.finance.chronus.context;
  
  
  import lombok.extern.slf4j.Slf4j;
  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.Component;
  import org.springframework.util.Assert;
  
  /**
   * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext.
   *
   * @author Zaric
   * @date 2013-5-29 下午1:25:40
   */
  @Slf4j
  @Component("applicationContextHolder")
  @Lazy(false)
  public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
  
      private static ApplicationContext applicationContext = null;
  
      public SpringContextHolder() {
      }
  
      public SpringContextHolder(ApplicationContext applicationContext) {
          SpringContextHolder.applicationContext = applicationContext;
      }
      /**
       * 实现ApplicationContextAware接口, 注入Context到静态变量中.
       */
      @Override
      public void setApplicationContext(ApplicationContext applicationContext) {
          log.debug("注入ApplicationContext到SpringContextHolder:{}", applicationContext);
          if (SpringContextHolder.applicationContext != null) {
              log.info("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
          }
          SpringContextHolder.applicationContext = applicationContext;
      }
  
  
      /**
       * 取得存储在静态变量中的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);
      }
  
      public static boolean containsBean(String name) {
          assertContextInjected();
          return applicationContext.containsBean(name);
      }
  
      /**
       * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
       */
      public static <T> T getBean(Class<T> requiredType) {
          assertContextInjected();
          return applicationContext.getBean(requiredType);
      }
  
      /**
       * 清除SpringContextHolder中的ApplicationContext为Null.
       */
      public static void clearHolder() {
          if (log.isDebugEnabled()) {
              log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
          }
          applicationContext = null;
      }
  
      /**
       * 检查ApplicationContext不为空.
       */
      private static void assertContextInjected() {
          Assert.notNull(applicationContext, "applicaitonContext属性未注入!");
      }
  
      /**
       * 实现DisposableBean接口, 在Context关闭时清理静态变量.
       */
      @Override
      public void destroy() throws Exception {
          SpringContextHolder.clearHolder();
      }
  }