Explanation of the method of actively obtaining bean by Spring through ApplicationContext

  • 2021-07-13 05:22:22
  • OfStack

Question 1:

There is an asynchronous thread Runnable that needs dao, which cannot be passed in through AutoWired and compoment annotations.

Therefore, I hope to actively obtain bean through Spring context.

Question 2:

getBean(name) Failed to get.

Resolve:

name= class name of default dao (first letter lowercase)

For example:

Interface name: TemplateDao getName(“templateDao”) You can

Generic SpringContextUtil to get Bean

1. Implement the ApplicationContextAware interface


/**
 * spring Context configuration 
 * @author Mingchenchen
 *
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {
  private static Logger logger = Logger.getLogger(SpringContextUtil.class);
  private static ApplicationContext applicationContext = null;
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
  {
    logger.info("------SpringContextUtil setApplicationContext-------");
    SpringContextUtil.applicationContext = applicationContext;
  }
  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
  /**
   *  Attention  bean name Default  =  Class name ( First letter lowercase )
   *  For example : A8sClusterDao = getBean("k8sClusterDao")
   * @param name
   * @return
   * @throws BeansException
   */
  public static Object getBean(String name) throws BeansException {
    return applicationContext.getBean(name);
  }
  /**
   *  Obtained from the class name bean
   * @param <T>
   * @param clazz
   * @return
   * @throws BeansException
   */
  @SuppressWarnings("unchecked")
  public static <T> T getBeanByName(Class<T> clazz) throws BeansException {
    try {
      char[] cs=clazz.getSimpleName().toCharArray();
      cs[0] += 32;// First letter uppercase to lowercase 
      return (T) applicationContext.getBean(String.valueOf(cs));
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    } 
  }
  public static boolean containsBean(String name) {
    return applicationContext.containsBean(name);
  }
  public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    return applicationContext.isSingleton(name);
  }
}

2. Configure the Listener that loads the Spring container in web. xml in the web project


<!--  Initialization Spring Container, let Spring Container with Web Start automatically when the application starts  --> 
  <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
  </listener> 

getBeanByName(Class clazz)

This method is better to use, but it should be noted that the name @ Service ("myService") needs to be configured in impl of Dao and service

The rule is that the first letter of the class name of interface Service is lowercase.

The second way:

At present, I have made a system initialization of SystemInit, and then found that the above getBean () can't be used. Look at the next discovery is because SpringContextUtil has not been initialized at the time of system initialization, resulting in the failure of getBean () in the SystemInit class.

With a minor modification, ApplicationContextAware is placed in the SystemInit class and then injected into SpringContextUtil, thus ensuring that applicationContext1 is not null before executing the system initialization method.


/**
 * spring Context configuration 
 * @author Mingchenchen
 *
 */
public class SpringContextUtil {
  private static Logger logger = Logger.getLogger(SpringContextUtil.class);
  //@Autowired  Follow springTest This method of   Would it be better? 
  //ApplicationContext ctx;
  private static ApplicationContext applicationContext = null;
  public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    logger.info("------SpringContextUtil setApplicationContext-------");
    SpringContextUtil.applicationContext = applicationContext;
  }
  // Notice that this has become static
  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
  /**
   *  Attention  bean name Default  =  Class name ( First letter lowercase )
   *  For example : A8sClusterDao = getBean("k8sClusterDao")
   * @param name
   * @return
   * @throws BeansException
   */
  public static Object getBean(String name) throws BeansException {
    return applicationContext.getBean(name);
  }
  /**
   *  Obtained from the class name bean
   * @param <T>
   * @param clazz
   * @return
   * @throws BeansException
   */
  @SuppressWarnings("unchecked")
  public static <T> T getBeanByName(Class<T> clazz) throws BeansException {
    try {
      char[] cs=clazz.getSimpleName().toCharArray();
      cs[0] += 32;// First letter uppercase to lowercase 
      return (T) applicationContext.getBean(String.valueOf(cs));
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    } 
  }
  public static boolean containsBean(String name) {
    return applicationContext.containsBean(name);
  }
  public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    return applicationContext.isSingleton(name);
  }
}
/**
 * Descripties:  System initialization 
 * @author wangkaiping
 * 2016 Year 5 Month 23 Day   Morning 11:58:09
 */
@Component
public class SystemInit implements InitializingBean,ApplicationContextAware{
  private static Logger logger = Logger.getLogger(SystemInit.class);
  @Autowired
  private ClusterDao clusterDao;
  @Override
  public void afterPropertiesSet() throws Exception {
    logger.info("-------------- System initialization -------------------");
    initClusterCache();// Initialize cluster data   Must be completed at the beginning 
    initRefreshAppStatusTask();
    initUpdateAppStatusToDB();
    initUpdateSession();
    logger.info("-------------- System initialization completed -------------------");
  }
  /**
   * 1. Initialize cluster data 
   */
  private void initClusterCache(){
    logger.info("1. Initialize cluster information into the cache :ClusterCache Begin ");
    // Query all cluster data in the database 
    List<ClusterEntity> allClusterInfoList = clusterDao.selectAll(ClusterEntity.class, "delete_flag=0");
    for (ClusterEntity k8sClusterEntity : allClusterInfoList) {
      ClusterCache.put(k8sClusterEntity.getUuid() , k8sClusterEntity);// Save in cache 
    }
    logger.info("1. Initialize cluster information into the cache :ClusterCache Finish , Total " + allClusterInfoList.size() + " Bar data ");
  }
  /**
   * 2. Initialize asynchronous tasks : Refresh all application status 
   */
  private void initRefreshAppStatusTask() {
    logger.info("2. Initialize task :RefreshAllAppStatusTask  Refresh the k8s Adj. pod Status and stored in the queue to be updated ");
    RefreshAppStatusExcutor.init();
    logger.info("2. Initialize task :RefreshAllAppStatusTask  Finish ");
  }
  /**
   * 3. Initialize asynchronous tasks : Update status to database 
   */
  private void initUpdateAppStatusToDB() {
    logger.info("3. Initialize task :RefreshToDBTask  From to be updated Appinstance Queue fetches data and updates database ");
    UpdateAppStatusToDBExcutor.init();
    logger.info("3. Initialize task :RefreshToDBTask  Finish ");
  }
  /**
   * 4.  Initialize asynchronous tasks:   Update all of the user's session
   */
  private void initUpdateSession() {
    logger.info("4. Initialization task: Update session Begin ");
    UserSessionUpdateExcutor.init();
    logger.info("4. Initialization task: Update session End ");
  }
  ////////////////////////////////////////////////////////////////
  // This method 1 Don't write it static
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) 
                        throws BeansException {
    // Actually, it is to put applicationContext Passed in SpringContextUtil Inside 
    SpringContextUtil.setApplicationContext(applicationContext);
  }
}

Summarize


Related articles: