content: package com.alibaba.tesla.authproxy;
  
  import lombok.extern.slf4j.Slf4j;
  import org.apache.commons.lang3.Validate;
  import org.springframework.beans.factory.DisposableBean;
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.ApplicationContextAware;
  import org.springframework.stereotype.Component;
  
  /**
   * <p>Title: SpringContextHolder.java<／p>
   * <p>Description: <／p>
   * <p>Copyright: Copyright (c) 2017<／p>
   * <p>Company: alibaba <／p>
   *
   * @author tandong.td@alibaba-inc.com
   * @version 1.0
   * @date 2017年4月8日
   */
  @Component
  @Slf4j
  public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
  
      private static ApplicationContext applicationContext = null;
  
      /**
       * 取得存储在静态变量中的ApplicationContext
       */
      public static ApplicationContext getApplicationContext() {
          assertContextInjected();
          return applicationContext;
      }
  
      /**
       * 实现ApplicationContextAware接口, 注入Context到静态变量中
       */
      @Override
      public void setApplicationContext(ApplicationContext applicationContext) {
          log.debug("注入ApplicationContext到SpringContextHolder:{}", applicationContext);
          if (SpringContextHolder.applicationContext != null) {
              log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:"
                      + SpringContextHolder.applicationContext);
          }
          SpringContextHolder.applicationContext = applicationContext;
      }
  
      /**
       * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型
       * 例如：getBean（“custService”），前提是对bean定义别名
       *
       * @param name beanId
       * @return bean对象
       */
      @SuppressWarnings("unchecked")
      public static <T> T getBean(String name) {
          assertContextInjected();
          return (T) applicationContext.getBean(name);
      }
  
      /**
       * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型
       * 例如：getBean(ICustService.class)，这种方式不需要考虑ICustService的别名
       *
       * @param requiredType 要获取的bean对象类型
       * @return bean对象
       */
      public static <T> T getBean(Class<T> requiredType) {
          assertContextInjected();
          return applicationContext.getBean(requiredType);
      }
  
      /**
       * 清除SpringContextHolder中的ApplicationContext为Null
       */
      public static void clearHolder() {
          log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
          applicationContext = null;
      }
  
      /**
       * 检查ApplicationContext不为空
       */
      private static void assertContextInjected() {
          Validate.validState(applicationContext != null,
                  "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder,同时set lazy-init is false.");
      }
  
      /**
       * 实现DisposableBean接口, 在Context关闭时清理静态变量
       */
      @Override
      public void destroy() throws Exception {
          SpringContextHolder.clearHolder();
      }
  }
  