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

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

«Зайди на комп продакшна, открой папку JBoss/server/default/deploy найди там файл idi.ear и открой его.… В ней есть applicationContext.xml… найди там SchedulerFactoryBean и чуть ниже есть datacarTrigger.»

Ну у вас и память!!!
Дык :) Если каждую неделю это делаешь, то это не так сложно :)
что, продакшн каждую неделю падает?!?!
Дело не в том, как часто падает, дело в том, что альтернатива была ехать в пятницу ночью обратно на работу. И ради того, что бы не ехать можно и не такое вспомнить. :)
На самом деле все просто. Оно везде одинаково да и все :) У меня в моих проектах обычно конфигурационный xml всегда лежит в одном и том месте.
У меня так и осталось ощущение что заметная часть решаемых проблем искуственно создана.
Да как бы DI — это в принципе для мазохистов. То есть это не просто способ выстрелить себе в ногу, это способ стрелять себе в ногу три раза в день короткими очередями в автоматическом режиме %)
Есть такой чувак, Jordan Zimmerman. В 2009 году он решил вести блог, который будет разоблачать жидомассонский заговор популярные заблуждения в архитектуре приложений. Написал много смелых мыслей про зло систем сборки (надо собирать только RAD-ом), unit тесты (QA должен работать, а не перекладывать свою работу на программистов), комментарии (если нужны комментарии — значит код -гавно) и DI.
Потом, конечно, со стыда потёр всё. Такие дела.
Я не знаю, что это за чувак такой. А за DI я знаю несколько очень простых вещей, неоднократно проверенных на практике в крупных проектах:

1) Всё, что может быть проверено в compile time, должно быть проверено в compile time. DI фактически выносит огромное количество таковых проверок, особенно интеграционных, которые могут быть прозрачно сделаны компилятором, на этап тестов или, того хуже, runtime.

2) Код должен быть однозначен и прозрачен. Это вопрос стоимости его поддержки и качества самого кода в целом. То есть, посмотрев на код, программист должен сходу видеть, как он работает и зачем он сделан. DI прямо этому противоречит, потому что смотря на код с DI сразу возникают вопросы относительно объектов и свойств, которые возникают ниоткуда, создаются непонятно кем, где и когда и непонятно как уничтожающиеся. И это не вопрос понимания DI. Это вопрос того, что взглянув на код с DI вы не имеете возможности его однозначного понимания того, как он работает.

3) Вопрос повторного использования кода и удобства написания тестов (mocks etc) — это вопрос архитектуры и структуры кода, а не наличия или отсутствия DI.

4) DI — это привнесение в код огромного медленного титаника, который не даёт никаких выраженных бенефитов в серьёзном продакшене, кроме кучи геморроя с диагностикой ошибок из разряда «какого чёрта у меня это свойство не проинициализировалось».
Ну, вот он примерно это и писал, да. Потом пошел работать в Netflix, и сразу всё стёр. А то мало-ли, коллеги увидят, стыда не оберешься.
Да, дерьмо — штука заразная. Некоторые как приходят в место, где его едят половниками, их прям так и тянет попробовать. Миллионы мух же не могут ошибаться, это же вкуснятина!
Ну, я бы не смотрел на количество, а смотрел бы на результат. Shop.com, в котором, под руководством Джордана не было DI, склеил ласты в том самом году. У Нетфликса, в который Джордан сбежал с тонущего корабля, и где ему объяснили, как надо писать код, все, слава Богу, в порядке по сей день.
А с чего вы взяли, что к фактам склеивания ласт shop.com или процветания netflix DI имеет хоть какое-то отношение?
Ну, я даже не знаю? Главный архитектор проповедует говнокод -> на говнокоде магазин то лежит, то тормозит -> в магазине никто не хочет покупать -> магазин — тю-тю?
Он кстати уже успел еще пару раз поменять работу :)
Данный факт абсолютно никак не опровергает, что все написанное относительно DI верно. DI — это паттерн проектирования, а не фреймворк. Никто не запрещает сделать свой контекст с методами: MyContext.getBean() без всякого спринга. Работать будет также, весить на несколько тонн меньше, магии ноль — соответственно надежней и читабельней.

Там, где есть реальная помощь фреймворка, так это при проксировании бина. При помощи декларативного AOP легко перехватить вызов методов. Реально же это необходимо практически в одном случае — для декларативного контроля за транзакциями. Это отнюдь не значит, что нельзя то же самое сделать и без фреймворка, или это будет на порядок сложнее. Кроме того, что декларативные транзакции — это вообще сомнительный паттерн.

Spring же — это не только и не столько IoC контейнер, сколько библиотека различных полезных и не очень надстроек вокруг него, каждая из которых представляет собой паттерн и его имплементацию для решения определенной проблемы (иногда спровоцированной самим фреймворком). Поэтому спринг так популярен.

В реальных же проектах никто не задумывается зачем им нужен Spring. Его сразу ставят «по дефолту», потому что это модно, стильно и все так делают. Даже в проекте из четырех бинов и базы данных.
Я боюсь, ваш пламенный спич немного не по адресу. Хочу напомнить, что в данной статье речь идет о сравнении разных контекстов в Спринге, а не обсуждается нужен ли DI вообще, и Спринг в частности.

Заранее согласен, что DI нужен не всегда (когда я пишу Hello World, наверное, обойдусь без DI), и что Спринг — не единственный DI framework в мире (это как-бы факт). Какое отношение эти два тезиса имеют к спору какой контекст лучше подходит когда при использовании Спринга?
Можно поподробнее, с примерами?
Код должен быть однозначен и прозрачен. Это вопрос стоимости его поддержки и качества самого кода в целом.

А как тут мешает DI? По мне наоборот помогает. Склеивание кода происходит только по DI, это упрощает архитектуру приложения. Если программист знает как работает DI то найти где что откуда вызвалось ему большой проблемы не составляет. Причем даже программисту который это проект видит в первый раз.

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

Ой да ладно. Правила откуда и как генерируются а так же появляются объекты четко прописаны в DI.

Вопрос повторного использования кода и удобства написания тестов (mocks etc) — это вопрос архитектуры и структуры кода, а не наличия или отсутствия DI.

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

DI — это привнесение в код огромного медленного титаника, который не даёт никаких выраженных бенефитов в серьёзном продакшене

Можно пояснить что там за такой огромный медленный титаник и откуда он берется?
Использование DI оно не от хорошей жизни. А от того что к тебе в любой момент могут прийти и сказать а нам надо так. В случае наличия DI многое такое можно сделать существенно проще.
Тонны конфига в xml перекачуют в тонны конфига groovy. Я надеюсь с этим никто не спорит — количество бинов-то от этого не поменяется. Только при этом ретивые девелоперы нафигачат туда еще и логики. Т.е. будет та же самая тонна xml, записанная чуть лаконичнее, но еще и с императивной логикой.

У меня есть проект, где конфигов эдак под файлов 20 размазанных по либам, но с главным конфигом в основном приложении. Я могу видеть в этом конфиге overview компонентов в системе. Плюс я обычно навигируюсь в Идее по ним, она хорошую поддержку имеет таких конфигов. И тут я наткнусь на теже 20 грувевых файлов (я еще не уверен что идея их поддерживает), а там будет еще и логика какая-то по инциализации чего-нить прописана, что только в рантайме и определяется. Короче мне уже страшно.

Про аннотации тоже кстати интересно — одно дело когда аннотациями отмечены бины типа контроллеров, которые нам не особо интересны с точки зрения их взаимосвязей с другими бинами (с другой стороны я бы хотел видеть RESTинтерфейс более наглядно, чем размазанным по методам контроллеров). Другое дело когда фэктори-на-фэкторях-фэкторями-погоняет. Тут я точно хочу видеть декларативный подход.

Короче все упирается в декларативный подход управления зависимостями vs императивный. Мне не очень нравится тренд фигачить все императивным кодом, не разбираясь где что будет в тему, а где нет.

ЗЫ Я смотрю вы к нам с Барухом скоро едете? Какой-то прямо праздник статей от вас на хабре :)
Ну, если так рассуждать, то вообще допускать к компу программера надо только после всестороннего тестирование на адекватность, IQ и прочие радости.
Ибо дебил в любой системе, любой технологии и любым инструментом отстрелит себе обе ноги, да еще и соседям достанется.
Нет смысла рассматривать технологии с этой точки зрения. От ретивых девелоперов никто не застрахует в любой технологии.
Ну допустим (очень сильно допустим, ибо это еще надо разбираться) что xml когфиг дает чуть меньшее количество ошибок.
Ну будет в итоге не 40% ошибок, а 35%, ну и что с того? Это же не сведение ошибок к нулю. А такая разница не существенна.
Но. Зато нормальным программистам, которые голову не выключают в процессе работы, доп возможности в виде конфигурирования спринга через Java код, даст дополнительные удобства, там где это надо.
У меня вот нет проектов, которые даже теоретически могут потребовать изменения конфигов без пересборки. Мне Java конфиг намного удобнее. Да и не требуют они очень хитрой поддержки в IDE. Java код гораздо нагляднее и удобнее в работе чем куча xml инклудящихся друг в друга. Есть нормальное наследование и прочие плюшки. ТО же самое касается и груви конфигов.
Да, количество бинов не уменьшится. Но работать с Java или Groovy кодом намного приятнее и удобнее чем с xml.
Я недавно работал в одной компании, у которой, среди бесполезных company vision a.k.a bumper sticker slogans была одна очень дельная мысль: «Находи лучших, и доверяй им».
Компания, конечно, до исполнения не дошла (или от него отошла?) и с доверием всё было плохо, но сама идея 100% верная.
Надо нанимать таких, которым не страшно дать в руки Groovy Config.
Спасибо за статью — хорошо обобщает знания по контекстам.

P.S. Был на вашем треннинге по спрингу, остался очень доволен — четко было рассказано не только про внутреннее устройство спринг, жизненный цикл бинов, но и о том, как протюнить его под свои нужны — создание собственных BeanPostProcessor для предварительной настройки бинов, эффективное применение AOP и т.д. Большим профитом было — большое количество кода, которое осталось после курсов, как наглядное пособие для использования в своих проектах
Спасибо! Надеюсь не последний раз. Приходи теперь на мой тренинг по Gradle!
Еще начиная с третьей версии пишу java config, в перемешку с аннотациями. Пока все прекрасно. Спасибо за статья — давно хотел чтобы кто-то из прошаренных поднял эту тему.
моя IDE прекрасно разбирается в xml-ях. Зря вы это в недостатки xml записали
IDE бывают разные, не у всех такие хорошие, как у вас.
А что кроме IDEA бывают еще какие-то?
Мне нравится ваш wishful thinking! Только IDEA и единороги!
Наконец-то статься в которой честно перечислены преимущества XML конфигов вместо хипстерских воплей «XML is so 2000-nd».

Многие наверно не согласятся, но по мне так лучше XML конфигов для Spring ничего не придумали. А все последующие «контексты» — чтоб было что написать в релиз нотах новой версии.

Разве что аннотации все же сгодятся для rapid prototyping и всяких proof of concept, но в масштабных проектах — увольте.

И ни одного аргумента почему в масштабных проектах «увольте». А почему?
А нужны дополнительные аргументы после сводной таблици вверху?
Централизованная конфигурация + не хочу видеть Spring в своем коде (иногда означает не могу вставить Spring в чужой код, который мне дали thirdparty vendor-ы) — ИМХО достаточно.
А вот что такого в аннотациях чтоб предпочитать их XML-ю?
Ну, вот, например Груви имеет те-же преимущества. Плюс — от него не тошнит.
В groovy можно случайно логику вписать постороннюю, что в XML невозможно принципиально. А аргумента «не тошнит» я лично не понимаю — я уже давно привык читать XML-ные Spring конфиги легко и непринужденно, и дополнительные разделители только помогают взгляду зацепиться.
Поверьте, если я захочу, я «случайно» напишу FactoryBean. Логики будет не меньше, а вот читать весь этот балаган будет сложнее.
Случайно вписать логику звучит круто. Хотя я знал одного умельца, который случайно логику умудрялся и в XML вписать при помощи SpEL-a. А поскольку XML-ов на то время у нас было много, мы потом неделями его баги выискивали.
Вы когда нибудь пробовали дебажить SpEL прописанный в XML-e?
С груви в этом будет проще.
Хотя настоящую гарантию от «умельцев» может дать только пистолет.
SpEL появился в Sping 3 — очередной пример новых вещей, написанных «чтоб был что в release notes указать».
А так Spring 2.5 и XML конфиги — и нет проблем (-;
Груви-конфигурация, как мне кажется, хороша в grails-приложениях, для которого груви родной. Для энтерпрайза же, я бы всё равно остановился на java-конфигурации, из за её более суровой проверки типов.
Это немного не та дилема.
Груви конфигурацию не имеет смысла сравнивать только с Джавой (или только с ХМЛ-ом). Он призван заменить оба, когда преимущества объеденения превышают недостатки замены одного из видов.
Т.е. заменять только Джаву на Груви — нет. А вот иметь один конфиг вместо двух (ХМЛ-а и Джавы) — вот за это можно даже заплатить потерей проверки типов.
Не понятно. Нет ничего такого в XML конфиге что нельзя заменить Java конфигом. Получается груви следующий этап эволюции конфига спринга, то есть груви пришел на смену java конфигу, поправьте если я не прав.
Преимущество XML-а (и Groovy) над Java конфигом в том, что нет необходимости пресобирать и перекомпилировать продукт для того, чтобы изменить конфигурацию. Тпереь не нужно выносить 100500 переменных в 100500 property файлов — Груви скрипт сам по себе читабельный, писабельный, и перезагружаемый отдельно от приложения.
Вопрос — почему у Вас 100500 properties? Надо четко разделять пользовательские настройки и системную конфигурацию. Такие вещи как URL к базе данных, хост пользуемого вебсервиса, различные настраиваемые параметры поведения системы — это все пользовательские настройки. Их нужно выносить в отдельный файл. Конфигурация бинов и зависимостей — это чисто внутренние параметры системы. Давать клиенту менять конфигурацию будет крайне необдуманно (пустить козла в огород...). Даже если нужно поменять всего один системный параметр, для клиента это должно выглядеть как новая версия. Клиент не должен знать что там и как внутри устроено.

Groovy конфиги добавят к проекту еще over 9000 мб jar-ов для одноразового чтения десяти строчек.
Всё зависит от того, кто такие «пользователи».
Для professional services, которым нужно слегка «твикнуть» продукт (больше, чем URL, меньше, чем писать код) — выбрать нужную версию того или иного сервиса (среди уже написанных) — самое оно. Например, моя система умеет брать какие-то сообщения и из файла, и из базы данных, в зависимости от среды клиента. professional services (за пол-зарплаты программиста) сможет поменять один бин на другой в груви ничего не сломав, и не пересобрав.
С моей точки зрения в XML стоит размещать то, что фактически является настройками. Все остальное типа это у нас контроллер, это у нас сервис, этот сервис используется тут стоит делать аннотациями. Это позволяет решить проблему с контекстом. Когда программист работает с кодом ему важно как это с друг другом связано и в случае аннотаций это сразу видно. В случае же если эти связи прописаны отдельно от кода ему приходится держать еще один открытый редактор с xml.
То, что является настройками, как по мне, лучше всё же выносить в конфигурацию приложения, которая меняется без пересобирания проекта и которая специальным образом обрабатывает значения параметров для реализации того или иного поведения, иначе можно наменять в бинах разного.
Из xml в properties?
Не совсем понял, как убирание бина из конфигурации помогло решить проблему. Если это был конечный бин вроде контроллера, то по факту отсутствие обработчика не сильно лучше его неработоспособности, а если это это был какой-то бин, представляющий сервисы, то убирать его — значит сделать неработоспособными его пользователей. Фабрики или провайдеры каких-то данных всё равно требуют замены на какую-то дамми-реализацию, что для продакшена почти никогда не подходит. В вашем примере, видимо, был какой-то джоб, выполняющийся по событию или раз в какое-то время, который (скорее всего) процессил какие-то данные, что очевидно тоже долго не протянет и потребует оперативного вмешательства. И ради одного кейза (вероятность которого близка к нулю) вводить xml-конфиги, которые по всем остальным параметрам менее удобны java-конфигурации? Мой выбор — это нативная конфигурация и по возможности избегать исправлений наживую. Иначе может быть стоит выбрать другой всем нам известный язык сделанный специально для изменения в продакшене?
Вы совершенно правы, это таки был джоб кварца, который обращался к вебсервису, и время от времени обновлял данные для БД. Если вебсервис сдох, то обновлять все равно было нечего и приложение могло работать против существующих данных.
Я согласен, что такое вообще не должно случаться в продакшне, но увы и ах, есть компании которые выкатывают новые версии каждую неделю и некоторые проблемы приходится решать вот таким образом.
Но этот пример является очень крайним. Это не пример того, как надо работать, а пример какие плюсы могут быть у конфигурации, которую можно менять без перекомпиляции.
И есть компании, которым такая функциональность полезна, не потому что они так пытаются решать проблемы, а потому что хотят иметь возможность максимально быстро перекастомизировать продукт не прогоняя билд. Такая стратегия подрозумевают целую эко систему заточенную под это и многим это просто необходимо.
А вот насчет XML-ей я согласен, сегодня в них надобность отпадает. То мизирное количество конфигураций, которые требуют динамизма, можно выкинуть в груви. Но это уж, кто как любит.
Основная масса пока останется в джава конфигурации, с этим я тоже не спорю.
> А где же находится правда? Неужели как всегда посередине?
А правда в том, что в подавляющем большинстве случаев использования спринга проще, надежнее и быстрее обойтись без него. Для связки четырех бинов и конекшна к БД IoC не нужен. Если уж пошла речь об IoC и конфигурации, мне с самого начала нравился Guice и его манера конфигурирования контекста (DSL).
вернулся от Java-бинов к XML-конфигурации после нескольких попыток написать читабельную SpringSecurity конфигурацию с несколькими «блоками» http. В четвёртой версии user friendly улучшился?
SpringSecurity должен быть красив на Грувях — более гибкий, чем XML, нет адового бойлерплейта Java.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.