Почему я ненавижу Spring

Полностью согласен! У меня к Spring такое же отношение – вы точно уверены что в вашем конкретном проекте он нужен?
Когда легаси, то понятно что выпилить его из проекта невозможно.
Но когда новый то…

habrahabr.ru

В начале своей карьеры я реально влюбился в Spring. Я так долго ждал его. Я использовал его во всех своих проектах. Вдобавок мне даже удалось впихнуть туда кучу всякой всячины из Spring Integration. Я был кем-то вроде короля XML. Я делал RPC-слой на основе JMS, protobufs и Kaazing для всего нашего отдела и банка в целом. Я думал: «Это так конфигурируемо. Всего-то пара XML-файлов — это действительно гибко». Я был очень доволен собой.

Но некоторые мои коллеги были склонны не согласиться. У них возникали проблемы, когда они пытались связать всё так, как им хочется; они не знали, где какие XML-файлы им нужны. Были проблемы с версиями Spring, с тем, как подружить их (я, к тому же, далеко зашел с модульностью: у нас было 5 или 6 разных модулей с разными номерами версий, и нельзя было просто так взять и понять, какой из них использовать, не спросив меня). Это были тревожные звоночки, но я их не замечал; я думал, что нужно больше документации или что те ребята просто тупые. Такая ситуация типична сама по себе: мольбы пользователей одного из самых нелюбимых и трудных в использовании фреймворков о помощи часто разбиваются о «да там один файл и немного параметров, это не так уж и тяжело», в то время как все остальные целыми днями пытаются найти магическую комбинацию файлов и параметров, чтобы хоть что-нибудь как-нибудь заработало.

Я всё ещё работаю в той же организации, но теперь я пользователь своего старого фреймворка. В результате этого питания кормом своей собаки я стал ненавидеть Сэма (автор имеет в виду себя — прим. пер.) 2009-2010 годов по нескольким причинам, но в основном — за Spring. Spring — это зло в хорошую погоду, но когда его включают в состав библиотеки или API, которым пользуются другие программисты, — это уже другой уровень зла: как плод любви Гитлера и дьявола. Не позволяйте Spring торчать из вашего API наружу.

Spring — отстой по ряду причин, и я почувствовал, что их нужно перечислить, т.к. в google нет четких контраргументов.

  • Конфигурация в XML. Хотел бы я думать, что мы как профессия оставили XML в прошлом. Он невероятно многословен, но это ещё цветочки. Намного важнее то, что я не хочу программировать на XML. Связывание всех классов воедино — чрезвычайно важная часть вашего приложения. Вы Java-разработчик, а не XML-разработчик. Одна из прелестей Java как языка — compile time safety. Я могу скомпилировать свои приложения, в которых нет Spring, и быть на 100% уверенным, что всё собрано, подключено и готово к работе. Но если в приложении есть Spring, ты запускаешь его, ждешь 30-60 секунд, пока оно инициализирует бины, прежде чем упасть. В современном мире это безумие, особенно если это еще и умножается на кучу интеграционных тестов, в которых вам нужно вертеть контейнер так и этак. Отдельного места в расстрельном списке заслуживает «это значит, что я могу менять реализацию без перекомпиляции!». Так никто не делает. Никогда.
  • Магия. Тут обычно следует реплика: «Теперь вы можете делать всё с помощью аннотаций! Больше никакого XML!». Здорово, когда не нужно программировать на XML, но аннотации — это всё ещё магия. Пока вы не запустите приложение, вы понятия не имеете, свяжется ли оно правильно. И даже потом вы не знаете, правильно ли оно связалось; вы всего лишь знаете, что оно связалось. Не люблю магию.
  • Импортирование других Spring-файлов. В данный момент это бесит меня больше всего. Я обнаружил, что существует тенденция разбивать Spring-файлы на более мелкие и раскидывать их по модулям. Я только что убил 2 недели, продираясь сквозь JAR’ы и пытаясь найти правильную комбинацию/порядок/версию Spring-файлов, чтобы кое-что заработало. Spring-файлы в JAR’ах — это плохая, плохая идея. Ужасная. Каждый раз, когда вы размазываете зависимые Spring-файлы по JAR’ам, где-то умирает ребенок.
  • Сложность. Когда на собеседовании спрашиваешь кандидата: «Какие подводные камни есть в Spring?» — чаще всего слышишь в ответ, что у него крутая кривая обучения. Правда это или нет — отдельная тема, но я хотел бы подчеркнуть тот факт, что Spring сейчас настолько сложен, что у него есть собственный фреймворк — Spring Boot. Фреймворк для фреймворка. Мы во «Framework Inception» — фильме о Леонардо Ди Каприо, который пытается найти свой давно потерянный Java-код, всё глубже и глубже погружаясь в слои XML и аннотаций, прежде чем в конце концов покончить с собой.

Штука в том, что я уверен: удачно использовать Spring в приложении теоретически возможно. Я еще никогда такого не видел, и это проблема. Как по мне, все «плюшки», которые он предлагает, вполне возможны и без него. Когда мы спрашиваем о Spring на собеседовании, кандидат обычно отвечает: «Со Spring у вас есть чистый код, разделение ответственности, к тому же он действительно хорош для тестирования». В общем, все те вещи, большим поклонником которых я являюсь (особенно тестирование), но на самом деле это результаты не использования Spring, а хорошего программирования. Возможно, для новичков Spring — это хороший костыль для освоения таких идей, как внедрение зависимостей, mocking и тестирование, но на самом деле они ортогональны Spring. Если вы применяете TDD, у вас в коде не будет геттеров и сеттеров — только внедрение зависимостей через конструкторы, которые вы можете «замокать» для тестирования, а затем, когда вы связываете своё приложение воедино, просто используете часто забываемый способ создания объектов — ключевое слово «new». Зачастую мы создаем класс «ApplicationContext», который отвечает за связывание всего воедино. Он чистый, всё тестируемо, у меня есть compile time safety, и мои тесты выполняются чертовски быстро.

Из комментариев:


  1. огромное количество библиотек и реализаций. Попробуйте навелосипедить свой spring-security c каким-нибудь oauth собственнм сервером и клиентом.

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

Альтернативу @Transactional с нетривиальнм двухфазным коммитом (например БД + Очередь в единой транзакции).

Двухфазный коммит делает не Spring, а стороннияя библиотека-координатор, например Atomikos, Narayana, etc. Spring @Transactional делает лишь наивный автоматический прокси на коммит/роллбэк, который также легко сделать вручную при помощи java.lang.reflect.Proxy, AspectJ или ByteBuddy. В реальных проектах практически всегда требуется вручную контролировать сбои и взависимости от типа ошибки нужно помимо роллбека повторить транзакцию, реинициализировать ресурс, отрапортовать о сбое, собрать метрики… Вот вам и свой @Transactional. Кроме того есть мнение, что XA вообще не рекомендуется использовать…

но опять же время на изучение и не меньшее время чтобы все это подружить между собой

Убеждался и продолжаю убеждаться, что гораздо быстрее сделать все самому, чем читать тонны документации, втыкать, стековерфловить и пытаться все это подружить между собой. Кроме того, как это зачастую бывает в спринге: шаг влево-шаг вправо от рецепта — и геморрой обеспечен.

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

Ваши 1-2 разработчика писали когда-нибудь bean postprocessors? Скорей всего они намолотили кучу кривой прикладной магии ввиде специфических @Заклинаний. Разобраться почему не проксируется бин, кто его процессит и в какой последовательности и почему вдруг что-то перестало работать — никто не будет. Девелоперы как правило понавтыкают костылей, чтобы хоть как-то решить требуемую задачу.

Куча проблем за вас решена

И на ровном месте создана другая куча. Если все так просто — почему на SO Spring держится в топе? Как правило всегда есть более простое и элегантное решение каждой конкретной проблемы. Spring же пытается влезть без вазелина везде, где это только возможно, вцелом значительно усложняя архитектуру и упрощая лишь какие-то конкретные простые случаи использования. Кроме того, подобное упрощение имеет негативный эффект: куча кодеров, не понимая принципы работы, начинает копипейстить туториалы и SO, допуская архитектурные ошибки. И, столкнувшись с проблемами или с незнанием того, как что-то конкретное сделать на спринге, начинают грязно костылить.

Сделать достаточно сложный проект на spring-boot для быстрого старта как прототип относительно несложно

Сделать демку типа “хелло-ворлд” с кучей подключенных технологий. В реальном проекте требуется более полный контроль над кодом, где в итоге все плюсы ввиде средств автоматического бутстрапа превращаются в огромные минусы.


На самом деле автор статьи достаточно прав.
Используя спринг на проекте — вы все больше и больше пишите кода, не связанного с проектом, но связанный со спрингом. В некотором смысле, спринг обязывает вас говнокодить. Код должен содержать бизнес логику, а не фабрики, интерфейсы, конверторы, дто и т д.
В этом и есть «болезнь» джавы, потому что когда-то давно «умные» дяди придумали кучу стандартов под маркой Java EE, и все фреймворки начали под него подстраиваться.
Ребят, задайте вопрос, «что делает спринг у меня на проекте»? Делает DI? А сколько у вас реализаций на интерфейс? Одна?? Так какой это нахрен DI? То есть вы юзаете спринг для того что бы создать ОДИН СРАНЫЙ СИНГЛТОН? Рилли??? Service/@Repository/@Controller и для этого всего-то спринг??? Так может вы просто не знаете как писать тестируемый код с синглтонами? Так почитайте!
Опять таки. Спринг, даже со своей гибкостью кривой! И не покрывает некоторые простейшкие случаи! К примеру Spring-Data-Jpa. Простейший кейс. Почему нельзя было добавить слово limit в синтаксис spring-data??? Почему когда дело доходит до более-менее сложных операций (а не CRUD) постоянно приходится отходить от «идеалов» спринга, и постоянно что-то дописывать?
Ребят, если вы говорите что спринг мега-крутой и хороший фреймвок, скорее всего вы просто не пробовали что-либо другое. Попробуйте пописать годик-два проект например на Play Framework-е, желательно на старом, что бы без DI. Попробуйте Vert.X с его реактивным программированием. Или попробуйте сами построить нужную вам архитектуру на простом веб-сервере, без сервлетов вообще. Попробуйте писать код БЕЗ JPA, продумайте архитектуру и тогда вы начнете мыслить по другом. А то у нас бл*ть не программист, а Senior Spring-Framework Developer, и если что-то не входит в спринг, не в силах решить проблему.
А самое интересное, что отказавшись от спринга, вы хоть и напишите «маленький» велосипед в виде кастомной архитектуры.
НО! Вы увидите, что ваш код стал намного чище и намного гибче, чем со спрингом. И вы имеет ПОЛНЫЙ контроль над своим кодом! Я пишу на джаве с 2010 года, за это время были совершенно разные проекты с соершенно разными подходами. И к огромному сожалению, я заметил, что мода «богатых дядек» на ентерпрайз только усугубляет вещи в джаве. «Типичные вещи» в джаве можно делать намного проще, чем вы можете себе представить. (PHP программисты наверное офигивают, когда видят, как на джаве пишутся веб приложения, потому что у них нету джава ЕЕ, спринга и т.д., и там всё гораздо чище и проще).

Добавить комментарий

HTML отключен, используйте Markdown. Размещение кода: [pastebin id=fs23] или [gistgit id=2926827] или [gistgit id=2926827 file=foo.txt]