【Java】使用@Value @Reource或@Autowire依賴 (值) 注入時出現NPE的排查方法

首先想說明的是,@Value @Resource和@Autowire雖然都是用於依賴注入的Annotation,可是兩者是有區別的。java

    1 Resource不依賴於Spring,後者相反,所以爲了減小以來,儘可能使用Resource;web

    2 Resource是優先按照變量名稱匹配的,也可用@Resource(name="")指定要注入的變量名。Autowire則是優先按類型匹配,配合@Qualifier也可指定變量名。spring

    3 不存在靈異事件!不存在靈異事件!不存在靈異事件!重要的事說三遍。若是出現了NullPointerException,那必定是代碼寫錯了。app

 

當出現被注入的變量被調用時拋出NPE,按照以下的經驗排查:webapp

0 Spring的xml配置文件是否都包含在classpath(resources、webapp甚至java均可)中,若是有多個xml文件,include的層次關係是否正確。測試

1 肯定類所在的包是否被Spring掃描到。檢查配置文件中是否有:spa

    <context:annotation-config />
    <context:component-scan base-package="me.xxx" />
    <context:component-scan base-package="me.yyy" />

2 檢查Bean是否有重複定義。code

3 對於靜態的依賴,要在其setter方法上加@Resource,目的是欺瞞Spring向一個靜態變量進行注入。component

<bean id="classType" class="....ClassType" />

static
ClassType classType; @Resource public void setClassType(ClassType classType) { XXX.cXXXlassType = classType; }

4 若是是在測試用例中使用@Resource時出現NPE,則考慮是否是Bean根本沒有在applicationContext中建立。xml

能夠用下面的方法寫測試用例,以免對大量的字段進行初始化(須要junit 4.9以上的版本):

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/spring-XXX.xml"}) public class BaseTest extends AbstractJUnit4SpringContextTests { @BeforeClass public static void setUpBeforeClass() throws Exception { // add whatever you like.
 } } public class XXXXTest extends BaseTest {...}

 固然若是明確地知道單個測試用例只需用到哪些上下文,也能夠把這段寫在測試用例XXXTest自己,避免每次都要加載整個上下文,致使重量級的用例。

5 若是要檢查上下文是否正常建立,或者某個Bean是否在上下文中,能夠直接用@Resource調出名爲「applicationContext」的全局上下文。

相關文章
相關標籤/搜索