И так...
Продолжаем курс по Spring'у. На прошлом занятии мы изучали внедрения зависимости c помощью сеттера. Если обратили внимания, то тогда мы внедряли значения с помощью ссылок на id. То есть внедрение происходило при помощи атрибута ref. Выглядело это примерно так:
Листинг 1
А в файле пропишем следующие значения:
<bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
<bean id="hiringDepartment" class="org.example.HiringDepartment">
<property name="development" ref="javaDeveloper"/>
</bean>
Тут 4 - строка ссылается на id "javaDeveloper", которая внедряет значение класса JavaDevelopment. А что если мы хотим внедрить значения вручную или получить его другим путем, а затем внедрить. Посмотрим на примере. У каждого сотрудника есть гражданство и заработная плата. И пусть эти сущности будут определены в классе HiringDepartment. Допустим так:
Листинг 2
package org.example;
public class HiringDepartment {
private Development development; //Определяем интерфейс
private int salary;
private String citizenship;
public void displayInfo(){
System.out.println("Name: " + development.getName());
System.out.println("Job: " + development.getJob());
}
public void setDevelopment(Development development){
this.development = development;
}
public Development getDevelopment(){
return development;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String getCitizenship() {
return citizenship;
}
public void setCitizenship(String citizenship) {
this.citizenship = citizenship;
}
}
Тут мы добавили 2 поля. int salary и String citizenship. А также определили геттеры и сеттеры для этих объектов. Напоминаю, что Spring за кулисами ссылается на эти геттеры и сеттеры для связывания значений с объектами класса. На остальные классы пока не трогаем. А затем переделаем файл applicationContext, в котором определяются бины для наших объектов. А это выглядит вот так:
Листинг 3
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
<bean id="pythonDeveloper" class="org.example.PythonDevelopment"/>
<bean id="hiringDepartment" class="org.example.HiringDepartment">
<property name="development" ref="javaDeveloper"/>
<property name="citizenship" value="USA"/>
<property name="salary" value="5000"/>
</bean>
</beans>
В отличие от Листинга 1, сюда были добавлены ещё два property (строки 12 и 13). Тут в игру вступает атрибут value, который определен внутри тега property. Еще раз напоминаю, что значение атрибута name должно совпадать с объектом на который ссылается бин. А далее Spring самостоятельно определяет геттеры и сеттеры по этим значениям. А при помощи атрибута value внедряем значения для полей. Обратите внимание, что оба значения value определены в кавычках, хотя для типа int это непривычно. Но Spring как всегда сам определяет какое значение с каким типом должно быть связано. Это происходит за счёт атрибута name. По названию бина Spring ссылается на объект класса и определяет тип этого объекта. В общем, всё. Теперь осталось лишь проверить наши обновления в классе Main:
Листинг 5
package org.example;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String ... args){
//Определяем контекст файл в котором содержатся прописанные нами бины
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//Получем бины, которые были определены в файле applicationContext.xml
HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);
hiringDepartment.displayInfo();
System.out.println("Citizenship: " + hiringDepartment.getCitizenship());
System.out.println("Salary: " + hiringDepartment.getSalary());
context.close(); //Контекст всегда должен закрываться
}
}
Тут особо ничего менять не надо. Только для получения результатов вызываем при помощи стандартного потока вывода геттеры класса HiringDepartment. В результате получаем следующий ответ:
Name: Alexa
Job: Middle Java developer
Citizenship: USA
Salary: 5000
Ок. Допустим у нас 10 таких работников, которые имеют такое же гражданство и получают такую же зарплату. И допустим компания решила повысить их зарплаты. Тогда придется вручную изменить все эти 10 значений. Это слишком скучно. А что если определить эти значения в отдельном файле и связать эти значения с бинами? Тогда нам бы пришлось всего лишь один раз в этом файле изменить значение, а остальные бины которые ссылаются на это значение, изменились бы автоматически. А попробуем - ка...
Для этого сделаем некоторые обновления в структуре проекта и в файле applicationContext.xml. Сперва в папке resources добавим новый файл с расширением .properties. Я назвал этот файл "myApp.properties". Теперь структура проекта приобрела следующий вид:

employee.citizenship="Russia"
employee.salary=6000
Слева от знака "=" находятся названия переменных (если их так можно назвать) , а справа значение этих переменных. Название вы можете дать как угодно, но как обычно со смыслом. И да, точка тут играет стратегическую роль, а не синтаксическую. Допустим у нас есть и менеджеры (manager), тоже со своими зарплатами. Тогда мы просто можем назвать эти переменные примерно так: manager.salary. То есть названия переменных не будет совпадать и мешать друг - другу.
А теперь давайте - ка обновим файл applicationContext.xml. Перед объявлением бинов должны прописать следующую строку:
<context:property-placeholder location="classpath:myApp.properties"/>
Тут мы определяем созданный нами файл для внедрения значений. А затем в атрибут value в двойных кавычках ставим знак доллара $ и в фигурных скобках {} пропишем название переменной из файла myApp.properties:
<property name="salary" value="${employee.salary}"/>
В результате Spring ищет эту переменную, получает её значение и прикрепляет её к объекту класса. Полный код выглядит так:
Листинг 6
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:myApp.properties"/>
<bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
<bean id="pythonDeveloper" class="org.example.PythonDevelopment"/>
<bean id="hiringDepartment" class="org.example.HiringDepartment">
<property name="development" ref="javaDeveloper"/>
<property name="citizenship" value="${employee.citizenship}"/>
<property name="salary" value="${employee.salary}"/>
</bean>
</beans>
Запускаем програмку:
Name: Alexa
Job: Middle Java developer
Citizenship: "Russia"
Salary: 6000
Как обычно, самый лучший способ изучения программирования - это программировать. Повторяйте изученное самостоятельно, попытайтесь апдейтить элементы, поиграйтесь с кодом. Короче, дерзайте.
А у меня на этом все. Спасибо за внимание!
Исходной код по ссылке
Мой GitHub
Присоединяйтесь на мой телеграм канал
Содержание курса
Продолжение следует...
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ