SpringContextHelper/SpringContextHolder偶現NullPointException異常

SpringContextHelper或者SpringContextHolder之類命名的類,主要是經過Spring上下文根據bean名稱獲取注入spring的對象。代碼相對簡單,本文不對代碼作詳細贅述。主要mark使用過程當中可能遇到的坑。java


  • 在項目啓動時,可能會偶現SpringContextHelper拋出的NPE異常。那麼什麼狀況會出現NPE呢?如bean A中有一個被@PostConstruct註解的方法m,當A被容器實例化以後會調用m,此時若是SpringContextHelper還未實例化就會致使NPE。最後雖然項目成功啓動了,而且後續SpringContextHelper能夠正常使用,可是這種NPE會致使m方法裏面處理的數據出現丟失的狀況。這種偶現的異常可能給項目帶來失之毫釐差之千里的影響。
  • 解決方案
    知道報錯緣由咱們很容易找到解決方法,只須要保證SpringContextHelper優先示例話便可。好比:
  1. 使用@DependsOn("springContextHelper"),在A上添加次註解,讓A在SpringContextHelper以後實例化;
  2. 在spring包掃描時調整SpringContextHelper優先被掃描到。 (SpringContextHelper.java在com.bingo包路徑下)
    @ComponentScan(basePackages = {
    			"com.bingo", "com.demo"
    	})

  • SpringContextHelper.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * <Description> 獲取容器中的ApplicationContext<br>
 *
 * @author <br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2016年10月10日 <br>
 */

@Component
public class SpringContextHelper implements ApplicationContextAware {
    /**
     * appCtx
     */
    private static ApplicationContext appCtx;

    /**
     * Description: 此方法能夠把ApplicationContext對象inject到當前類中做爲一個靜態成員變量。<br>
     *
     * @param applicationContext ApplicationContext 對象. <br>
     * @author <br>
     * @taskId <br>
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHelper.setAppCtx(applicationContext);
    }

    /**
     * Description: 此方法能夠把ApplicationContext對象inject到當前類中做爲一個靜態成員變量。<br>
     *
     * @param applicationContext ApplicationContext 對象. <br>
     * @author <br>
     * @taskId <br>
     */
    private static void setAppCtx(ApplicationContext applicationContext) {
        appCtx = applicationContext;
    }

    /**
     * Description: 獲取ApplicationContext<br>
     *
     * @return <br>
     * @author <br>
     * @taskId <br>
     */
    public static ApplicationContext getApplicationContext() {
        return appCtx;
    }

    /**
     * Description:這是一個便利的方法,幫助咱們快速獲得一個BEAN  <br>
     *
     * @param beanName beanName
     * @return <br>
     * @author <br>
     * @taskId <br>
     */
    public static Object getBean(String beanName) {
        return appCtx.getBean(beanName);
    }

    /**
     * Description: 快速獲取Spring容器中的bean<br>
     *
     * @param <T>   <br>
     * @param clazz <br>
     * @return <br>
     * @author <br>
     * @taskId <br>
     */
    public static <T> T getBean(Class<T> clazz) {
        return appCtx.getBean(clazz);
    }

    /**
     * 打印全部的bean name <br>
     */
    public static void printAllBeans() {
        System.out.println(Arrays.asList(appCtx.getBeanDefinitionNames()));
    }
}
相關文章
相關標籤/搜索