记一次mybatis的classpath踩坑记录

本文记录了一次关于Mybatis的classpath问题的解决过程。在Spring+SpringMVC+Mybatis环境中,出现class path resource无法解析的问题。经过排查,发现并非spring.xml配置错误,而是mapper配置路径不正确。将mapping文件移动到resources源文件夹下,问题得到解决。通过此次经验,对classpath有了更深入的理解,强调了项目结构清晰和资源文件的正确放置对于避免此类问题的重要性。
部署运行你感兴趣的模型镜像

前情提要:

某日,M君外出办事,结果去早了,店家未开门。
见寒风凛冽,遂溜进一网吧。打开电脑欲大战机器人一把。
结果看到群内某男问了一个springmvc问题,M君按耐不住。欲解之,故有了下文。。。


问题描述:

环境:Spring+SpringMVC+Mybatis,Maven构建
异常:Install时,

[org.springframework.test.context.TestContextManager]Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@4a4038e2] to prepare test instance [sy.test.TestMybatis@6e030872]
java.lang.IllegalStateException: Failed to load ApplicationContext

起初一眼认定 ,测试用例TestMybatis里面的spring.xml路径配置错了。
于是你来我往聊了半天,没说出个所以然。再加上对maven不是非常熟悉,于是去看了看maven方面spring.xml配置文件的路径问题,发现应该是对的。
又问: service注解写了没啊?scan service的spring xml文件是哪个啊,有问有给进去啊?都没问题。
这下有点摸不着头脑了。

思索一小会儿,让其把完整异常发来。打开文件的瞬间一万个尼玛飞过。
大哥,你TM发异常能发完整不?
你可知道这会整死人不?
这里写图片描述

[org.springframework.test.context.TestContextManager]Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@4a4038e2] to prepare test instance [sy.test.TestMybatis@6e030872]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:103)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:73)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:313)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    at com.sun.proxy.$Proxy0.invoke(Unknown Source)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void sy.service.UserServiceImpl.setUserMapper(sy.dao.UserMapper); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [sy.dao.UserMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRoleMapper' defined in file [U:\Spring\testmybatis\target\classes\sy\dao\UserRoleMapper.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.core.io.Resource[]' for property 'mapperLocations'; nested exception is java.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:sy/mapping/*.xml]: class path resource [sy/mapping/] cannot be resolved to URL because it does not exist

class path resource [sy/mapping/] cannot be resolved to URL because it does not exist
看完之后,立马认定还是路径不对,但是是sy/mapping/这个不对,而不是spring.xml,于是问这是什么玩意儿?
答:mybatis配置文件。

于是索要了项目结构图:
这里写图片描述

研究了半天,没发现啥错啊。
于是准备在网吧整个IDE编译看看。结果破网吧的网速不到500K。谁TM在下片啊。(吐槽下:自称网咖,却浓浓的烟味)

奈何还有急事在身,于是匆忙出了网吧,去办事了。


半小时后,回到办公室,要了份项目压缩包,就Happy的跑起来了。
研究了一会儿,没什么头绪,感觉什么都是对的。
思来想去,算了,换个路径,不是说maven推荐resources放资源文件嘛,那就把这些mapping丢resources源文件夹下。
Bingo!Success了。我了个去,百度了下,没这方面的情报。只有之后再研究研究了。
这里写图片描述


收获:

其实一直对classpath这个玩意儿一知半解,迷迷糊糊的。通过这次我对它认识更深了一步。

之前的印象:
在src目录下建个resources文件夹,丢配置文件.然后classpath:resources即可。
然后就是WEB-INF下的会自动被读取到。

现在:
看目录结构!source folder,和folder,还有package是有很大区别的!
按之前的理解,MybatisMapper下的mapper写法是:classpath:main/resources/MybatisMapper/*.xml
现在看来完全就是错误的,应该是classpath:MybatisMapper/*.xml
意思就是我们应该是按照源文件夹下的路径来写。(如果有错误或者不足欢迎指正,本人也是在学习)
(之后好好理解下源文件夹、文件夹、package的区别)

以及:
项目一定要按结构来划分,资源文件不要放在代码的package里面,那样是读不到的
(或者有方法能读到,但是肯定不如清晰的结构来得好)

其他:
classpath:/xxx 和 classpath:xxx是一样的
classpath:xxx 和 classpath*:xxx是不一样的,前者表示引入一个,后者表示引入多个。


其实我经常喜欢回答群里人问的问题,可能很多大神完全不屑于回答。但是对我这菜鸟来说,能在解答的过程中重新学习认识一遍。是一种很有效的学习/复习方法。而且从他人的代码/问题中能学习到很多我所没遇到的问题和知识。

想我当年高中意气风发时候,物理课从不听讲,书一直没翻过,只有等到妹子们来问我这个物理课代表课后题目的时候,我才临时抱佛脚,看一通,然后做出来给她们讲。现在看来,这方法到现在还适用啊!哈哈!所以说做题实践永远比死记硬背来的快也来的懂!

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论 23
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值