Spring Di через параметры динамического конструктора setter

#java #spring #dependency-injection

#java #spring #внедрение зависимостей

Вопрос:

Я новичок в Spring Framework, и я следую этому руководству, чтобы применить DI через setter. Все работает нормально, но я хотел бы добавить в свой класс CsvOutputGenerator конструктор с одним динамическим параметром, передаваемым на лету, когда я получаю компонент из контекста приложения.

Как я могу это сделать?

Я уже изменил свою конфигурацию Spring таким образом:

 ...
<bean id="CsvOutputGenerator" class="com.mkyong.output.impl.CsvOutputGenerator">
    <constructor-arg type="java.lang.String" value="Test"/>
</bean>
...
  

но таким образом это статическое значение для моего конструктора.

Ответ №1:

Вы можете передать это через системное свойство, например

 <constructor-arg lazy-init="true" type="java.lang.String" value="#{ systemProperties['some.key']}"/>
  

Комментарии:

1. Вы имеете в виду из другого файла конфигурации? Я хотел бы передать его из своего источника, когда я получаю компонент из ApplicationContext.

2. он устанавливает свойства при инициализации контекста приложения по умолчанию, вы хотите отложенную инициализацию, и перед инициализацией вам нужно установить системное свойство, чтобы передать его

3. Можете ли вы привести пример отложенной инициализации?

4. обновлено в ответе, однако это кажется хорошей идеей просто для целей обучения, если это реальное приложение, тогда лучше не зависеть от такой инициализации и перейти к настройке свойства вручную с помощью кода после его инициализации

5. Спасибо за ваш совет, но есть некоторый класс, например, класс File, который в своем конструкторе выполняет некоторые действия — например, new MyClassFile(«mypath»). Как вы решаете эти случаи?

Ответ №2:

Попробуйте что-нибудь еще, даже если Spring не предназначен для использования подобным образом (обратите внимание на область «прототип»):

 <bean id="CsvOutputGenerator" class="com.mkyong.output.impl.CsvOutputGenerator" scope="prototype" />
  

И затем в вашем коде вы можете сделать что-то вроде этого:

 CsvOutputGenerator myBean = (CsvOutputGenerator) context.getBean("CsvOutputGenerator", "testing testing");
  

Это метод в API, который я использовал выше.

Комментарии:

1. Я следовал вашей инструкции, но получаю это сообщение об ошибке: «Не удается разрешить метод ‘getBean (java.lang. Строка, java.lang. Строка)'»

2. Я бы предложил более новую версию Spring. Spring прямо сейчас находится в версии 4.0.5, самой последней, в то время как в тестируемом вами руководстве используется 2.5.6. Эта версия была выпущена почти 6 лет назад.

Ответ №3:

Приведенный ниже контент основан на приведенном выше вопросе и комментариях. Допустим, у вас есть класс URLRepo со строкой атрибута url. URL инициализируется значением. Затем вы можете сделать что-то подобное, чтобы подключить свой CsvOutputGenerator

 public class URLRepo {
     private String url = "your value";
     getters and setters
}


<bean id="urlRepo" class="com.*.*.MyURLRepo"/>    

<bean id="CsvOutputGenerator" class="com.mkyong.output.impl.CsvOutputGenerator">
    <constructor-arg type="java.lang.String" value="urlRepo.url"/>
</bean>
  

надеюсь, это то, что вы ищете.