Автопроводка при загрузке весной: странный случай заполнения значения - PullRequest
0 голосов
/ 19 февраля 2020

Я был поражен чем-то, и мой сон никуда не девался после того, как я узнал, что мой код работает с прошлых 2 лет, когда явно это не должно! Так что это загрузочное приложение Spring. Приложение имеет несколько контроллеров. Один из классов, которые я использую, расширяет WebServiceGatewaySupport, поэтому требует, чтобы я @Autowire это. Имя класса AClient. Теперь этому классу нужно 4 свойства для работы. Три из них поступают из файла свойств, например,

@Value("${a.userName}")String userName; 

Таким образом, три свойства, очевидно, выбираются из файла application.properties. Теперь четвертое свойство меня сдуло. Он НЕ извлекается как остальные три, но копируется из параметра конструктора. Таким образом, у нас есть только один конструктор в классе:

public AClient(String d){
    this.d=d;
}

Теперь это свойство используется в одном из методов, которые этот класс имеет

public String getSomeData(){
// This method gets Data based on property d
}

И что интересно и удивительно, значение этого свойства присутствует каждый раз, когда к этому бобу обращаются! Бин @Autowired только в одном месте, внутри класса Controller. Я не пометил значение свойства для извлечения из файла application.properties. Я не предоставил этому классу никакой подсказки, откуда взять значение d. Я не предоставлял никаких методов publi c для других классов, чтобы установить это значение. Тем не менее, код работает, и я даже могу поместить указатель отладки в метод getSomeData () и увидеть, что значение d присутствует!

Теперь я понимаю, что, возможно, упускаю что-то очевидное, но что? Есть ли способ попасть в контейнер Spring, когда объекты @Autowired создаются и отлаживаются с этой точки, чтобы увидеть, откуда приходит это значение? Я проверял код несколько раз. Запустите сотни запросов в Google, чтобы найти что-то похожее на то, что Spring boot делает магические вещи c, чтобы отобразить отсутствующие свойства String. Но имя переменной в файле свойств отличается от имени в классе AClient. Так, как это может даже нанести на карту? Это действительно убивает меня сейчас!

Дополнение: Менее актуально, но к коду обращаются стандартным способом:

@Autowired
AClient aClient;

public someOtherMethod(){
    aClient.getSomeData();
}

Поэтому, когда я помещаю отладчик в первую строку someOtherMethod ( ) и наведите курсор мыши на aClient, он отображает значение переменной d, заполненное, так же, как в файле application.properties!

Редактировать: вот что я пропустил:

@Configuration
public class someConfig{
@Bean
   public AClient aClient(){
    // Someone else fetched property from application.properties file, created an object of AClient class using argument constructor and returned that object here. So now Spring is using @Autowire reference for this object I guess
 }
}

1 Ответ

1 голос
/ 19 февраля 2020

Таким образом, ваш класс @Configuration выглядит примерно так?

@Configuration
public class SomeConfig {

    @Value("${a-client.important-value-d}")
    private String importantValueDFromApplicationProperties;

    @Bean
    public AClient aClient() {
        return new AClient(importantValueDFromApplicationProperties);
    }

}

Если да, то Spring будет aClient для каждого @Autowired, запрашивающего его. Поэтому значение importantValueDFromApplicationProperties будет присутствовать в этом конкретном случае.

Еще одно примечание: я бы рекомендовал использовать Spring 101 Boot вместо 1011 *. Посмотрите.

...