spring的@ContextConfiguration注解-java.lang.IllegalStateException: Failed to load ApplicationContext

近期项目由普通项目换成了gradle构建项目以及管理

问题描述:

在junit测试的时候出现: Failed to load ApplicationContext 具体如下

> Task :wrapper
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
> Task :cleanTest
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test FAILED
16:11:47,302 ERROR --- TestContextManager.prepareTestInstance(231) | Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@16d8ae4a] to prepare test instance [-路径-.TjTest@221c9715]
java.lang.IllegalStateException: Failed to load ApplicationContext
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
	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:193)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:106)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:117)
	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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)

解决经历:
出现这个问题,开始以为是gradle构建项目时 test包下的扫描问题,在网上查了一堆也没搞出个究竟,包括junit的各种可能原因,种种都试了都不行,一把辛酸一把泪啊!

最终发现了问题!

问题原因:

究其根本就是没有抓住问题的源头,反被一个小问题引出了其他问题迷惑了双眼。
@ContextConfiguration这个注解中属性值的问题。

下图是原来的配置:可以看到IDEA已经给 很清楚的提示(红色字体报错,如果正确会显示正常字体颜色),“cannot resolve file …”
也就是这个配置文件路径有问题,解析不了。都已经说了这么清楚了,你还去junit测试 ,那ApplicationContext能加载进来就见鬼了啊。
在这里插入图片描述

@ContextConfiguration 注解的用法详解

直接举例子吧:
首先是我的配置文件路径如下:
在这里插入图片描述
也就是在根目录之下

针对以上 “applicationContext.xml” 文件@ContextConfiguration可以如下使用:

@ContextConfiguration(value="/applicationContext.xml") 		 //方法一
@ContextConfiguration(locations="/applicationContext.xml")   //方法二
@ContextConfiguration("classpath:/applicationContext.xml")   //方法三
@ContextConfiguration("/applicationContext.xml")  		     //方法四

切记前边要加一个 “/” 代表根目录(不带双引号)
这是我亲测的几种都可以正常运行junit。

其实也不用去死记, 这个分开也就是两块;

  • 一个是属性名(value、locations)
  • 一个是 属性值(双引号里边的,就是文件路径)

单个文件一般直接在双引号里边写路径或者用value属性(切记要加“ / ” !!!)
如果有多个文件要加载可以使用多个文件时,可用{}括起来,并用逗号分隔,以下示例

@ContextConfiguration(locations = { "classpath*:/spring1.xml", "classpath*:/spring2.xml" }) 

或者用value

@ContextConfiguration(value = { "/spring1.xml", "/spring2.xml" }) 

或者不写属性名,(加不加"classpath:" 都可以)

@ContextConfiguration({ "classpath:/spring1.xml", "classpath:/spring2.xml" }) 

当然单个文件也可以用locations 如上述方法二。
总之双引号里边的 路径一定要写正确了!写错了idea会用红色字体标识无法解析

打开ContextConfiguration源码

关于属性名,可以直接打开这个注解
在这里插入图片描述
在这里插入图片描述

@AliasFor 意思是注解中的属性可以互相为别名进行使用

根据上述源码可以看到, 该属性可以使用 locations 、value 或者直接写值(不写属性名),重点是值(路径)一定要写对。
根据返回值可以得出以上三种方式都可以配置多个文件

总结

  1. 解决问题要抓源头,治标先治本。
  2. 一定要关注idea给的提示信息。
  3. 一个工具用好了是你的左膀右臂,用不好会成为你的绊脚石。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值