我正在将Spring 2.5升级到4.2。
问题在于一个bean具有属性类型org.springframework.core.io.ClassPathResource
。资源值在xml中定义为p:location="classpath:/<the resource path>"
这完美无缺,bean属性填充了资源。但是在4.2中,值没有设定。
所以我调试了代码,发现类org.springframework.beans.BeanWrapperImpl
正在操作该值并从Spring 2.5中的实际值中删除classpath:
字符串。
然而,4.2中的情况并非如此,而org.springframework.beans.BeanWrapperImpl
类并未修改导致spring无法找到资源的值。
任何人遇到类似情况?你申请了什么解决方案?
谢谢, Hanumant
编辑1:代码示例
spring配置文件
<bean class="com.test.sample.TestBean" id="testBean"
p:schemaLocation="classpath:/com/test/sample/Excalibur_combined.xsd" />
TestBean.java
public class TestBean {
private ClassPathResource schemaLocation;
public ClassPathResource getSchemaLocation() {
return schemaLocation;
}
public void setSchemaLocation(ClassPathResource schemaLocation) {
this.schemaLocation = schemaLocation;
}
}
App.java
public class App {
public static void main(String[] args) {
ApplicationContext ap = new ClassPathXmlApplicationContext("classpath:/com/test/sample/spring-config.xml");
TestBean tb = (TestBean) ap.getBean("testBean");
try {
URL url = tb.getSchemaLocation().getURL();
System.out.println(url);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
错误消息
INFO: Loading XML bean definitions from class path resource
[com/test/sample/spring-config.xml] java.io.FileNotFoundException:
class path resource
[classpath:/com/test/sample/Excalibur_combined.xsd] cannot be resolved
to URL because it does not exist at
org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:187)> at com.test.sample.App.main(App.java:20)
但是,如果我从bean定义中删除classpath:
,它就可以工作。
bean定义xml文件中是否需要classpth:
?为什么它在Spring 2.5中运行良好?
答案 0 :(得分:1)
主要问题是您没有对接口进行编程。而不是具体org.springframework.core.io.ClassPathResource
使用org.springframework.core.io.Resource
。执行org.springframework.core.io.ResourceEditor
时会启动并将String
转换为Resource
实例。您提供的位置classpath:/<the resource path>
将传递给ResourceLoader
,如果资源不存在,则会获取资源或抛出错误。
但是,如果您直接使用具体类型ClassPathResouce
,则此机制不会启动,并且该位置将设置为您提供的classpath:/<the resource path>
。但是,这实际上不是URL
类的有效位置,并且最终会因您看到的消息而失败。
由于BeanWrapperImpl
中的hack / workaround / patch来剥离前缀,因此它在早期版本中有效。
基本上它现在失败了,因为你做的事情你不应该在第一时间做。