不學無數——Spring注入後反射的空指標異常
Spring注入後反射的空指標異常
自動裝配是在spring環境下當使用該類的例項時由spring容器完成了類的例項化過程,包括對依賴物件的例項化過程。
而通過反射建立例項時,是根據你呼叫的建構函式完成的例項化過程,沒有容器的自動化建立例項了,所以需要自己對依賴物件進行注入。
所以依賴spring容器例項化和自己用反射例項化是兩種獨立的方式,不能相互滲透的。
1. 異常說明
在單元測試類中,要單獨測一個類中的private
方法,所以想通過反射獲得此方法,解除私有限定,然後進行呼叫。此類為Service
其中注入了許多的Mapper
,因此在通過呼叫此私有方法的時候報了空指標異常的錯誤,錯誤如下:
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.suixingpay.bap.service.impl.CheckAmsPmtAndPtsFlowServiceImplTest.testInvoke(CheckAmsPmtAndPtsFlowServiceImplTest.java:78) at com.suixingpay.bap.service.impl.CheckAmsPmtAndPtsFlowServiceImplTest.insertByList(CheckAmsPmtAndPtsFlowServiceImplTest.java:69) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: java.lang.NullPointerException at com.suixingpay.bap.service.impl.CheckAmsPmtAndPtsFlowServiceImpl.succesExitReove(CheckAmsPmtAndPtsFlowServiceImpl.java:247) ... 36 more
注意最後面是由NullPointerException
引起的。通過Debug進去以後發現是與資料庫互動的Mapper
沒有注入進來。
單元測試程式碼如下:
@Autowired private CheckAmsPmtAndPtsFlowServiceImpl checkAmsPmtAndPtsFlowServiceI; @Test public void insertByList() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { List<TBapCheckResultSave> list = new ArrayList<>(); Class cls = Class.forName("service.impl.CheckAmsPmtAndPtsFlowServiceImpl"); Class[] cArg = new Class[5]; cArg[0] = List.class; cArg[1] = boolean.class; cArg[2] = String.class; cArg[3] = String.class; cArg[4] = String.class; Method succesExitReove = cls.getDeclaredMethod("succesExitReove",cArg); succesExitReove.setAccessible(true); succesExitReove.invoke(checkAmsPmtAndPtsFlowServiceI,list,true,"1","1","2"); }
此處有個知識點:在呼叫
getDeclaredMethod()
獲得指定的方法時,第二個引數是方法的傳參型別,包裝類和其基本型別是不一樣,例如下面方法為boolean
,如果此時在上面cArg[1] = Boolean.class;
寫為其包裝型別的話,那麼就會報錯找不到此方法的錯誤
被反射的類中方法succesExitReove ()
如下
@Autowired
private TMemAcPmtDtlPoMapper tMemAcPmtDtlPoMapper;
private void succesExitReove(List<TBapCheckResultSave> result, boolean isFen, String sourceType, String opId, String batchId) {
Iterator<TBapCheckResultSave> iteDownPtsNoCodeSuccces = result.iterator();
while (iteDownPtsNoCodeSuccces.hasNext()) {
int count;
if (isFen) {
count = tMemAcPmtDtlPoMapper.queryCheckFlow(bapCheckResult.getOutTransId());
} else {
count = tMemAcPmtDtlPoMapper.queryCheckFlow(bapCheckResult.getTransId());
}
bapCheckResult.setPmtCount(count);
if (count > 0) {
iteDownPtsNoCodeSuccces.remove();
}
}
}
此處在Debug時發現tMemAcPmtDtlPoMapper
為空。
2. 解決辦法
在單元測試類中
@Autowired
要用的Mapper,然後通過反射獲得上面方法要用到Mapper
的變數,為其賦值即可
單元測試程式碼如下
@Autowired
private CheckAmsPmtAndPtsFlowServiceImpl checkAmsPmtAndPtsFlowServiceI;
--在單元測試類中進行依賴注入Mapper
@Autowired
private TMemAcPmtDtlPoMapper tMemAcPmtDtlPoMapper;
@Test
public void insertByList()
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException,
NoSuchFieldException {
List<TBapCheckResultSave> list = new ArrayList<>();
Class cls = Class.forName("service.impl.CheckAmsPmtAndPtsFlowServiceImpl");
Class[] cArg = new Class[5];
cArg[0] = List.class;
cArg[1] = boolean.class;
cArg[2] = String.class;
cArg[3] = String.class;
cArg[4] = String.class;
Field a1 = cls.getDeclaredField("tMemAcPmtDtlPoMapper");
Method succesExitReove = cls.getDeclaredMethod("succesExitReove",cArg);
succesExitReove.setAccessible(true);
--在此為反射的類進行賦值Mapper
Field a1 = cls.getDeclaredField("tMemAcPmtDtlPoMapper");
a1.setAccessible(true);
a1.set(checkAmsPmtAndPtsFlowServiceI,tMemAcPmtDtlPoMapper);
succesExitReove.invoke(checkAmsPmtAndPtsFlowServiceI,list,true,"1","1","2");
}
相關推薦
不學無數——Spring注入後反射的空指標異常
Spring注入後反射的空指標異常 自動裝配是在spring環境下當使用該類的例項時由spring容器完成了類的例項化過程,包括對依賴物件的例項化過程。 而通過反射建立例項時,是根據你呼叫的建構函式完成的例項化過程,沒有容器的自動化建立例項了,所以需要自己
Spring注入SessionFactory的空指標異常
自己的錯誤在於,new的Dao例項,進行呼叫,以至於出現Dao中注入的Sessionfactory空指標。 在hibernate+spring配置過程中,應注意幾點: 1、不能直接new一個DAO的例項,而應該通過spring的配置檔案自動初始化session be
spring整合mybatis時報空指標異常:service注入得不到Mapper介面的例項化物件(已解決)
解決方法在下邊↓↓問題一: mabite中Mapper介面的例項化物件找不到,顯示為NULL這是我的配置,還有執行時報的錯這幾個檔案都是使用反向工程生成的,應該沒有錯。執行結果顯示tUserMapper為null問題二:還有,使用ssm框架寫web工程的時候還出過這麼一
Test測試:Spring 注入失敗,空指標
問題描述 使用註解無法注入例項,出現空指標異常。若不用註解,直接new一個例項,可以正常執行 控制檯輸出 異常發生點 @Resource private UserService userService; priv
Spring自動裝配報空指標異常
這幾天在學Spring的自動裝配,自己動手做一個小專案,但是被一個空指標異常卡住了。 啟動的時候彈出index.jsp,這是一個登陸頁面: <%@ page language="java" contentType="text/html; charset
eclipse 中Spring 使用@Autowired 報空指標異常
最近在學生Spring框架,這算是一個很低階的錯誤,寫出來希望不要有人犯和我一樣的錯誤,執行下面的例子時,使用了@autowired註釋,但是報出了空指標異常,例子程式如下: TextEditor SpellChecker MainApp: 執行後報了一個空指
關於執行緒呼叫Spring註解物件報空指標異常
本人剛接觸執行緒方面,今天在寫一個埠監控的時候遇到一個問題,就是線上程中,呼叫spring注入的物件時,報空指標異常. 而且只在這個類中報這個問題. 在controller類中,能正常執行,所以應該能排除注入失敗或者配置錯誤的因素. 百思不得其解,暫時先記下問題,以
Myeclipse啟動後tomcat空指標異常
今天早上吃完早餐來公司上班,開啟電腦,輸入密碼,123456。。。。。嗯……,再開啟myeclipse,duang。。。duang。。。duang。。。。tomcat空指標異常,tmd我這暴脾氣昨天還好好的今天就給我來這一套,擱我五年前那暴脾氣,早就卸了你,時間成就了我的成熟
不學無數——反射和內省的區別
反射和內省的區別 內省是基於反射實現的,主要用來操作JavaBean,通過內省可以很方便的動態獲得bean的set/get方法,屬性,方法名,他相當於是反射的工具類一樣 1. 反射 反射其實簡單來說就是通過類的名字獲得對於這個類的描述,這種描述包括方法、構造器、屬性的描述。
不學無數——初識反射
反射:執行時的類資訊 執行時型別資訊使得你可以在程式執行時發現和使用型別資訊 1. Class物件 通過Class物件可以在執行時發現一個物件完整的類繼承結構 類是程式的一部分,每一個類都會有一個Class物件。換句話說既每編寫一個新的類,就會產生一個Cl
不學無數——Java中IO和NIO
JAVA中的I/O和NIO I/O 問題是任何程式語言都無法迴避的問題,可以說 I/O 問題是整個人機互動的核心問題,因為 I/O 是機器獲取和交換資訊的主要渠道。在當今這個資料大爆炸時代,I/O 問題尤其突出,很容易成為一個性能瓶頸。 什麼是I/O I/O ? 或者輸入/輸出
不學無數——SpringBoot入門Ⅷ
SpringBoot--Actuator 1. 初識Actuator 在開發過程中,專案被放置到生產伺服器上執行時,有可能需要我們全方位的監控應用服務的執行情況。此時SpringBoot提供了Actuator模組進行監控和管理 2. 使用方法 在gradle中新增依賴 compi
不學無數——SpringBoot入門Ⅶ
SpringBoot 1.建立自己的Auto-configuration 無論是在公司中你想開發自己的一套框架,定製一些東西,或者是在開源網站中分享自己做的一些東西。你可能想要開發屬於自己的Auto-configuration。Auto-configuration的類能夠捆綁到外部的jar包
不學無數——SpringBoot入門VI
SpringBoot 1 連線資料庫 Spring框架為連線資料庫提供了許多的幫助,從JDBC連線到使用JdbcTemplate完成元素之間的對映技術。例如Hibernate、Spring Data提供了更高級別的功能,建立Repository的實現,用介面中的方法和xml檔案具體SQL的對
不學無數——SpringBoot入門V
SpringBoot 1.開發一個Web程式 SpringBoot是非常適合開發Web應用的,因為他內嵌有Tomcat、Jetty、Undertow或者Netty。大部分的應用可以通過載入spring-boot-starter-web模組能夠快速的建立並啟動一個Web應用。 1.1Spr
不學無數——SpringBoot入門IV
SpringBoot 1.Profiles Spring Profiles能夠在不同的環境中使不同的應用配置生效。@Component和@Configuration兩個註解都能夠通過@Profiles來標記。下面是例子: @Configuration @Profile("buxuewus
不學無數——SpringBoot入門Ⅲ
SpringBoot-外部資源的配置 1.外部資源的配置優先順序 為了能夠在不同的環境執行不同的配置檔案,或者有些程式碼的一些變數是跟隨著環境的改變而改變的,這時候就需要在外部做一些配置。SpringBoot允許這麼做,並且有一套配置規則。可以通過@Value註解進行將一些變數動態的取出來。
不學無數——SpringBoot入門Ⅱ
SpringBoot 1.Starters Starters是一套技術,是什麼技術呢?是SpringBoot整理出來,人們經常要用的技術。有了starters人們在想要使用這些技術的時候,就不用扒之前的老程式碼將那些依賴啊或者配置的都拷貝過來,只需要加上SpringBoot提供的依賴就行,它
不學無數——SpringBoot入門Ⅰ
SpringBoot 1.SpringBoot簡介 在剛接觸SSM框架的時候,想必都會被這個框架的配置檔案所煩擾,需要自己手動配置的東西非常多,哪怕有些東西自己不需要也是需要配置的。而SpringBoot此時就應運而生,減少了大家的配置過程。相信都聽過“約定優於配置”的這樣一句話,就是說系統
不學無數——裝飾模式
裝飾模式 在開始之前 我們可以用一個簡單的例子引出來裝飾模式,在小的時候,相信大家都有過這樣的經歷:小學每年會有好幾次的考試,如果有一次成績非常差,而且考完以後學校會有個很損的招,就是打印出來成績單,然後讓家長簽字。那麼拿著這個成績單,肯定是不會直接告訴家長成績什麼的,肯定是會加一些,例如,