Как стать автором
Обновить

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

НЛО прилетело и опубликовало эту надпись здесь

Можно без него, вот только придётся изобретать велосипеды. Много велосипедов.

Велосипеды?
Простой сервис "JSON api JAX-RS -> вызов процедур БД Oracle"
Зачем тут Spring (Spring Container, например)?
И какие велосипеды нужно изобретать?

Транзакционность, например.

JPA используйте, если так хочется модно-молодежно. Зачем Spring для транзакций?

JPA — это Java Persistence API. Вероятно, вы имели ввиду JTA?


Спринг/Спринг Бут очень сильно упрощают разроботку.

НЛО прилетело и опубликовало эту надпись здесь

Типовой фреймворк под типовые задачи, да. Это относится к любым средствам разработки, к той же яве. Например, массив размером больше 2^32 средствами самого языка выделить нельзя, т.к. величина "размер массива" типа int.


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


Со Спрингом примерно так же.

если вы всю кухню без спринга напишите, то вы потратите гораздо больше времени на отладку.

Щас на любой вопрос по спрингу есть ответ в стек оверфлоу
НЛО прилетело и опубликовало эту надпись здесь
Транзакционность, например.

Эта разница принципиально, что бы для нее тянуть SpringBoot библиотеки?
И бины только ради jdbcTemplate?


Классический Spring подход к вызову процедуры:


@Transactional
  public void putSomething(String s) {
    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
            .withCatalogName("BBB")
            .withFunctionName("putSSS")
            .declareParameters(
                    new SqlParameter("p$SSS", Types.VARCHAR),
            );
         SqlParameterSource in = new MapSqlParameterSource().addValue("p$SSS", s);
      jdbcCall.execute(in)
  };

Cильно лучше (короче и понятнее) чем напрямую с jdbc (и пулом конеектов от Oracle)? С явным commit? там где это МНЕ нужно.


 public void putSomething(String s) {
  try (Connection conn = pds.getConnection()) {
    try (CallableStatement stmt = conn.prepareCall("begin BBB.putSSS(?); end;")) {
     stmt.setString(1, s);
     stmt.executeUpdate();
     conn.commit();
    }     
  }
}

А кто из здесь читающий сможет сразу сказать как выполнить тонкую специфичную настройку пула коннектов и управлять им динамически в Spring? Все скрыто "магией" и приходится копаться в Интернете и в конечном итоге в Spring исходниках, что бы понять как...


SpringBoot удобен там где он удобен… Не обязательно его пихать везде. Мир им не ограничивается. guice для некоторых целей удобнее и проще чем Spring.
Не понимаю этого хайпа по спрингу. Один из инструментов. Не икона на стену.

А кто из здесь читающий сможет сразу сказать как выполнить тонкую специфичную настройку пула коннектов

1) не вижу в вашем примере тонкой или какой-то особой настройки пула коннектов. Всё очень рутинно, и как раз от этой повседневности и призван избавить Спринг.
2) ваш пример предполагает, что сложная логика вынесена в хранимку в БД (кстати, как отлаживать её будете?)
3) если вы очень переживаете о производительности, то в случае с БД 90% времени скорее всего придётся на сетевое взаимодействие с базой и исполнение запроса, так что отказ от фрейворка не даст какого-то сверхвыигрыша.


Я всё ещё не вижу внятной аргументации в пользу отказа от Спринга. Всё сводится к "спринг плохой потому что потому".


Не понимаю этого хайпа по спрингу.

Если вы внимательно прочитаете статью, то увидите, что она не претендует на какое-то откровение или на роль Евангелия от Холлера. Это некоторая сумма опыта, и описание граблей с целью избавить от боли ещё не наступивших на них, не более того.

1) не вижу в вашем примере тонкой или какой-то особой настройки пула коннектов. Всё очень рутинно, и как раз от этой повседневности и призван избавить Спринг.

Причем тут мой пример. Я им иллюстрировал конкретную простую задачу (озвучил в первом посте). Решение которой не отличается ни объемом ни сложность в обоих примерах. Мое замечание, к этому конкретному примеру прямого отношение не имеет.


А мой комментарий в конце… Я просто точно знаю, что любой шаг вправо-влево от типовой задачи — это долгий поиск решения. И зачастую копание в исходниках Spring.


2) ваш пример предполагает, что сложная логика вынесена в хранимку в БД (кстати, как отлаживать её будете?)

Там где я сейчас работаю, традиционно, слой бизнес логики целиком в БД (PL/SQL). Все работа через API процедур/функций и представления (view)
Есть плюсы… есть минусы такого подхода. Но это отдельная тема. Да и какая разница. Так есть.


так что отказ от фрейворка не даст какого-то сверхвыигрыша.

Не даст. Но я не это хотел сказать… А то, что задачи могут решаться разными способами. И утверждение, что Spring ОБЯЗАТЕЛЬНО дает какой тов выигрыш — это заблуждение. И то, что "велосипед изобретать" — это плохо. Это то же заблуждение. Иногда нужно. Как минимум, нужно уметь.


Я всё ещё не вижу внятной аргументации в пользу отказа от Спринга. Всё сводится к "спринг плохой потому что потому".

Где Вы увидели призыв отказаться от Спринга? Основной посыл — использовать то, что подходит к конкретной задаче.


Я видел, например, решения, когда ради 3-х (!) вызовов БД (однотипные select из view) в приложение пихался Hibernate! А ничего, что он +5 сек при старте отъедает на моем рабочем компе… И все что нужно, это "изобрести велосипед" из нескольких строчек кода (ResultSet в Map<Map<String, Object>>). Вместо нудного описания Entity классов..


Из за этого я же не буду призывать отказаться от JPA и конкретных реализаций JPA.

+5 сек

да не может быть

Если сущностей сотни-полторы, то легко. А если есть ещё и Spring Data, то добавьте время проверки запрсов (они проверяются при поднятии контекста). Я об этом ранее писал: https://habr.com/ru/post/439918/


Выпиливание лишней зависимости даёт -20 секунд ко времени запуска приложения.

спринг дата это уже другая история, во говорили про хибернейт

да и разве не плевать, если даже пару минут стартует.

если вы для ручного теста постоянно перезапускаете приложение, то переходите на автотесты

сотни-полторы

переходите от монолита к микросервисам, или хотябы подробите монолит.

Spring Data JPA работает поверх хибернейта. Использовать Хибернейт сам по себе в 2019 г смысла нет, кмк.

Ещё как может. Я видел проект, в котором основное приложение запускалось ок. 15 минут, и 12 минут как минимум из этого времени съедал Hibernate.

>> Всё сводится к «спринг плохой потому что потому».

Вам же прямо сказали — чуть в сторону и сразу всё очень плохо. Это что, достоинство?

Нет проектов, где не нужно «в сторону». Просто нет. Детский сад, понятно, исключаем. Поэтому любой, кто погружается в спринг, всегда будет обязан долго и нудно изучать его недра, а потом через известное место подстраиваться под них, просто что бы выполнить поставленную задачу. И это — очень напрягает. Вам нравится? Ну ради бога. Но я вот — не мазохист.
чуть в сторону и сразу всё очень плохо

Я работаю со Спрингом уже 6 лет и приходилось решать довольно головоломные задачи. Иногда приходилось лазить в кишки, да. В 1 особом случае из 100. Во всех остальных хватало яндекса и СО.


Поэтому любой, кто погружается в спринг, всегда будет обязан долго и нудно изучать его недра

Без примеров (пока я не увидел не одного) всё это общие слова. Как правило (сужу по своему опыту) человек, лезущий в кишки в 9/10 невнимательно прочитал документацию. А она в Спринге удивительно хороша, покрывает почти все тонкости.


Опять же накоплен огромный опыт, который позволяет 99 задач из 100 решить одним поисковым запросом.


Хотите спорить — приводите примеры из жизни.

>> Я работаю со Спрингом уже 6 лет и приходилось решать довольно головоломные задачи. Иногда приходилось лазить в кишки, да. В 1 особом случае из 100. Во всех остальных хватало яндекса и СО.

Да, за 6 лет можно многое изучить. Вот поэтому вам и кажется, что «В 1 особом случае из 100». Я же, когда пробовал это чудо, получил гораздо больше проблем. И именно в начале пути. То есть если бы я усидчиво 6 лет изучал, как мне решить порождённые спрингом проблемы при помощи спринга, то наверняка сегодня я бы их почти все решил. Но я сделал другой выбор — отказался от спринга. Хотя да, поэтому меня нельзя назвать экспертов по нему, ну и к моему мнению можно не прислушиваться. Только вы знаете, потом мне было приятно ощущать отсутствие того самого напряжения, которое я почувствовал при попытке решить простые проблемы при помощи спринга.

>> Без примеров (пока я не увидел не одного) всё это общие слова.

Вам другие участники дали несколько примеров. Там ясно видно — ненужные приседания можно устранить, просто отказавшись от спринга. Разве это не так?

>> Как правило (сужу по своему опыту) человек, лезущий в кишки в 9/10 невнимательно прочитал документацию. А она в Спринге удивительно хороша, покрывает почти все тонкости.

На счёт качества документации — ну не знаю. Вот их сайт, искал на странице с гайдами по ключевому слову «архитектура». Нашёл одну (одну!!!) ссылку, и та — про безопасность. Внимание, вопрос — а где архитектура? Как без понимания архитектуры решать сложные вопросы? И как можно говорить, что «А она в Спринге удивительно хороша», когда там нет информации о самых важных вещах?

>> Опять же накоплен огромный опыт, который позволяет 99 задач из 100 решить одним поисковым запросом.

Опять же — ну не знаю, что у вас там за опыт. Опыт гугления (если речь о нём) приобретается за пару дней. А вот опыт изучения, понимания, и применения на практике информации по спрингу — это нечто большее, для такой задачи 99% решений не нагуглить. Хотя я не знаю, что у вас за задачи. Теоретически, всё то, что на 99% решается гуглением — это тривиальнейшие задачи. Хотя с другой стороны, если вы о поиске способа обхода внезапно возникающих проблем со спрингом, то сама необходимость постоянно гуглить (в 99% случаев) говорит о невозможности как-то осмысленно разобраться с происходящим внутри. И количество ответов по спрингу на СО — тоже свидетельство в пользу сложности сабжа. Там реально миллионы вопросов. Хорошо, что кто-то на них успел ответить, но может было бы лучше, если бы используемая библиотека не предполагала миллионы (!!!) вопросов? То есть не была такой запутанной и непрозрачной. Ну а если она запутанная и непрозрачная — зачем вообще её использовать? Только потому, что миллионы программистов очень часто ходили по этим граблям и смогут ответить на некоторые (не все, даже в вашей практике) вопросы?

В целом повторю своё впечатление — непрозрачно, много возни в нетривиальных случаях, а в тривиальных случаях код получается проще вообще без спринга. Хотя да, есть множество ответов на СО, есть толпа поимевших опыт работы с изделием (неглубокий, чаще всего). Если плыть по течению и стараться быть в толпе — ну ладно, тогда скорее выбор в пользу спринга. Но если понятие «архитектура» всё же важно для вас и вы не готовы постоянно прогибаться под чужой шаблон, по сути отдавая архитектуру на откуп этому шаблону, то я бы вам советовал подумать перед выбором такого инструмента.

Ну а тем, кто «уже 6 лет» и более — да, им остаётся только лишь монетизировать потраченное время путём расширения толпы фанатов. К счастью, меня сия участь миновала.

В том-то и дело, что приведённый выше код — это типичный бойлерплейт, от которого спасает Спринг. Примеров, когда обычных средсв Спринга не хватает, не привёл никто. Только общие фразы и намёки.

Я вас прошу не путать SpringBoot, и например JdbcTemplate. Во втором нет ровным счетом никакой магии, исходники его легко читаются, и более чем понятны.
Очень полезная статья. Раньше выносил преобразование dto просто в отдельный /@Component, теперь конвертерами начну пользоваться

Конвертер тоже компонент ;)

Понятно дело, только с Converter<> явное указание на поведение появляется

Да, в этом его ценность. Кстати, если у вас "восьмёрка", то можно написать что-то вроде


@Component
class LongToString implements Function<Long, String> {
}

@Component
class StringToLong implements Function<String, Long> {
}

И использовать так же:


@Component
@RequiredArgsConstructor
public class DI {
  private final Function<Long, String> longToString;
  private final Function<String, Long> stringToLong;

}

Думаю, будет работать.

Думаю, будет работать.

Работать то будет, но если захочешь средствами IDE перейти к реализации, то будут проблемы.

С Converter удобно использовать
 org.springframework.core.convert.ConversionService


Примерно так:
User user = conversionService.convert(userObject, User.class)


Spring сам найдет нужный Converter (по типу объекта userObject и target class) и вызовет converter.

Спасибо за ваш комментарий! Во-первых, я не знал об этом, во-вторых, ваш коммент один из немногих по существу заметки.

Извините, а чам вам мапстрикт не нравится? Возможности у него достаточно обширные, а разница в имени полей легко настраивается с помощью "source" и "target".

Если полей много и названия разные, то интерфейс по объёму кода может получиться такой же, как и самописный преобразователь.

а как в случае разных имен полей это делает спринговский конвертер? Откуда он знает, что куда?

Не знает, нужно ручками писать. Поэтому когда имена полей совпадают, то лучше марстракт использовть.

А если не найдёт, то упадёт в рантайме.
Именно поэтому мы у себя используем свои мапперы, которые являются спринговыми бинами и обеспечивают типобезопасность на этапе компиляции. Нет маппера — ошибка компиляции.
Самое первое что мы начали делать плохо со спринг, это втаскивать конфигурацию в компилируемые классы. Да конечно теперь spring boot запускается и настраивается с той же скоростью что и php-приложение. Но теперь что-то сложнее параметров properties разрулить не удастся. А если по старинке выносить все в xml файлы начинает бомбить у тех кто привык к @Configuration

Компилирйемость настройки — это скорее преимущество, т.к. ошибки времени исполнения превращаются в ошибки компиляции. Опять же, "Идея" умеет анализировать структуру проекта и прямо в классах указывать на возможные ошибки (неразрешенные зависимости, к примеру).

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

21 век, а спринг все еще не умеет в конфигурацию из разных источником сливать? То есть настройки в классе нельзя перебить переменными окружения?

Насколько я помню нет. Дополнительно если программисты не озаботились брать из properties то никак это не поменять, только пересобирать.

Умеет, например тот же порт можно передать из коммандной строки.

Порт относится к встроенному серверу, так что я не удивлен. А вот например конфигурацию подключения к бд?

1) Для этого есть профили: набор файлов application-dev.yml, application-test.yml, application-int.yml, application-prod.yml и т.д.


2) Если вам лень вносить изменения в файлы, то в build.gradle прописываете что-то вроде


def psqlTestPort = project.hasProperty('psqlTestPort') ? project.getProperty('psqlTestPort') : '54321'
def psqlTestHost = project.hasProperty('psqlTestHost') ? project.getProperty('psqlTestHost') : 'localhost'

а в *.yml


spring:
  datasource:
    jdbc-url: jdbc:postgresql://${psqlTestHost}:${psqlTestPort}/postgres?currentSchema=AUTO

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

Хорошо усложняю задачу. Есть spring security и набор url надо на часть выдать доступ на часть нет. Как будете задавать через property?
А можно просто spring security положить в xml и получить ровно тоже самое без дополнительного велосипеда. Собственно это мне и не понравилось в @Configuration. Для простых случаев ок. Когда сложные случаи писанины получается больше чем в случае xml которое он должен заменять.

Можно, только плюс ява-конфига в том, что ошибки/очепятки очень часто становятся ошибками компиляции. А у вас битый xml-конфиг упадёт только при запуске.

В случае spring security нет. Пути лежат прям строками. И много что на уровне компиляции не отловится, особенно если берется из properties. Вот и получается что для простых случаев все хорошо, для сложного начинается ой.

Подавляющее большинство приложений, написанных с нуля, используют именно ява-конфиг. ИМХО, распространённость технологии/подхода есть производная от её/его удобства/полезности.

Потому что в документации написано делай так :) Насчет удобства, зависит от. Я привел пример spring security как только там чуть сложнее стандартных схем авторизации, там конфигурация начинает выглядеть не очень прям скажем.

Документацию пишут разработчики фрейворка, имеющие огромный опыт его разработки, внедрения, поддержки. Вы задумывались, почему вообще появился ява-конфиг? Ведь xml-конфиг уже существовал. Но разработчики почему-то заморочились и сделали другое решение.


Если взять ваш секьюрити xml, и выкусить из него описание какого-нибудь бина, то ошибку вы не увидите до запуска приложения.


А если написать ява-конфиг, при чём не передавать зависимости паарметрами в метод, а использовать вызов (как я показал в статье), то выкусывание бина превращается в ошибку компиляции и красный редактор в "Идее".


Это же касается других примеров из статьи. Пакеты и имена классов можно описать в xml-е, ямле и свойствах, вот только опечатка не проявится до запуска. В случае использования классов ошибка в его наименовании/импорте становится ошибкой сборки.

Потому что банально надо было обеспечить более быстрый и удобный запуск для программистов. А в xml сейчас умеет все меньше и меньше программистов. Плюс надо было чтоб запускалось как php. Да этого достигли.

И да нормальная ide вам еще на процессе валидации покажет, что в xml файле написана ерунда.

Если собирать проект без среды разработки, то ошибка компиляции всё равно станет видна ещё до запуска. В случае с хмл ошибка станет видна только после запуска.


Потому что банально надо было обеспечить более быстрый и удобный запуск для программистов.

Потому что ява более гибкая, чем хмл. Как вы опишите типизацию бина в хмл-е? Никак. А в яве это раз плюнуть, и опять же ошибка станет ошибкой сборки, а не времени исполнения.

Я вам приводил пример когда будет не видна. К примеру при ошибке в написании драйвера jdbc в properties упадет точно так же на стадии запуска.

Потому что ява более гибкая, чем хмл. Как вы опишите типизацию бина в хмл-е?

Может покажете где вы такое в конфигурации используете?

Ну и да xml изначально декларативен, а вот в java для декларативности кода добавлены аннотации. В итоге для декларативности приходится их указывать и дописывать. В итоге конфигурация может сильно удлиняться в сложных случаях.

Простой пример мне надо было несколько view теплейт движков использовать. Один для страничек еще 4 было для различных документов и отчетов. В случае xml это было 8 объявленных bean прям в xml с указанием 5 разных viewClass и указанием приоритетов. Как подобное напилить в конфигурации и сколько там будет аннотаций?

Я без понятия, сколько в итоге получится аннотаций, так как с MVC почти не работаю.


Я констатирую факт: настройка проекта с помощью кода стала де-факто стандартом. Загрузка классов работает несравнимо быстрее чтения и разбора ХМЛ-а, а настройки, привязанные к профилям выносятся в application-*.yml. Это сегодняшний день. ХМЛ — день вчерашний за редкими исключениями.

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

Загрузка классов работает несравнимо быстрее чтения и разбора ХМЛ-а, а настройки

У вас там xml в пару килобайт укладывается, вы о чем вообще? Я вон переключился на @Configuration аннотации и никакой разницы по скорости нет. Там дольше тот hibernate с spring jpa стартует.
Удобство @Configuration перед xml в том, что для программиста не нужно «переключать контекст».
Т.е. он пишет настройки контекста как код.
И при этом не надо учить новый язык.
При это можно ввести логику в создание контекста на понятном ЯП (Java).
Это же является обратной стороной медали. Во первых проще делать hardcode. Простой пример я приводил выше с spring security и списком url. При этом документация прямо говорит пишите кодом.
А раз проще, то он и делается.

Дополнительно так-как это все же код, а не декларативные объявления что-то более сложное, требует больше писанины.
Э-э-э вообще то в Spring можно все сконфигурировать декларативно через аннотации.

А XML это жесть.
Начинал как раз с 3-го Spring с конфигурированием xml.
Километровые простыни, в которых черт ногу сломит.
Процитирую себя же

Простой пример мне надо было несколько view теплейт движков использовать. Один для страничек еще 4 было для различных документов и отчетов. В случае xml это было 8 объявленных bean прям в xml с указанием 5 разных viewClass и указанием приоритетов. Как подобное напилить в конфигурации и сколько там будет аннотаций?

Если надо дам вам xml файл и вы попробуете его завернуть в аннотации.
А XML это жесть.

Но стартует быстрее, чем аннотации ))

Существуют ли бенчмарки, подтверждающие это утверждение?

Ну оно может стартовать быстрее банально из-за того что там контекст грузится напрямую без конфигурационных оберток.
может

А может и нет. Поэтому я и спросил про бенчмарки.

Честно говоря, не знаю. Я делаю такой вывод из того, что конфигурация с аннотациями скорее всего будет делать component scan, что не очень быстро.

Нет ни какой проблемы в java конфигурации настроить права на список адресов, взятых из файла properties. В этом то и сила java конфига, что можно наложить некую логику на настраиваемые компоненты. Я думаю или вашим программистам не полностью сообщили требования или они у вас ленивые. Нужно лишь немного кода написать. Хардкодить изменяемые параметры в коде это плохо.
Соглашусь, что через xml такая задача будет решаться проще. Не нужно дополнительных properties файлов и кода для считывания из них значений. Но опять же спринг сильно упрощает работу с properties файлами и сложностей там не должно быть.
Опыт работы есть и с xml и java конфигами. Мой выбор java конфиг.
Она будет решаться заметно проще и никакого boilerplate кода писать не придется. Когда конфигурация простая, то да через аннотации все красиво. Но когда он сложнее становится, то все становится хуже. И при этом люди уже не знают про xml и просто пишут кучу boilerplate кода.
И при этом люди уже не знают про xml и просто пишут кучу boilerplate кода.

Напишите статью на хабр с примерами ваших задач, которые проще решить с помощью ХМЛ. Серьёзно, я не подкалываю. Напишите, а сообщество посмотрит и оценит.

Мне отмотать на 2010 год? Про view я писал уже
habr.com/ru/post/101546

Если их надо под пихнуть более одного то возникает ой в spring boot.
Любую пропертю можно передать в командной строке. В том числе подключение к БД.
Таких программистов, которые «не озаботились», надо ссаными тряпками хреначить.))
Тут, к сожалению, общая проблема с квалификацией кадров. На любой технологии.
Все настраиваемые параметры выносятся в стандартный yml конфиг.
Стандартные спринговые модули, типа БД и прочих, все имеют конфиги из коробки. Никаких проблем. Администраторы прекрасно меняют, что надо.
Spring Boot умеет подтягивать настройки из семнадцати разных источников прямо из коробки. Достаточно вынести то что хочется менять без перекомпиляуии в проперти. Если хочется влиять не только на проперти, но и на создаваемые бины, можно поиграться с профилями и аннотациями Conditional*.

Почитайте документацию. 21 век же.

Про конфиг серевер почитайте.

В книге лонга «джава в облаке» описано более 10 источников, как можно пропертя вносить
Мы у себя решили эту проблему следующим путем:

public interface Settings {

    String property(String key);

    default String property(@NonNull String key, String defaultValue) {
        String value = property(key);
        return StringUtils.isBlank(value) ? defaultValue : value;
    }

    void setProperty(String key, String value);

    default void setProperty(@NonNull String key, @NonNull Object value) {
        setProperty(key, value.toString());
    }
	
	// default implementations like getPropertyAsInt, getPropertyAsList, etc
}

@Service("settingsBasedOnApplicationProperties")
public class SettingsBasedOnApplicationProperties implements Settings {

    private final Environment applicationProperties;

    @Autowired
    public SettingsBasedOnApplicationProperties(Environment applicationProperties) {
        this.applicationProperties = applicationProperties;
    }

    @Override
    public String property(@NonNull String key) {
        String value = applicationProperties.getProperty(key);
        return value == null? "" : value;
    }

    @Override
    public void setProperty(String key, String value) {
        throw new UnsupportedOperationException(
                "It's readonly service."
        );
    }
}

@AllArgsConstructor
@Service("settingsBasedOnDatabaseProperties")
public final class SettingsBasedOnDatabaseProperties implements Settings {

    private final SettingsRepository settingsRepository;

    @Override
    public String property(@NonNull String key) {
        Setting value = settingsRepository.findOne(key);
         return value == null ? "" : value.getValue();
    }


    public void setProperty(@NonNull String key, @NonNull String value) {
        settingsRepository.save(new Setting(key, value));
    }
}

@Service("settings")
public class SettingsImpl implements Settings {

    private final Settings applicationProperties;
    private final Settings databaseProperties;

    @Autowired
    public SettingsImpl(
            @Qualifier("settingsBasedOnApplicationProperties") Settings applicationProperties,
            @Qualifier("settingsBasedOnDatabaseProperties") Settings databaseProperties) {
        this.applicationProperties = applicationProperties;
        this.databaseProperties = databaseProperties;
    }

    @Override
    public String property(String key) {
        return StringUtils.isBlank(applicationProperties.property(key))
                ? databaseProperties.property(key)
                : applicationProperties.property(key);
    }

    @Override
    public void setProperty(String key, String value) {
        databaseProperties.setProperty(key, value);
    }
}


Таким образом, мы делаем Autowired для Settings и получаем значение проперти. Если она есть в конфиге (.properties файл или .yaml) или в environment variables — берем от туда. Если нет — берем с базы данных. Логику можно поменять и сделать значение в базе данных «главным». Похожим путем можно инкапсулировать получение значений с любых источников.
А можно просто контекст из xml файла подключить :)
С точностью до наоборот.
Конфигурирования бинов в классе, это очень хорошо.
Не нужно изучать два языка Java и XML.
С учетом текущей ориентированности Spring'а на микросервисы, это вообще замечательно.
Т.к. настройки по умолчанию, дают возможность просто добавить зависимость и получить уже готовый функционал, без написания портянки XML.
Ох. В сложных случаях это приводит к ухудшению читаемости и большему размазыванию настройки конфигурации по коду. Если следовать документации надо @Configuration раскладывать по раздельным файлам как это делалось в xml. Ну или класть несколько классов в один файл, что тоже не очень хорошая затея.

В случае если у вас микросервис и все необходимые конфигурации укладываются в то что предлагается разработчиками все хорошо и более менее прилично.
Опять же с точностью до наоборот.
God object — это антипаттерн.
Если очень сильно хочется все настройки можно собрать в один пакет.
Если у вас монолитный монолит.
А так, я лично предпочитаю разделять монолит по отдельным модулям.
А потом в одном модуле, просто прописыванием зависимостей, собирать артефакт.
Я в курсе, что класть конфигурацию в один километровый объект так себе затея. Просто почему-то папочку config забыли в документации. Кладите в корень все конфиги ну тоже так себе затея.
Если делить проект по модулям, то норм.
Хотя я обычно выношу конфиги в модулях в отдельный пакет config.
Там же лежат классы для properties
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории