Проблема с обновлением Spring 2.5 до 4.2 - BeanWrapperImpl

Я обновляю Spring 2.5 до 4.2. Проблема связана с одним компонентом, который имеет тип свойства org.springframework.core.io.ClassPathResource. Значение ресурса определяется в xml как p:location="classpath:/<the resource path>"

Это сработало отлично, и свойство bean-компонента было заполнено ресурсом. Но в 4.2 значение не устанавливается.

Поэтому я отладил код и обнаружил, что класс org.springframework.beans.BeanWrapperImpl манипулировал значением и удалял строку classpath: из фактического значения в Spring 2.5.

Однако то же самое не верно в 4.2, и класс org.springframework.beans.BeanWrapperImpl не изменяет значение, в результате чего spring не находит ресурс.

Кто-нибудь сталкивался с подобной ситуацией? Какое решение вы применили?

Спасибо, Ханумант.

EDIT 1: пример кода

конфигурационный файл весны

    <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)

Однако, если я удалю classpath: из определения компонента, это сработает.

Итак, необходимо ли classpth: в XML-файле определения бина ?? И почему в Spring 2.5 все работало нормально??


person hanumant    schedule 15.06.2016    source источник
comment
Пожалуйста, добавьте реальную конфигурацию в свой класс вместо фрагментов.   -  person M. Deinum    schedule 15.06.2016
comment
@ M.Deinum, я изменил исходный вопрос с помощью кода   -  person hanumant    schedule 15.06.2016
comment
Для начала в вашем коде это должен быть Resource, а не конкретный тип. Если он не может быть загружен, это потому, что он не существует в этом месте (об этом говорит вам исключение). Так что я предполагаю, что что-то еще изменилось в вашей структуре (и, возможно, вы обновляете не только spring, но и другие фреймворки/инструменты).   -  person M. Deinum    schedule 15.06.2016
comment
Я создал независимый проект maven для проверки этого сценария. Так что, просто изменив весеннюю версию в pom, я могу воспроизвести эту проблему. Пример приложения работает с версией 2.5, но не работает с версией 4.2.   -  person hanumant    schedule 15.06.2016
comment
можешь добавить на гитхаб?   -  person M. Deinum    schedule 15.06.2016
comment
извините, политика компании не может ничего добавлять в онлайн-репозитории с исходными кодами. Просто, чтобы ограничить комментарии. Изменение ClassPathResource на Resource работает. Интересно, что здесь произошло.   -  person hanumant    schedule 15.06.2016
comment
Почему бы вам не добавить независимый проект maven, который не имеет ничего общего с компанией. В любом случае, почему это работает, так это то, что вы должны были все время программировать интерфейсы :). Теперь это работает, потому что теперь ResourceLoader используется для загрузки фактического ресурса, а classpath: теперь является триггером, определяющим, откуда загружать. Если вы используете определенный тип, этот механизм не срабатывает, и строка напрямую передается в ресурс. Это работало в более старых версиях из-за хака, который вы обнаружили ранее.   -  person M. Deinum    schedule 15.06.2016
comment
@ M.Deinum, пожалуйста, добавьте это как ответ, чтобы я мог закрыть этот вопрос. Спасибо :)   -  person hanumant    schedule 15.06.2016


Ответы (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 для удаления префикса.

По сути, теперь это терпит неудачу, потому что вы делаете то, что не должны были делать в первую очередь.

person M. Deinum    schedule 15.06.2016