5.1.5 Использование специальных значений свойств
При настройке свойств вы не ограничиваетесь объявлением их значений как жестко закодированных строковых и числовых значений. Вместо этого можно получить их значения из других свойств конфигурации.
Например, предположим (по какой-либо причине), что вы хотите установить свойство с именем greeting.welcome на основе значение другого свойства с именем spring.application.name. Для этого при настройке приветствия можно использовать маркеры-заполнители $ {} для задания свойства greeting.welcome:
greeting:
welcome: ${spring.application.name}
Вы даже можете использовать этот заполнитель как часть другого текста:
greeting:
welcome: You are using ${spring.application.name}.
Как вы уже видели, настройка собственных компонентов Spring со свойствами конфигурации позволяет легко вводить значения в свойства этих компонентов и настраивать автоконфигурацию. Свойства конфигурации не являются эксклюзивными для bean-компонентов, которые создает Spring. Приложив небольшое усилие, вы можете использовать свойства конфигурации в ваших собственных bean-компонентах. Посмотрим как.
5.2 Создание ваших собственных свойств конфигурации
Как я упоминал ранее, свойства конфигурации - это не что иное, как свойства bean-компонентов, предназначенных для получения конфигураций из абстракции среды Spring. Что я не упомянул, так это то, как эти компоненты предназначены для использования этих конфигураций.
Для поддержки внедрения свойств конфигурации Spring Boot предоставляет аннотацию @ConfigurationProperties. При указании аннотации в любом Spring bean-компонен туказывается, что свойства этого bean-компонента могут быть внедрены из свойств среды Spring.
Чтобы продемонстрировать, как работает @ConfigurationProperties, предположим, что вы добавили следующий метод в OrderController, чтобы вывести список прошлых заказов аутентифицированного пользователя:
@GetMapping
public String ordersForUser(
@AuthenticationPrincipal User user, Model model) {
model.addAttribute("orders",
orderRepo.findByUserOrderByPlacedAtDesc(user));
return "orderList";
}
Наряду с этим вы также добавили необходимый метод findByUser() в OrderRepository:
List<Order> findByUserOrderByPlacedAtDesc(User user);
Обратите внимание, что этот метод хранилища (репозитория) имеет в названии OrderByPlacedAtDesc. Часть OrderBy указывает свойство, по которому будут упорядочены результаты - в данном случае, свойство placeAt. Desc в конце заставляет упорядочение быть в порядке убывания. Таким образом, список возвращаемых заказов будет отсортирован от самых последних до наименее последних.
Этот метод контроллера может быть полезен после того, как пользователь разместил несколько заказов. Но это может стать немного громоздким для самых заядлых ценителей тако. Несколько заказов, отображаемых в браузере, полезны; бесконечный список из сотен заказов - это просто шум. Допустим, вы хотите ограничить количество отображаемых заказов самыми последними 20 заказами. Вы можете изменить ordersForUser()
@GetMapping
public String ordersForUser(
@AuthenticationPrincipal User user, Model model) {
Pageable pageable = PageRequest.of(0, 20);
model.addAttribute("orders",
orderRepo.findByUserOrderByPlacedAtDesc(user, pageable));
return "orderList";
}
вместе с соответствующими изменениями в OrderRepository:
List<Order> findByUserOrderByPlacedAtDesc(User user, Pageable pageable);
Вы изменили сигнатуру метода findByUserOrderByPlacedAtDesc(), чтобы принимать на вход Pageable в качестве параметра. Pageable - это способ Spring Data выбрать некоторое подмножество результатов по номеру страницы и размеру страницы. В методе контроллера ordersForUser() вы создали объект PageRequest, который реализовал Pageable для запроса первой страницы (нулевой страницы) с размером страницы 20, чтобы получить до 20 самых последних размещенных заказов для пользователя.
Хотя это работает фантастически, мне немного неловко, что вы жестко закодировали размер страницы. Что, если позже вы решите, что 20 - это слишком много заказов, и вы решите изменить его на 10? Поскольку он жестко запрограммирован, вам придется пересобрать и повторно развернуть приложение.
Вместо того, чтобы жестко задавать размер страницы, вы можете установить его с помощью пользовательского свойства конфигурации. Сначала вам нужно добавить новое свойство с именем pageSize в OrderController, а затем аннотировать OrderController с помощью @ConfigurationProperties, как показано в следующем листинге.
Листинг 5.1 Включение свойств конфигурации в OrderController
@Controller
@RequestMapping("/orders")
@SessionAttributes("order")
@ConfigurationProperties(prefix="taco.orders")
public class OrderController {
private int pageSize = 20;
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
...
@GetMapping
public String ordersForUser(
@AuthenticationPrincipal User user, Model model) {
Pageable pageable = PageRequest.of(0, pageSize);
model.addAttribute("orders",
orderRepo.findByUserOrderByPlacedAtDesc(user, pageable));