В начале своей карьеры я реально влюбился в 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, и мои тесты выполняются чертовски быстро.
Поделиться с друзьями
-->

Комментарии (243)


  1. gonzazoid
    26.07.2017 19:33
    +4

    Я только осваиваю Spring, но по смыслу статьи так ине понял чем он плох (я не защищаю и не осуждаю, я просто не понял) Про аннотации в самой же статье сказали, а про магию — ну извините, это инверсия. В любой инверсии вам придется знать ЧТО именно делает каркас к который вы встраиваетесь — это не магия спринга это магия DI.

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


    1. AndreyRubankov
      26.07.2017 23:34
      +6

      это не магия спринга это магия DI.

      Посмотрите на Guice — это маленькая библиотека, которая позволяет сделать DI. Но она маленькая, легковесная и в ней много конкретики. Хороший конфиг выглядит как: «для интерфейса Х создай имплементацию Y со всеми зависимостями».
      Хотя тут тоже свои подводные камни для больших проектов.

      В случае со спрингом это Можно сделать так, но редко кто делает — «это сильно много кода». Сервисы и компоненты просто декларируются и закидываются в класспас, а дальше «магия спринга» решит кого куда внедрить и кто кому нужен для работы. Контроля в этом случае нету в принципе.
      Для небольших проектов, где есть по одной имплементации – это вполне удобно. Для крупных — не уверен.


      1. satahippy
        27.07.2017 05:12

        В таком случае лучше уж Dagger, там конкретный код можно посмотреть.


        1. TheKnight
          27.07.2017 14:50

          А есть примеры использования Dagger за пределами Android? Мне он показалась каким то уж усложненным по конфигурации, по сравнению с Guice.


          1. satahippy
            27.07.2017 20:11

            По конфигурации да, чуть сложнее, но это не рокет сайнс, привыкаешь быстро.


            Мы использовали в десктопщине.


            Если интересует пример — можно посмотреть в github репозитории самого dagger — dagger/examples.


      1. s-kozlov
        27.07.2017 05:13

        Для небольших проектов, где есть по одной имплементации – это вполне удобно.


        Кстати, а зачем там вообще DI?

        Вот глобальный вопрос: посмотрите на типичный Spring-проект и ответьте себе честно: там есть польза от DI?


        1. AndreyRubankov
          27.07.2017 08:40

          Если смотреть на те проекты где я работал со spring boot, там есть польза. В проекте 50-100 файлов и все само в кучу собирается. Красиво и удобно, нету тонны кода для ручного создания всего кода.
          ps: но это было удобно только потому, что нужно было получить результат быстро и не париться с веб-фреймворками.

          Если смотреть в целом, то я сам сторонний compile-time связывания, т.е. для меня лучше написать код для создания всех зависимостей.
          Но я прекрасно понимаю, что это огромная гора кода будет. Более того, это будет ужас, если нужно будет добавлять какую-то новую зависимость — это больно.

          У меня нету однозначного мнения на счет DI — это и хорошо и плохо одновременно.


        1. rraderio
          27.07.2017 16:09

          Нет, польза от DI только в тестах


          1. s-kozlov
            27.07.2017 17:18

            О блин, как я мог забыть.


            1. rraderio
              27.07.2017 17:33

              А что, нет? У вас в проекте обычно одна реализация для интерфейса + для теста


              1. s-kozlov
                27.07.2017 17:42
                -1

                У нас очень и очень редко для теста нужна прям другая реализация. Обычно просто разные значения пропертей.


              1. asm0dey
                28.07.2017 10:35
                -1

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


      1. madkite
        31.07.2017 18:15

        А ещё можно посмотреть на HK2 — оно ещё меньше и проще.


        1. trix
          01.08.2017 22:47

          не надо на него смотреть, это древнючий, ужасно написанный контейнер к которому буквально приклеен кусок guice (но не очень аккуратно). смотрите или просто на guice или на чудесный picocontainer


  1. alek_sys
    26.07.2017 20:16
    +12

    Я, кажется, превращаюсь в адвоката Spring, но статья и хорошая, и не очень одновременно.

    Думаю, можно опустить пункты про XML (его ещё кто-то пишет?) и импортирование других файлов, что бы это ни значило. Если речь идёт про размазывание конфигурации по куче jar ов… Ну так и правда делать не нужно :)

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

    Но очень хороший совет, и его прямо сложно переоценить — это не включение в свои Api / библиотеки зависимости на Spring. Этого и правда нужно избегать, в идеале код библиотеки вообще не должен знать про Spring. В крайнем случае, можно выделить отдельную библиотеку интеграции. Но это ещё Дядюшка Боб завещал, это не особенность конкретно Spring.

    Поэтому отвечая автору «Почему я ненавижу Spring» я бы сказал «Скорее всего, потому что вы не любите уровни абстракции которые не контролируете и предпочитаете им написанный руками boilerplate код».


    1. Acuna
      27.07.2017 02:54
      -5

      Думаю, можно опустить пункты про XML (его ещё кто-то пишет?)

      Эммм… Да, под Андройд, и еще как) Там это вообще каркас.


      1. alek_sys
        27.07.2017 08:29
        +5

        Я имел в виду XML для конфигурации Spring :)


        1. Acuna
          28.07.2017 18:13

          А, ну это другое дело, да) А-то думаю ничего себе товарищ за бортом оказался, ибо то, что под Андройд на нем пишется чуть ли не половина логики, знает даже простой обыватель)


    1. ijusti
      28.07.2017 18:57

      Да пишет (XML) — Егор Бугаенко


    1. trix
      01.08.2017 22:53
      +1

      обычно если тащат в приложение спринг, то тащат почти всё (веб, дао, и т.д.) ваше приложение опирается на разномастное, местами старинное дерево абстракций, навязывающих свои интерфейсы, свои, подчас, не самые оптимальные способы работы с core-DI и проч.
      для поддержки всего этого добра уже мало знать underlying технологии, надо знать интеграционную специфику спринга.
      авторы многих интеграционных подпроектов одержимы причесыванием всего под одну гребенку, бывает, что суют свои интерфейсы даже если нативные лучше.


  1. Borz
    26.07.2017 21:08
    +3

    зачем использовать new в тестах, когда есть @MockBean и @SpyBean?


    и если вас напрягает DI и иже с ним, то как вы выживаете в этом мире микросервисов и распределённых систем?


    1. s-kozlov
      27.07.2017 05:15
      +1

      Это вопрос автору, переводчику или вообще всем мимо проходящим?


      1. Borz
        27.07.2017 07:49

        то, что это перевод заметил не сразу. Так что, давайте так:
        0) вопрос выше — всем мимо проходящим
        1) вопрос переводчику — зачем такой вброс сюда был? Какую цель вкладывал, когда переводил это?


        1. s-kozlov
          27.07.2017 17:24
          +2

          то, что это перевод заметил не сразу


          Вот это, я считаю, самый большой комплимент, который может получить переводчик.

          вопрос переводчику — зачем такой вброс сюда был? Какую цель вкладывал, когда переводил это?


          В основном, хотел немного попрактиковаться в переводах :) А конкретно этот пост выбрал потому, меня тоже бесит Spring. Я мог бы еще набросить лично от себя, но холиворить в интернетах надоело :)


  1. j_wayne
    26.07.2017 22:35

    Автор, а вы знакомы с проповедями Егора Бугаенко yegor256?

    http://www.yegor256.com/2014/10/03/di-containers-are-evil.html
    http://www.yegor256.com/2016/04/12/java-annotations-are-evil.html

    Выбросил Spring из проекта, остался только JdbcTemplate) Результатом доволен.


    1. Borz
      26.07.2017 23:32
      +3

      Выбросил Spring из проекта, остался только JdbcTemplate

      расскажете как вы так сумели?


      1. j_wayne
        26.07.2017 23:40
        +1

        ОK, OK, я отказался от DI средствами Spring. Совсем выбросить руки не дошли пока.


      1. AndreyRubankov
        27.07.2017 00:09

        Можно еще и Spring JdbcTemplate выкинуть, он не нужен.

        Что обычно нужно от Spring JdbcTemplate?
        — подготовить запрос, выполнить и смапить результат на какой-то бин или объект, правильно?

        Если больше ничего не нужно — у меня есть хорошая новость, чистый JDBC с этим прекрасно справляется!
        Миниатюрная обертка над бойлерплейт кодом подготовки JDBC запроса (~50-150 строк) и можно не подключать Spring JdbcTemplate в проект.

        https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setObject(int,%20java.lang.Object)
        — этот метод убирает всю сложность подготовки запроса (лучше использовать другой метод, но там немного усложняется код, может +50 строк будет).

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

        ps: конечно, может это зависит от Jdbc драйвера, я тестировал только для PostgeSQL.


        1. rraderio
          27.07.2017 16:14

        1. j_wayne
          27.07.2017 18:48

          Нет, не нужно, я тоже умею обходиться JDBC.
          Есть еще http://jdbc.jcabi.com/ от yegor256. Но с ним как-то не срослось под мои нужды.


        1. DreadKnight
          28.07.2017 15:11

          Для работы с базой есть прекрасная библиотека https://commons.apache.org/proper/commons-dbutils/


    1. s-kozlov
      27.07.2017 05:16
      +1

      Автор, а вы знакомы с проповедями Егора Бугаенко yegor256?


      ХЗ, спросите у него. Ссылка на его блог — под переводом.


  1. gnefedev
    26.07.2017 23:17

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


    1. s-kozlov
      27.07.2017 05:18
      +1

      С другой стороны, чем мощнее фреймворк и чем больше он дает возможностей, тем он монструознее и тем больше шанс, что 95% его вам нафиг не сдались, и вообще лучше было разбить его на либы.


  1. 3draven
    26.07.2017 23:39
    +2

    Мне аннотации нравятся, тестируемость нравится и магия тоже нравится. Но вот когда выясняется, что либа, которая внутри сервера приложений используется для запросов в сеть не может работать через прокси, а в конфигах в ста местах уже прописано «работай зараза» и тебе приходится заменить ее апачевской, которая умеет после нескольких дней выяснения «где же эта сволочь конфиг берет я ведь все указал!?». В общем это да, раздражает. За широкие возможности готовой реализации (магия) приходится платить. Зато сервер разворачивается и работает «сам по себе с парой конфигов».


  1. GerrAlt
    27.07.2017 00:24
    +5

    Одна из прелестей Java как языка — compile time safety.
    тут надо тогда не на Spring ругаться, а на весь AspectJ целиком, с включенным режимом инжектирования runtime.

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

    В общем ИМХО «не хочу учиться, хочу жениться» какое-то.


    1. 3draven
      27.07.2017 00:27

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


      1. s-kozlov
        27.07.2017 05:22
        +5

        А кто сказал, что он будет «своё ваять»? Возьмет и заюзает тулзу, которая устраивает его больше. Как будто кроме Spring на планете Java ничего нет.


    1. trix
      01.08.2017 22:59
      +1

      так навалом схожего и попрозрачнее. dropwizard, spotify apollo, lagom, play/slick, etc…
      чем больше народ будет уходить на микросервисы, тем сильнее будут отказываться от спринговой монструозности


  1. relgames
    27.07.2017 00:50
    +1

    Пару лет назад осознанно отказался от Spring в одном своем проекте.
    Стал использовать Akka, jooq, dagger.
    За 2 года не пожалел ни разу.


    1. rraderio
      27.07.2017 17:09

      А чем вы транзакции управляете? JOOQ ведь не умеет


      1. doom369
        27.07.2017 18:07

        Упрощенно:

        try {
             dbConnection = getDBConnection();
             dbConnection.setAutoCommit(false);
             new JOOQ(dbConnection).query().execute(); //dbConnection.commit();
        } catch (Exception e) {
            dbConnection.rollback();
        }
        


        1. rraderio
          27.07.2017 18:13

          Упрощенно, 6 строк, вместо одной, круто.
          А как у вас с уровнями изоляции транзакций?


          1. doom369
            27.07.2017 18:15

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


            1. rraderio
              27.07.2017 18:18

              Да какая магия? Создается Proxy класс, т.е. та же самая обертка, и в ней тот же код, почти, как у вас.
              В чем магия?


              1. doom369
                27.07.2017 18:24
                +1

                Ну так в том то и дело. Если нет разницы — так зачем платить больше (использовать спринг?)


                1. Borz
                  27.07.2017 18:29

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


                  1. doom369
                    27.07.2017 18:38

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


                1. rraderio
                  27.07.2017 18:32

                  В веб приложении часто надо сериализовать/десериализовать json/xml, security, api documentation, интернационализация, миграции,… в Spring это все интегрированно и протестированно, ну а если мы используем Spring то и писать свои обертки не нужно


                  1. doom369
                    27.07.2017 18:39
                    +1

                    Все это точно так же легко решается и без спринга.


                    1. rraderio
                      27.07.2017 19:00

                      Решается, но зачем решать если уже есть готовое?


                      1. doom369
                        27.07.2017 19:11
                        +1

                        Спринг многоцелевой и сложный. Чтобы начать работу со спрингом нужен определенный бекграунд. Любую задачу, которую решает спринг можно решить другими инструментами, которые простые и узконацеленные. Никто не говорит что нужно писать свои велосипеды.


                        1. fogone
                          27.07.2017 21:29

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


                          1. doom369
                            27.07.2017 21:48
                            +1

                            т.е. разобраться с одним спрингом сложнее, чем с полусотней других «простых» решений?


                            Именно. Тут уже внизу писали, что спринг — в топах вопросов на СО.

                            а набор «простых» решений еще придется друг к другу подгонять и писать интеграцию.


                            Наоборот — в виду узкой специализации каждой из библиотек вместе их собрать гораздо легче, чем наконфигурить спринг. Гляньте, например, guice как пример DI. За 1 минуту подключаете и используете во всю.

                            P. S. Если что — я 7 лет использовал спринг. Последние 3 год не использую. Моя продуктивность сильно выросла. Но это мой частный случай.


                            1. GerrAlt
                              28.07.2017 12:51
                              +1

                              Тут уже внизу писали, что спринг — в топах вопросов на СО.
                              возможно это не только в силу его непонятности, но еще и в силу высокой популярности?

                              если я напишу жутко сложную неудобную либу-обертку над JDBC и повешу ее на гитхаб, смогу ли я на основании отсуствия вопросов по ней на СО констатировать ее понятность?


                            1. fogone
                              30.07.2017 11:21

                              Гляньте, например, guice как пример DI. За 1 минуту подключаете и используете во всю.

                              Вы так говорите, как будто спринговый di подключается дольше.


                  1. trix
                    01.08.2017 23:06

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


          1. echipachenko
            28.07.2017 22:37

            А как у вас с уровнями изоляции транзакций?

            Я надеюсь вы понимаете, что изоляцию транзакций и сами транзакции управляются исключительно базой данных. А команды для этого посылает jdbc драйвер. Спринг и хибернейт абсолютно ничего нового не делают с транзакциями, всё сводится в конце к jdbc драйверу и методам setTransactionIsolation()/setAutoCommit(false)/commit()/rollback() из java.sql.Connection.


      1. relgames
        27.07.2017 18:09

        Руками — написал обертку.
        Выглядит так:

        database.executeAsyncTransactional(create -> create.update...)
        

        Внутри там используется create.transaction


        1. fogone
          27.07.2017 21:33

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


          1. s-kozlov
            28.07.2017 15:15

            А если оно таки неудобное?

            А если я использую простенькую библиотечку, исходный код которой я могу прочитать за один присест и как угодно пропатчить под себя в случае необходимости, то на кой черт мне SO и другие люди?


          1. relgames
            28.07.2017 23:28
            +1

            Потому что бэкенд на Akka стартует за 3 секунды и выдерживает 10 000 REST запросов в секунду на моем маке.
            Приложение на Spring стартует секунд 30, и держит хорошо если 100 запросов в секунду.

            Приложения примерно сравнимы — простенькие CRUD операции на базе.


            1. fogone
              29.07.2017 12:36

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


            1. rraderio
              29.07.2017 15:50
              +1

              Можно посмотреть на приложение на Spring?


              1. fogone
                29.07.2017 17:04

                Если вы имеете ввиду веб-приложение с реактором, то можно посмотреть на примеры из бута.


                1. rraderio
                  01.08.2017 11:28
                  -1

                  Хочу посмотреть на приложение на Spring которое стартует секунд 30


                  1. fogone
                    01.08.2017 15:43

                    Да, прошу прощения, я не туда ответил. Мне тоже интересно, что это за приложение такое и почему оно 30 секунд стартует. Уверен, что спринг тут играет очень косвенную роль. Например включено сканирование всех 100500 классов проекта и зависимостей. Или кучу времени инциализируется хибернейт и тд…


  1. Kerman
    27.07.2017 05:19
    +1

    Как по мне, все «плюшки», которые он предлагает, вполне возможны и без него.

    С этих слов обычно начинается эпичное велосипедостроение. Насколько велосипедостроение хорошо или плохо — тема для отдельного холивара.


    1. s-kozlov
      27.07.2017 05:20
      +1

      А еще эти слова внезапно могут значить, что автор нашел нормальный способ делать то же самое без Spring и велосипедов (другой способ DI, например).


      1. Borz
        27.07.2017 08:10
        +3

        другой способ DI

        обычно в таком случае человек рассказывает об альтернативе и какие плюсы он получил от перехода с инструмента А на инструмент Б. Если же человек говорит "возможны и без него" не приводя примеров, то это начинает попахивать


  1. penetrarthur
    27.07.2017 05:19
    +11

    На самом деле самая большая проблема спринга в 2017 году заключается в том что он реально старый и существует больше пяти способов сделать любую стандартную вещь. Причем все эти способы реально рабочие. В итоге вместо того чтоб писать "мясо" приложения, ты гуглиш какой же самый правильный способ сконфигуририть.


    1. GerrAlt
      27.07.2017 14:59
      +4

      Полностью согласен, отдельно стоит упомянуть что при гуглении методов решения какой-то проблемы/задачи первыми вылезают наиболее «проверенные временем» варианты, т.е. те что были опубликованы раньше, и отдельной проблемой становится узнать «а надо ли еще вот это вот все писать/реализовывать» или в современных реалиях уже все что нужно это какая-нибудь аннотация на классе/jar в класспасе и все сработает само


      1. s-kozlov
        28.07.2017 19:00

        Особый кайф ловишь, когда эти «проверенные временем» варианты на XML, а у тебя в проекте — нет, и конверсия не всегда тривиальна.


  1. StanislavL
    27.07.2017 09:41
    +8

    Есть пачка бонусов которые перевешивают:
    1. огромное количество библиотек и реализаций.
    Попробуйте навелосипедить свой spring-security c каким-нибудь oauth собственнм сервером и клиентом. Куча багов и без гарантий что дырок нет. Альтернативу @Transactional с нетривиальнм двухфазным коммитом (например БД + Очередь в единой транзакции). Возможно вы напишете свое, но сколько это займет времени. Возможно вы найдете для всего альтернативы, но опять же время на изучение и не меньшее время чтобы все это подружить между собой.
    2. сообщество.
    Легко найти того, кто знает, делал и есть доки, SO и т.д. Представьте, что у вас ушел 1-2 ключевых разработчика, кто делал ваши велосипеды и потом найдите и пофиксите сложный баг.
    3. оттестированно.
    Куча проблем за вас решена, причем проблемы в основном транспортного уровня, безопасность и т.п. Туча народу пробежала по граблям и убрала большинство.
    4. относительно быстрый старт.
    Сделать достаточно сложный проект на spring-boot для быстрого старта как прототип относительно несложно по количеству кода и времени. Самостоятельные попытки найти нужные библиотеки и связать их вместе только для того чтобы быстро показать и выбросить/поменять намного труднее.


    1. Throwable
      27.07.2017 12:37
      +7

      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 для быстрого старта как прототип относительно несложно

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


      1. grossws
        27.07.2017 13:40
        -2

        А как прекрасно становится, когда надо оверрайдить версии библиотек, прибитых гвоздём в parent pom'е spring boot.


        Например, если нужна определенная версия jetty-client с её зависимостями; у тебя уже есть нужный bom, но его не подключишь, т.к. parent pom оверрайдит.


        1. Borz
          27.07.2017 14:10
          +2

          а мне казалось, что чтобы заменить версию библиотеки, достаточно просто в своём pom-файле в properties переопределить для зависимости на новую версию...


          <properties>
            <jetty.version>9.4.2.v20170220</jetty.version>
          </properties>

          имена нужных переменных берутся тут поиском по необходимому артефакту


          1. grossws
            27.07.2017 14:50

            Похоже вы правы, если mvn dependency:tree -Dverbose=true меня не обманывает.


            Скорее всего, кусок pom'а вида


              <properties>
                <java.version>1.8</java.version>
            
                <jetty.version>9.3.20.v20170531</jetty.version>
              </properties>
            
              <dependencyManagement>
                <dependencies>
                  <dependency>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-client</artifactId>
                    <version>${jetty.version}</version>
                  </dependency>
                  <dependency>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-http</artifactId>
                    <version>${jetty.version}</version>
                  </dependency>
                  <dependency>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-io</artifactId>
                    <version>${jetty.version}</version>
                  </dependency>

            у меня появился неспроста. Возможно, зависит от версии мавена и на 3.5.0 просто не проявляется. IIRC, они несколько раз переделывали resolve зависимостей в третьей ветке.


      1. s-kozlov
        27.07.2017 17:34

        О боже, вы только что перечислили всё то, что было у меня в голове все эти годы! Я чувствовал, что со Spring много чего не так, но чтобы вот так взять и выразить словами… Да вам надо статью пилить!


      1. sshikov
        29.07.2017 12:08
        +3

        Хм. Ну вот так-то передергивать не нужно:


        например тот же Servlet уже содержит простые средства security.

        Вам про OAuth, а вы про сервлеты. Покажете, в каком месте у сервлетов OAuth? :)


        Ну и самое главное, что почему-то всегда ускользает в подобных дискуссиях — если автор/комментатор способен реализовать то что есть в спринге самостоятельно, то он достаточно квалифицирован, потому что код спринга достаточно высокого качества. Большинство джунов не в состоянии не только написать такой, но и понять зачастую. Поэтому посты типа "я ненавижу..." следует читать с солидной долей скепсиса. Ну ненавидит, и что? В нашем случае все может быть сильно иначе.


        1. Throwable
          31.07.2017 10:53
          +2

          Большинство джунов не в состоянии не только написать такой, но и понять зачастую. Поэтому посты типа "я ненавижу..." следует читать с солидной долей скепсиса.

          Это понятно. С другой точки зрения, джун, который мало-мальски в состоянии распарсить файл и запихнуть его в базу данных, при попытке сделать это на Spring Batch наполняется лютой и праведной ненавистью.


    1. eirnym
      31.07.2017 17:38

      свой spring-security c каким-нибудь oauth

      в мавен-репозитории значатся как минимум Apache Shiro и PicketBox Assembly, если искать в категории "Security Frameworks". Применительно к OAuth2, сервера и клиенты ищутся в гугле достаточно легко, и Spring там далеко не на первом месте.


  1. Londoner
    27.07.2017 12:25
    +2

    Эх… когда же всё таки появится что-то похожее на Flask для джавы?


    1. myrslok
      27.07.2017 17:40

      Spark не устроит?


      1. Londoner
        27.07.2017 17:55

        Близко, но не оно. А какие есть ещё альтернативы?


    1. SlyDen
      27.07.2017 17:40

      ну можете глянуть на ratpack.io… у меня с ним положительный опыт в проекте (чистый API, UI отдельное SPA на JavaScript)


  1. vsb
    27.07.2017 13:01
    +1

    Использовал Spring, исключительно с полным описанием всех компонентов через XML и без всяких Autowired, могу сказать, что получается очень удобно. Во-первых никакой магии, всё описано в XML до последнего параметра. Во-вторых можно без перекомпиляции менять кучу всего и это, вопреки мнению автора статьи, действительно используется. В-третьих я никогда не пойму ненависть по отношению к XML, по-мне это чудесный формат и пока никому ещё не удалось создать что-то лучше, единственный его недостаток это то, что там нет синтаксиса для массивов, поэтому при маппинге возникают неоднозначные ситуации (но XML Schema это решает).


    1. GerrAlt
      27.07.2017 15:12
      +2

      Тоже не понимаю ненависти к XML.
      Многословен? А вы куда-то все время торопитесь? :)

      Зачастую очень многих проблем с «многословностью» можно избежать если почитать стандарт + сопутствующие технологии (например namespaces)


      1. fogone
        27.07.2017 21:55

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


  1. darkslave
    27.07.2017 16:11
    +1

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


    1. s-kozlov
      27.07.2017 17:50

      Любой фреймворк создается для решения какого-то определенного множества задач.


      И в этом большая проблема самого подхода «фреймворк». Эй, люди, как насчет SRP? Хороший инструмент должен решать одну задачу. Помню, когда я только начинал осваивать Spring, я не мог понять, какую задачу решает он. После раскуривания манов у меня сложилось ощущение, что он пытается решить вообще все задачи. Так оно и оказалось. Это оборачивается тем, что потом вы начинаете думать, как подружить Spring с библиотекой/фреймворком X. Это ж звездец какой-то! Я программист, а не семейный психолог. Я хочу писать свой код, а не сглаживать межфреймворковые противоречия. Не припомню, чтобы мне приходилось даже думать о том, чтобы подружить две библиотеки. Одну ты вызываешь, когда нужно А, другую — Б.


      1. fogone
        27.07.2017 21:57

        Спринг сам по себе решает ровно одну задачу. Интеграцию решений. Плюс у спринга еще есть много дополнительных библиотек, которые решают другие задачи. Тоже обычно по одному за раз.


        1. s-kozlov
          28.07.2017 15:17

          Спринг сам по себе решает ровно одну задачу. Интеграцию решений.


          Интеграция решений — это работа программиста.


          1. rraderio
            28.07.2017 15:26

            Ну вот заинтегрировал я 3 библиотеки, что, мне за это заплатят деньги?


            1. s-kozlov
              28.07.2017 15:31

              Не знаю как Вам, а мне платят. А что такое программирование если не интеграция решений? Работа программиста в том и заключается, чтобы выдать продукт А, используя инструменты B, C и D. Ну это если не брать всяких мышевозов с джумлой.


              1. rraderio
                28.07.2017 15:51

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


                1. s-kozlov
                  28.07.2017 19:06

                  Ну дык это никак не противоречит тому, что я сказал


          1. fogone
            29.07.2017 12:39

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


            1. s-kozlov
              29.07.2017 16:52
              +1

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

              Есть easy, a есть simple. Easy — это когда написал пару строчек. Simple — это когда легко разобраться, как это работает, и просто изменить что-то в одном месте, будучи уверенным, что ничего не сломалось где-нибудь еще.

              Spring — это easy (пока не нужно сделать шаг влево/вправо :)), но это очень, очень далеко от simple. И вот этот not simple оборачивается hard, когда нужно сделать тот самый шаг в сторону.

              Вообще каждый выбирает сам. Я начинал с предпочтения easy, меньшего объема кода, минимального дублирования и т.д. Сейчас предпочитаю немного отойти от easy, чтобы сделать simple.


              1. fogone
                29.07.2017 17:16

                Очень люблю писать велосипеды, но с опытом приходит понимание, что обычно лучше использовать готовое решение, особенно если оно знакомо другим разработчикам и решает все твои задачи. А велосипеды требуют не меньшей работы, чем разобраться со спрингом хотя бы из за того, что для всех его частей придется писать тесты, а потом еще ловить баги, проблемы секьюрити, корнер-кейзы и тд. Да еще если кто-то после тебя на твои велосипеды придет, то будет материть тебя на чем свет стоит (а то и решит, что её нужно переписать), потому что спринг знаком более-менее каждому современному джава-разработчику, и имеет очень неплохой уровень качества — как кода и архитектуры, так и проработанности деталей и покрытия тестами, а ваш велик придется исследовать с нуля, неизвестно какого он качества, да и не был бы я уверен, что по ходу развития системы сложность вашей собственной интеграции не станет существенно выше её же в спринге.


                1. s-kozlov
                  29.07.2017 17:36

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


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

                  ваш велик придется исследовать с нуля


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

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


                  Ну так не уверен — не берись, уверен — делай и никого не слушай. «Главное понимать что ты хочешь и что можешь.» (https://habrahabr.ru/post/259831/#comment_8453133)


                  1. fogone
                    30.07.2017 12:10
                    +2

                    готовые решения — это не однозначное добро

                    я никогда не говорил, что готовые решения это однозначное добро. Только конкретно о спринге и с большими оговорками на то, что не стоит воспринимать спринг как универсальное решение для всех и вся и рассчитывать, что там нет проблем или решены любые ваше потребности. Это готовое решение по интеграции, которое часто при прочих равных на мой взгляд выигрывает перед самописным решением, когда речь идет о проекте, которые будет развиваться и разрабатываться не одним человеком. Во многом из за большого числа уже готовых интеграций, которые не без греха, чего уж, но работают без необходимости всё это писать самому.
                    особенно когда к этому готовому решению городить столько костылей, что объем костыльного кода начинает превышать объем самого «решения»

                    Да, спринг часто кастомизируют, тем он и ценен, но вот так, чтобы объем кода кастомизации превышал объем бизнес-кода… такого я еще не видал. Да еще и весь костыльный, точно ли тут дело в спринге?
                    Простите, но в ваших комментах сквозит нечто вроде детского страха перед тем, что сделали «взрослые дядьки»: мол, они могут сделать хорошо, потому что взрослые,

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

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


                    1. s-kozlov
                      31.07.2017 15:39

                      Вот вы в целом пишете правильные вещи, и всё-таки смотрите на спринг как на нечто божественное, что вам не дано понять, повторить или обойтись без этого. Годы собирания типовых решений типовых проблем — это, конечно, показатель, но тоже спорный. Во-первых, Spring — вещь общая, и вполне возможно, что собственное решение будет проще и лучше (в том числе — на long term). Во-вторых, что если многие из этих «решений» на самом деле решают проблемы, которые породил сам Spring.

                      Кстати, вы часто говорите, что Spring — это решение для интеграции. Можете привести пример, когда что-то с чем-то не спринговое нужно интегрировать, это действительно проблема и Spring ее решает?


                      1. fogone
                        31.07.2017 19:38

                        Во-первых, Spring — вещь общая, и вполне возможно, что собственное решение будет проще и лучше (в том числе — на long term).

                        А так же вполне возможно, что не будет. Только во втором случае на это придется потратить время, силы и деньги. И что точно получится ты пока не знаешь, а спринг уже вполне понятный. По большей части, конечно.
                        Во-вторых, что если многие из этих «решений» на самом деле решают проблемы, которые породил сам Spring.

                        Уже не первый раз про это слышу, что собственно вы имеете ввиду? Приведите топ 10 проблем, которые создал спринг, которые он сам же и решает. Т.е. поймите правильно, спринг безусловно решает свои внутренние проблемы, с этим спорить глупо. И да для этого написано много кода. Но эти проблемы второстепенны по сравнению с теми какое количество решений моих проблем у него есть.
                        Можете привести пример, когда что-то с чем-то не спринговое нужно интегрировать, это действительно проблема и Spring ее решает?

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


                        1. s-kozlov
                          01.08.2017 09:20

                          Ну как, запустить сервер, сконфигурировать его, пробросить в него мэппинги контроллера, где-то хранить инстансы сервисов, каким-то образом драйвить транзакции, скорнфигурировать какой-нибудь хибернейт, создать для него инфраструктуру, сконфигурировать датасорс и тд.


                          Ясно, спасибо, я думал, вы имеете в виду что-то другое.


                          1. fogone
                            01.08.2017 15:47

                            Что например? Может показаться, что мелочи, но на мой взгляд совсем нет, да и не так иллюзорно это, когда спринг из коробки поднимает стек нетфликса, например.


                            1. s-kozlov
                              02.08.2017 13:59

                              Я просто думал, что вы говорите о какой-то интеграции, о которой я не знал / забыл.


                            1. gonzazoid
                              02.08.2017 22:04

                              вмешаюсь немного в ваш диалог. Мне кажется (возможно я ошибаюсь) что под интеграциями обычно (если не оговорено иное) подразумевают что то типа круга задач решаемых например Apache Camel.


                              1. fogone
                                03.08.2017 09:32

                                кто-то интегрирует системы, а кто-то библиотеки в системе, всем нужны свои инструменты


                        1. s-kozlov
                          01.08.2017 09:22
                          -1

                          Приведите топ 10 проблем, которые создал спринг, которые он сам же и решает.


                          Я не готов сейчас дискутировать на эту тему. Тем более, что вы сами понимаете, что они есть.


  1. echipachenko
    27.07.2017 17:52
    +2

    На самом деле автор статьи достаточно прав. Используя спринг на проекте — вы все больше и больше пишите кода, не связанного с проектом, но связанный со спрингом. В некотором смысле, спринг обязывает вас говнокодить. Код должен содержать бизнес логику, а не фабрики, интерфейсы, конверторы, дто и т д. В этом и есть «болезнь» джавы, потому что когда-то давно «умные» дяди придумали кучу стандартов под маркой 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 программисты наверное офигивают, когда видят, как на джаве пишутся веб приложения, потому что у них нету джава ЕЕ, спринга и т.д., и там всё гораздо чище и проще).


    1. rraderio
      27.07.2017 18:03

      Так может вы просто не знаете как писать тестируемый код с синглтонами? Так почитайте!

      дайте ссылки что ли


      1. echipachenko
        27.07.2017 18:51
        +2

        Как и любой другой код. Тем же JUnit + Mockito или powermock. Если вы будете писать код в стиле спринга — а именно, сохранять ссылки на синглтон в полях класса — не будет никаких проблем с тем что бы их замокать. + никто не запрещает вам, делать конструктор синглтона не приватным, а пекедж-протектеж, что бы Ваши моки могли без проблемно мокать. Кроме того, end-to-end/интегрейшн тесты никто не отменял. Да и уровень покрытия с ними намного лучше, чем с юнитами. + Автотесты от QA. Не вижу никаких проблем.


        1. rraderio
          28.07.2017 10:10
          -1

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

          Зачем сохранять ссылки на синглтон в полях класса, если это синглтоны? Их же можно вызвать прямо там где нужно.

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

          Да и уровень покрытия с ними намного лучше, чем с юнитами.

          Но они медленные


          1. Borz
            28.07.2017 10:21

            Есть класс EmailSender если я в тесте забуду замокать все методы

            замокайте весь класс сразу в тесте через тот же PowerMockito.mockStatic и возвращайте реальные вызовы уже для конкретных методов в этом классе. Заодно будете уверены, что у вас вызываются ровно те методы, которые вы планировали тестировать


          1. mayorovp
            28.07.2017 10:23

            Зачем сохранять ссылки на синглтон в полях класса, если это синглтоны? Их же можно вызвать прямо там где нужно.

            Чтобы ограничить разрастание макарон в коде.


        1. rraderio
          28.07.2017 10:59

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

          Инстанс вы в конструкторе получаете или ининциализируете поле?
          private EmailSender emailSender = EmailSender.getInstance();
          


          1. echipachenko
            28.07.2017 11:46

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


            1. doom369
              28.07.2017 11:51

              Конструкторы лучше. Так как легче тестить. Например, когда нужно замокать этот самый EmailSender. Но да, бывает, что конструктор очень сильно ростет. Я в таких случаях создаю объект Holder который содержит ссылки на все синглтоны.


              1. rraderio
                28.07.2017 11:57

                Т.е. Вы сами создаете инстансы классов и передаете синглетоны? А если завтра надо будет использовать SmsSender вместо EmailSender, Вы перепишите весь код?


                1. doom369
                  28.07.2017 12:06

                  Т.е. Вы сами создаете инстансы классов и передаете синглетоны?


                  Да. Вот пример. В нем как раз есть и имейл сендер и смс сендер и пуш сендер =).

                  А если завтра надо будет использовать SmsSender вместо EmailSender


                  Любая IDE это делает через 2 клика.


                  1. rraderio
                    28.07.2017 12:12

                    Любая IDE это делает через 2 клика.

                    А как же принцип открытости/закрытости?


                    1. doom369
                      28.07.2017 12:16

                      И как код выше противоречит этому принципу?


                      1. rraderio
                        28.07.2017 12:20
                        -1

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

                        Вы не только добавляете новые сущности но и вносите изменения в код.


                        1. doom369
                          28.07.2017 12:25
                          -1

                          Так смс это не расширение, а новое поведение, поэтому все честно.


                          1. rraderio
                            29.07.2017 17:30
                            -1

                            А что тогда расширение?


                            1. doom369
                              29.07.2017 17:38

                              Добавить в смс враппер еще один метод.


                              1. rraderio
                                31.07.2017 20:08

                                И это не будет новым поведением? От этого же могут изменится результаты


            1. rraderio
              28.07.2017 12:02

              Инициализирую прямо в поле.

              А если завтра надо будет использовать SmsSender вместо EmailSender, Вы перепишите весь код?


              1. echipachenko
                28.07.2017 12:13
                +2

                class SmsSender implements ISender{...}
                class EmailSender implements ISender{...}
                
                public class Sender{
                  private static final ISender smsSender = SmsSender.getInstance();
                  private static final ISender emailSender = EmailSender.getInstance();
                
                  public static ISender getInstance(){
                    return condition ?  smsSender : emailSender;
                  }
                ....
                }
                


                Не знаю как у вас, у меня ни разу не было случая, что бы это «когда-то» наступило. Закладывать в основу кода, то, что когда-то что-то может изменится, зачастую есть ошибочным, ибо это когда-то никогда не наступит. Но, конечно случаи бывают.


                1. echipachenko
                  28.07.2017 12:21
                  +1

                  Опять же, ребят, я не пытаюсь вас убедить в том, что спринг полное говно и его нужно избегать. Нет. Я просто хочу донести до вас то, что жизнь без спринга существует, и иногда это даже намного лучше чем с ним. Конечно, всё очень индивидуально. Но! Просто перед тем как начинить новый проект, надо задать себе 3 вопроса:
                  1. Что будет делать у меня на проекте спринг.
                  2. Все ли сложные случаи он покроет, или надо будет писать костыли для него же.
                  3. Какая есть альтернатива для решения этих задач.
                  Посмотреть на эти альтернативы, возможно они намного лучше подойдут вам чем тот-же спринг.


                1. rraderio
                  28.07.2017 12:26
                  +1

                  Вот это и есть DI, это и делает Spring :)
                  Sender у вас какбы контекст из Spring.


                  1. echipachenko
                    28.07.2017 12:36
                    +1

                    Уж лучше я в коде проверю кондишн и обращусь к нужной реализации, чем буду цеплять для этого спринг. Тем более что кондишены для получения реализации в рантайме там насколько ужасно и не очевидно сделаны, что приходится каждому новому разработчику объяснять как оно работает. А если это одноразовое изменение — это вообще не проблема. И ничего не надо переписывать, максимум — пару строчек кода. Да и за всё время таких случаев почти не было.


                  1. Borz
                    28.07.2017 12:37
                    +1

                    но то DI от Spring, который какой-то магический, а тут свой, родной и понятный


                  1. echipachenko
                    28.07.2017 12:43

                    Если у вас есть реальная потребность в DI — есть много других библиотек, которые нормально справляются с этой задачей. Тот же Google Guice.


            1. semio
              30.07.2017 15:42

              С конструкторами мне не очень нравится, потому что иногда синглтонов может быть много, и тогда конструктор становится большим и принимать много параметров, и это становится не удобным и не красивым кодом.

              Тут как бы звоночек о том, что надо подумать над архитектурой класса, т.к. он стал брать на себя слишком много. Но не всегда, конечно, можно/нужно разбивать класс на несколько. Тогда может прийти на помощь Lombok, если все поля — инжекты бинов. Будет что-то вроде:
              @Service
              @AllArgsConstructor
              public class MyFatService {
                  private final SomeRepository someRepository;
                  private final SomeBean2 someBean1;
              	...
                  private final SomeBean10 someBean10;
              	
                  // Дальше код
              }
              

              В этом случае никаких @Autowired и никаких конструкторов не нужно.


    1. rraderio
      27.07.2017 18:08

      Для Play или Vert.x есть модуль который генерирует Swagger документацию только добавлением зависимости в pom?

      SpringFox


      1. echipachenko
        27.07.2017 18:46

        Для начала — да есть. Но даже если бы и не было — это не должно быть чем-то страшным. Всё что делает сваггер — принимает JSON с описанием. Никакой магии он не делает, и я не вижу никаких проблем реализовать это в течении одного дня.
        https://swagger.io/playing-with-swagger-using-swagger-and-swagger-ui-with-the-play-framework/


        1. rraderio
          28.07.2017 10:01

          https://swagger.io/playing-with-swagger-using-swagger-and-swagger-ui-with-the-play-framework/

          Это не совсем
          модуль который генерирует Swagger документацию только добавлением зависимости в pom


          Spring без Swagger
          @Controller
          public class MyController {
          
              @RequestMapping(value = "test")
              public  @ResponseBody String save(@RequestBody  Animal animal) {
                  System.out.println(animal.getClass());
                  return success;
              }
          }
          


          Добавляем зависимости
          compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0'
          compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0'

          И все, можем открывать в браузере, не надо ничего больше описывать

          В Play
          @ApiOperation(value = "get All Todos",
               notes = "Returns List of all Todos",
               response = Todo.class, 
               httpMethod = "GET") 
          public static Result getAllTodos() { 
               return ok(toJson(models.Todo.findByUser(SecurityController.getUser()))); 
          }
          

          А что если мы в методе поменяем тип а в ApiOperation забудем, компилятор ведь не может это проверить, в SpringFox оно само выводится


    1. zirix
      28.07.2017 12:39
      +2

      Почему нельзя было добавить слово limit в синтаксис spring-data???
      Добавьте Pageable/PageRequest к методу, он генерирует LIMIT;


      1. echipachenko
        28.07.2017 12:48
        -2

        Да, я знаю о этом. Но это уже выглядит криво, не правда ли? Если есть такой крутой механизм, в чем была сложность добавить что-то вроде findAllWithLimitOffset(int limit, int offset)? И таких кейсов достаточно много.
        Вот кстати ещё один из самых смешных кейсов. Спринг Controller не умеет возвращать файлы! Что бы вернуть файл с контроллера надо заинжектить HttpServletResponse и пробрасывать через оутпут-стрим и хидеры прокидывать. Неужели спринг со своей гибкостью не мог сделать поддержку контроллера с возвращаемым значением File? Или какой-то более компактный и лаконичный способ?


        1. zirix
          28.07.2017 12:51
          +2

          Спринг Controller не умеет возвращать файлы!

          Можно без HttpServletResponse:


             @GetMapping("/...")
              public ResponseEntity<?> get(...) {
                  final InputStream stream = ...;
                  return ResponseEntity.ok()
                          .contentType(MediaType.IMAGE_JPEG)
                          .cacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
                          .lastModified(storage.getDate().getTime())
                          .eTag('\"' + String.valueOf(storage.getId() + storage.getDate().getTime()) + '\"')
                          .contentLength(storage.getSize())
                          .body(new InputStreamResource(stream));
              }


          1. echipachenko
            28.07.2017 13:47
            +1

            Вы хотите сказать это краткий и лаконичный код?))))
            Вот вам пример из Play-a

            public Response getFile(String path){
            File file = ....
            return ok(file)
            }
            


            1. zirix
              28.07.2017 14:34

              Вы хотите сказать это краткий и лаконичный код?))))

              Вы про хидеры говорили, вот я и дал вам пример с хидерами. Вот короче:


              @GetMapping("/")
              public ResponseEntity<?> get() throws FileNotFoundException {
                  File file = ...
                  return ResponseEntity.ok(new InputStreamResource(new FileInputStream(file)));
              }


              1. zirix
                28.07.2017 14:43
                +1

                Если хотите большей лаконичности, то создайте класс:


                public class SendFile extends ResponseEntity<?> {
                    public SendFile(File file) throws FileNotFoundException {
                        super(new InputStreamResource(new FileInputStream(file)), HttpStatus.OK);
                    }
                }

                А потмо везде пишите так:


                @GetMapping("/")
                public ResponseEntity<?> get() {
                    File file = ...
                    return new SendFile(file);
                }
                


                1. echipachenko
                  28.07.2017 22:26
                  +1

                  Ну вот вы и вернулись к тому, о чем писал я.

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

                  Почему, когда я подключаю такой огромный и мощний фрейморк, спринг, я не могу просто написать
                  @GetMapping("/")
                  public File get() {
                      return new File(file);
                  }
                  

                  У спринга есть все возможности для этого, и эту элементарную вещь они могли добавить лет так 7-8 назад. Почему спринг понимает, что POJO можно отдать в Json/XML, String — загрузить шаблон, а файл вызывает просто ужас у спринга? Я не хочу писать кучу конфигов, утилитарных методов, адаптеров и прочей чепухи, используя такой огромный фреймворк. Игры для андроида занимают 50 мегабайт, там куча 3д объектов, миллионы формул и вычислений, а я своём веб-аппе тяну спринг фреймворк весом в 50 мегабайт, который из коробки не понимает что если контроллер возвращает файл — то надо вернуть файл! И это я навел только 2 маленьких и безобидных примера.


                  1. zirix
                    28.07.2017 22:58
                    +1

                    Ну вот вы и вернулись к тому, о чем писал я.

                    Мы пришли к тому, что вы не очень хорошо знаете spring.


                    @GetMapping("/...")
                    @ResponseBody
                    public FileSystemResource get() {
                        return new FileSystemResource("/path/to/file");
                    }

                    Но не стоит отдавать статические файлы через контроллер. Для файлов есть директория resource и spring.resources.static-locations.


                    1. 3draven
                      28.07.2017 23:01

                      Ой, а может тогда мне совет дадите. Надо сделать сокет сервер на wildfly, а там через JCA и пр. Есть способ попроще что бы восемь классов оберток не делать? Я конечно обошелся сделав сокет клиент, но все же хочется.


                    1. echipachenko
                      28.07.2017 23:21
                      +1

                      Смотрите, за время нашей переписки, здесь было уже упомянуто 3 способа. И не стоит рассуждать о моих знаниях спринга исходя из переписки. 3 способа, какой из них лучше? И речь вообще не идет о том, статик файлы это или нет, вполне возможно что они генерируются на лету и отдаются только авторизированному юзеру и доступны в течении некоторого небольшого времени. А теперь представьте что у вас таких мест много. И у каждого, свой вариант. Как вы потом будете сапортить такой код? И опять таки, это самые безобидные примеры. Ну, повповторюсь, я не призываю кого либо отказываться от спринга и не говорю что он говно. Но некоторые вещи в нем плохие. И есть лучшая альтернатива.


                      1. zirix
                        29.07.2017 00:15

                        3 способа, какой из них лучше?

                        Решить что лучше — задача архитектора.


                        ResponseEntity<> позволяет управлять статусом ответа (200 OK, 404 Not Found...). Имеет смысл проверять заголовки запроса и отдавать "304 Not Modified"…
                        Также позволяет установить Content-Disposition, cacheControl, eTag и прочее.


                        Если вам это не нужно, то возвращайте из контроллера FileSystemResource или InputStreamResource + @ResponseBody


                        Если вы захотите автоматизировать установку хидеров и выдачу статуса "304 Not Modified", то можете доработать мой пример с SendFile.


                  1. fogone
                    29.07.2017 13:11

                    Почему, когда я подключаю такой огромный и мощний фрейморк, спринг, я не могу просто написать

                    У спирнга нет никаких проблем с отдачей файла, zirix написал выше как сделать это одной строкой, если надо. Ваше негодование по поводу того, что спринг-вебмвц гибкий и позволяет сложно кастомизировать ответ прямо из котроллера звучит просто смешно, видимо вам просто никогда не приходилось этим пользоваться.
                    У спринга есть все возможности для этого, и эту элементарную вещь они могли добавить лет так 7-8 назад.

                    Примерно 7-8 лет назад это и там и появилось.
                    Я не хочу писать кучу конфигов, утилитарных методов, адаптеров и прочей чепухи, используя такой огромный фреймворк.

                    Кто же вас заставляет? Даже если вас насильно засадили писать приложение на спринг-вебмвц, то для простых случаев не нужно писать кучу конфигов, утилитарных методов и прочей чепухи, а вот если нужно что-то кастомизировать, то другой фреймворк может просто в лужу сесть, а в спринге обычно всегда есть способ кастомизировать поведение, как раз во многом из за хорошей модульности и продуманности этого фреймворка и webmvc в том числе.
                    а я своём веб-аппе тяну спринг фреймворк весом в 50 мегабайт

                    в теории это возможно если тянуть как минимум 5 разных версий всех зависимостей, но что-то мне подсказывает, что это не будет работать. Я это к тому, что ваша оценка размера спринга более чем преувеличена. Да и не так уже это страшно для нынешних реалий 10 мегабайт, если они удовлетворяют большинству потребностей.
                    который из коробки не понимает что если контроллер возвращает файл — то надо вернуть файл!

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


                    1. echipachenko
                      29.07.2017 13:49

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


                      1. fogone
                        29.07.2017 17:22

                        Это не холивар, а указание на неточности вашего комментария, я (честно говоря) и не ждал на него ответа.


        1. asm0dey
          29.07.2017 16:21
          +1

          В JPA нет LIMIT. Реализации его — вендор-специфичны. Зато есть Pageable, который вполне можно передать, он и сделан для лимит-оффсета.


          1. echipachenko
            29.07.2017 16:59

            Спасибо, я это и так знаю. И говорю о том, что спринг мог бы это делать сам. Ровно так же как он строит и другие запросы по имени метода в интерфейсе репорепозитория.


            1. asm0dey
              29.07.2017 17:04

              Они это сделали с помощью другой абстракции — Pageable. Чем она вас не устраивает?


        1. asm0dey
          29.07.2017 16:22

          Возвращайте InputStreamResource или FileResourse — это законные действия.


          1. echipachenko
            29.07.2017 17:00

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


            1. asm0dey
              29.07.2017 17:06

              Зачем? И если вам так этого не хватает — почему не сделаете PR с этой функциональностью? И где можно посмотреть хотя бы на feature request на эту функциональность? Или вы думаете что ребята из pivotal читают мысли разраобтчиков через libastral?
              Я обычно иду по одному из двух путей — либо делаю PR, либо feature request. Вероятно кто-то выбирает третий путь — пожаловаться на хабре — и ему это помогает, но я не особенно в это верю.


              1. echipachenko
                29.07.2017 17:17
                +1

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


                1. rraderio
                  29.07.2017 17:22

                  Будет очень круто


                1. asm0dey
                  29.07.2017 17:41
                  +1

                  Мне кажется неконструктивным ругать то, чем не пользуешься.


                  1. s-kozlov
                    30.07.2017 11:04

                    *пользовался


    1. rraderio
      31.07.2017 10:57
      +1

      Попробуйте пописать годик-два проект например на Play Framework-е, желательно на старом, что бы без DI.

      Почему без DI? Если DI настолько плох, почему его внедриои в Play?


  1. pqgg7nwkd4
    27.07.2017 17:54
    +1

    Неужели нельзя просто взять и сделать руками (велосипед, если хотите)?
    Я не первый день занимаюсь разработкой веб-приложений и до сих пор не осилил спринг. Сейчас объясню что имею виду.
    Когда я прочел книгу про Java EE и про Spring, я прям загорелся: «а что так можно было?». После того как начал искать в сети и пробовать — я почти во всем разочаровался.

    1. Тот же DI — крутая штука, но я так и не понял когда ее крутость может пригодиться в бою. Мне всегда было достаточно Singleton-ов и ThreadLocal-переменных. Аналоги Session-бинов, по-моему уже не нужны, больше проблем будет, чем пользы; это можно сказать в целом про сессии на сервере.

    2. @RequestMapping("/helloWorld"). По сути мы выставляем метод наружу. И этот маппинг — дополнительная, на мой взгляд, не нужная абстракция. В своих приложениях я выставил методы наружу по их собственному имени, например, /ru/example/Booking.list?param1=… Это понятнее.
    Превратить get-параметры в параметры вызова, а результат функции в json не составило труда. Это действительно очень просто сделать.

    3. Security. Все очень здорово придумано: определяешь роли и ассоциируешь их с пользователями. А методы с ролями. Но в бою это работает плохо и неэффективно, потому что в большой организации обязанности перекладываются из роли в роли постоянно. То одним нужен отчет, то другим. Кому-то можно заселять задним числом, кому-то нет (я про отель). Таких примеров каждый день прибавляется — грани между ролями плавающие. К тому же часто права должны быть параметрическими (например, хочется задать за какое количество дней назад человек может сделать отчет или, допустим, инспектор в отеле имеет доступ в раздел номера, но вносить правки должен мочь только для своего корпуса).
    Каждый раз пересобирать и перевыкладывать проект из-за этого не хочется.
    В своем проекте я иначе это реализовал.
    Есть security-классы, которые описывают те или иные права. Для каждой роли (которые хранятся в базе) задается список классов и их значения (в виде json-а, например)

    У методов задается аннотация со списком классов, которые должны быть у пользователя. Если у роли пользователя нет какого-то класса, то метод вообще не выполняется. Внутри модуля, при необходимости, я получаю экземпляры этих секурити-классов и кодом осуществляю нужные проверки.

    Это более гибко и типобезопасно.

    4. BeanValidation — вот это мне кажется мега-крутой задумкой. Особенно то, что аннотации можно передать на клиент и тот тоже будет выполнять проверки параметров. К сожалению, без контейнера это очень тяжело реализовать, потому, что тут без магии не обойтись: либо использовать нестандартные методы в AnnotationProcessing, либо модифицировать байт-код во время загрузки классов, либо велосипедить контейнер. Пути сложные, поэтому, пока не реализую, у себя я добавляю вызов проверяльщика первой строкой в каждый метод. Внедрять в проект контейнер только из-за BeanValidation не хочется.

    Удивительно, но все это реализовано классами, которые можно пересчитать пальцами рук (ну, возможно и ног). Это действительно очень просто и новый программист быстро поймет как и что работает. И никакой магии. Проект деполится в Tomcat-е меньше чем за секунду. И при этом я не перетрудился, я же программист.

    Ну и не стоит забывать про KISS:
    На мой взгляд у почти всех back-end приложений две основных задачи:
    1. положить в базу то что прислал пользователь,
    2. взять что-то из базы и отправить пользователю.
    Не усложняйте.


  1. adfsgh121
    27.07.2017 17:55
    -4

    тормознутая сама по себе жаба, жрущая гигабайты оперативки плюс тормознутый xml где данные хранятся нерациональным способом в виде текста вместо бинарного способа(что создает избыточность представления, необходимость парсинга, сложность поиска)


  1. moonster
    27.07.2017 18:09
    +4

    Тружусь в относительно большом проекте, несколько сотен тысяч строк кода, все на Spring'е, пока все хорошо.
    Хочется сказать пару слов в защиту:

    • Магия — это действительно плохо. Ряд приемов, например, autoscan, лучше использовать с осторожностью или не использовать совсем, тем более что магия часто замедляет инициализацию контекста.
    • Конфигурировать лучше с помощью Java конфига. Будет вам compile time safety.
    • Импортировать Java конфиги не легко, а очень легко.
    • Spring умеет очень много, сложность его велика, но документация очень неплоха, а главное — никто не вываливает всю эту сложность на программиста за раз. Обычно бывает наоборот: нужна какая-то штука, и в попытках найти решение вдруг оказывается, что в Spring'е есть и это!
    • Подъем контекста Spring'а крупного приложения занимает заметное на глаз время, поэтому в тестах лучше Spring'ом не злоупотреблять. Если же оказывается, что без Spring'а протестировать класс, например, нереально — вы что-то делаете не так.
    • Spring сам по себе не делает мир лучше. Если бардак в головекоде — начинать надо не со Spring'а.



    1. s-kozlov
      28.07.2017 15:28

      Конфигурировать лучше с помощью Java конфига. Будет вам compile time safety.


      Компилятор таки сможет проверить, что всё заавтовайрится?

      а главное — никто не вываливает всю эту сложность на программиста за раз


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

      Если же оказывается, что без Spring'а протестировать класс, например, нереально — вы что-то делаете не так.


      А именно — используем Spring в проекте. Шутка (но с долей правды).

      Если бардак в головекоде — начинать надо не со Spring'а.


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


      1. rraderio
        28.07.2017 15:46
        +1

        А именно — используем Spring в проекте. Шутка (но с долей правды).

        Класс принимает зависимости в конструкторе, в тесте просто создаете новый инстанс класса и передаете зависимости, Spring тут не обязателен.


      1. moonster
        28.07.2017 16:53
        +2

        Компилятор таки сможет проверить, что всё заавтовайрится?

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

        В этом высказывании можно заменить Spring на любую другую не самую простую технологию, смысл особо не изменится. Но, честное слово, я не видел такого не разу. Либо джун Василий не совсем пустоголовый и способен обучаться, либо он не пройдет собеседование и не попадет в проект.
        А именно — используем Spring в проекте. Шутка (но с долей правды).

        Юзер rraderio выше все правильно сказал. Spring'ом можно инициализировать бины, которые про Spring не знают.
        Вообще это здравая мысль, вот только почему-то в поддержку Spring часто звучит такой «аргумент», что он якобы учит молодежь правильной архитектуре.

        Виноват ли в том Spring?


        1. s-kozlov
          28.07.2017 19:22
          +1

          Нет, конечно, но при использовании java он позволяет гарантировать, что при наличии всех зависимостей компонент инициализируется корректно.


          Звучит как «если вы всё сделали правильно и ничего не забыли, компонент гарантированно инициализируется корректно». Вот у меня Spring-конфигурация на Java и, по моему опыту, она вообще ничего не гарантирует. Проект скомпилируется и обосрется через 2 минуты инициализации контейнера, потому что тут не завайрился бин, а тут пропертю забыли подсунуть в файл. Вот это удовольствие автор и имел в виду, когда говорил, что в Spring нет compile time safety.

          В этом высказывании можно заменить Spring на любую другую не самую простую технологию, смысл особо не изменится. Но, честное слово, я не видел такого не разу. Либо джун Василий не совсем пустоголовый и способен обучаться, либо он не пройдет собеседование и не попадет в проект.


          Ну т.е. на него таки вываливают всё это дерьмо сразу.

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


          Виноват ли в том Spring?


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


          1. moonster
            29.07.2017 00:18

            Звучит как «если вы всё сделали правильно и ничего не забыли, компонент гарантированно инициализируется корректно». Вот у меня Spring-конфигурация на Java и, по моему опыту, она вообще ничего не гарантирует. Проект скомпилируется и обосрется через 2 минуты инициализации контейнера, потому что тут не завайрился бин, а тут пропертю забыли подсунуть в файл. Вот это удовольствие автор и имел в виду, когда говорил, что в Spring нет compile time safety.

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

            В зрелом проекте дерьмо неизбежно. Если не Spring, то еще что-нибудь.
            Еще как виноват, потому что хеллоуворлды на нем выглядят просто и весело, создавая иллюзию, что вот за тебя крутые дядьки подумали и сделали мегафреймворк на все случаи жизни, а ты просто пишешь 2 строчки кода — и вуаля, у тебя сама собой вырастет шикарная архитектура и все девки будут твои.

            В сети достаточно инфы про любую зрелую технологию, зачем взращивать иллюзии если есть возможность ознакомиться с опытом коллег? Опять же, ни про какую технологию авторы и причастные не будут говорить плохо, поэтому их дифирамбы нужно сразу выносить за скобки.


          1. fogone
            29.07.2017 12:22

            Проект скомпилируется и обосрется через 2 минуты инициализации контейнера

            Да, есть di контейнеры, которые гарантируют консистентность на уровне компиляции, но это накладывает другие серьезные ограничения на них, которых у спринга нет. Выбирайте, что вам важнее.
            … а тут пропертю забыли подсунуть в файл..

            Звучит как «если вы взяли какую-то другую библиотеку, то она не падает в рантайме если ей забыли пропертю подсунуть в файл».
            Ну т.е. на него таки вываливают всё это дерьмо сразу.

            Нет, обычно проблемы появляются по одной, а если ваш код вообще не работает, то вряд ли стоит в этом винить спринг.
            Еще как виноват..

            То есть вы искреннее считаете, что тот факт, что вы не можете сделать большое приложение на спринге, означает, что никто не может? Я обсолютно согласен с тезисом, что если сложность фреймворка вас пугает, не надо его использовать. Возьмите что-то попроще, возможно ничего более сложного и не потребуется. Остальное можно и напедалить. Но не нужно винить в этом спринг — он лишь инструмент, которым вы или умеете пользоваться и получаете то, что нужно или нет. Лично для меня важно, что я могу воспользоваться готовыми решениями и их интеграцией из коробки, а не писать их заново. Конечно никакое решение не идеально в том числе и спринг, просто не нужно строить на этот счет иллюзий и выбирать инструмент по себе и своей задаче.

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


            1. s-kozlov
              29.07.2017 17:22
              +1

              Да, есть di контейнеры, которые гарантируют консистентность на уровне компиляции, но это накладывает другие серьезные ограничения на них, которых у спринга нет. Выбирайте, что вам важнее.


              А бывает DI вообще без контейнеров, который еще и валидируется компилятором.

              Нет, обычно проблемы появляются по одной


              Ты можешь позволить себе такую роскошь, когда начинаешь проект в одиночку. А когда ты вливаешься в уже довольно большой проект… Из моего личного опыта: приходишь на проект, а там — куча магии: Spring, Hibernate, Spring Data JPA, Dozer, AspectJ и прочий reflection. У меня ушло примерно полгода на то, чтобы во всем этом более-менее разобраться и начать делать более-менее серьезные изменения. И не надо мне рассказывать, что это я такой дурак. Я себе цену знаю.

              То есть вы искреннее считаете, что тот факт, что вы не можете сделать большое приложение на спринге, означает, что никто не может?


              То есть вы искренне считаете, что спринг могут ругать только неосиляторы? Ну если считать Spring верхом совершенства, то конечно. А если ненадолго включить логику и воображение, можно подумать о людях, которые просто осилили и переросли Spring. Кто-то расширял кругозор и нашел что-то более удобное (даже если только для его проекта). Кто-то заглянул под капот Spring и не увидел там ничего сверхъестественного, а просто набор паттернов, одни из которых реализованы удачно, другие — не очень, третьи — вообще отвратительно. Ну а для кого-то Spring так и остался шайтан-машиной с книгой @Заклинаний.


              1. rraderio
                29.07.2017 17:35

                Из моего личного опыта: приходишь на проект, а там — куча магии: Spring, Hibernate, Spring Data JPA

                У Вас на тот момент был уже опыт работы со Spring и Hibernate?


                1. s-kozlov
                  29.07.2017 17:37

                  У Вас на тот момент был уже опыт работы со Spring и Hibernate?


                  Был — в этом вся соль.


                  1. rraderio
                    31.07.2017 20:17

                    И что же там было трудно понять? Обычно приложение на Spring это куча сервисов с DI, Spring Security и Spring Jdbc


                    1. s-kozlov
                      01.08.2017 09:29
                      +1

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


                      1. rraderio
                        01.08.2017 11:34
                        +2

                        Т.е. у вас были проблемы не с Spring а с Spring Data JPA :)
                        Вместо него можно взять Spring JDBC без рефлексии


                        1. Borz
                          01.08.2017 13:27

                          строго говоря и Spring Data JPA можно без рефлекции готовить


                        1. s-kozlov
                          02.08.2017 14:02

                          Можно много без чего, и без спринга тоже.
                          Spring Data JPA — это всего лишь частный пример, не надо к нему цепляться. Отрубите голову гидре — а там еще куча этих голов.


              1. fogone
                29.07.2017 20:37
                +1

                А бывает DI вообще без контейнеров, который еще и валидируется компилятором.

                Я так и написал.
                У меня ушло примерно полгода

                Тут конечно у каждого будут разные сроки на освоение, но главное, что один раз потратив это время, в любом другом проекте вам не нужно тратить пол года, чтобы разобраться с местными велосипедами, а вы просто начинаете писать код. Да это не золотая пуля, он далек от идеала. Но его делает толковая команда с хорошим qa, его знают разработчики, он решает реальные задачи и развивается. Этого достаточно, чтобы выбрать его вместо самописного решения.
                То есть вы искренне считаете, что спринг могут ругать только неосиляторы?

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


                1. s-kozlov
                  30.07.2017 11:09
                  +1

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


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

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


                  1. fogone
                    30.07.2017 11:36

                    А если «велосипед» грамотно написан, там не в чем разбираться, т.к. всё делается очевидно

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

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


                    1. s-kozlov
                      31.07.2017 15:44

                      Обычно под словом «магия» я подразумеваю, что всё сделано через жоreflection.

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


                      Шаг влево, шаг вправо…


                      1. Borz
                        31.07.2017 16:00

                        тесты тоже через жоreflection работают


                        1. grossws
                          31.07.2017 17:15

                          Тесты не сильно смущают обычно. Они таки в проде не запущены.


                          Конечно, когда it-suite выполняется час-другой, то очень хочется оптимизации, но это другая проблема.


                        1. s-kozlov
                          31.07.2017 17:36

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


                      1. fogone
                        31.07.2017 19:46
                        -2

                        Так и всё же, что же там за страшная рефлексия такая, не эта случаем?


                        1. s-kozlov
                          01.08.2017 09:29

                          Reflection


          1. sshikov
            29.07.2017 14:31

            а тут пропертю забыли подсунуть в файл. Вот это удовольствие автор и имел в виду, когда говорил, что в Spring нет compile time safety.

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


            Сорри, может вы не то имели в виду — но именно так оно почему-то и выглядит. Нет compile time safety во многих случаях — когда у вас в проекте база, она вам этого не гарантирует, когда у вас вообще любые внешние данные. И никто кроме вас этого гарантировать не может.


            1. s-kozlov
              29.07.2017 17:00

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


              1. rraderio
                29.07.2017 17:05

                Вы интеграционные тесты пишите? Если с пропертями что-то будет не так вы поймаете это в тестах


                1. s-kozlov
                  29.07.2017 17:38
                  +1

                  А разве интеграционные тесты не требуют поднятия всей системы?


                  1. rraderio
                    31.07.2017 19:48

                    Ну да, тогда Вы и узнаете что есть проблемы


                    1. s-kozlov
                      01.08.2017 09:32

                      Так, это уже другая тема. Речь была о том, что Spring стартует долго. Проперти — дело десятое.


                      1. rraderio
                        01.08.2017 10:06

                        И Вы хотите чтобы эти проперти проверялись на этапе компиляции?


                        1. s-kozlov
                          02.08.2017 14:02

                          Нет, где я такое говорил?


                          1. rraderio
                            02.08.2017 14:19

                            Ну а когда проверять эти проперти? Spring делает это в рантайме, вот и прочима почему он стартует дольше.


                            1. s-kozlov
                              03.08.2017 11:20

                              Меня вполне устраивает, что он проверяет их в рантайме. А тормозит он не из-за этого.


              1. sshikov
                29.07.2017 18:09
                -1

                Да хоть через сто лет. Файл это внешние данные. Type safety для них не обеспечивается никогда.


                Если у вас от содержимого файла с внешними данными зависит, упадет ли приложение — это точно не проблема фреймворка. Никакого.


                1. mayorovp
                  29.07.2017 18:58

                  В этом-то и проблема, что часть приложения зачем-то объявили внешними данными.


                  1. sshikov
                    29.07.2017 19:05
                    -2

                    А спринг тут при чем?


                1. s-kozlov
                  30.07.2017 11:10

                  А мне вот, представьте себе, не пофиг, пару секунд стартует мое приложение или пару минут.


                  1. Borz
                    30.07.2017 11:25

                    вы можете узнать чуть раньше об отсутствующей property, если будете использовать @ConfigurationProperties, т.к. такие бины, по идее, должны инициироваться раньше остальных.


                  1. sshikov
                    30.07.2017 11:43
                    -1

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


                    И да, у меня две минуты стартует приложение, в котором порядка 100 спринговых контекстов. Так что проблемы медленного старта тоже как правило не от спринга, а из головы. И решать их надо головой — путем профилирования, выяснения, что именно тормозит, и потом оптимизации, а не путем пустой ругани на фреймворк.


                    1. s-kozlov
                      31.07.2017 15:50

                      Да мне наплевать, сколько стартует ваше приложение.


                      Ну и что вы тогда забыли в этой ветке?

                      А если у вас претензии к времени старта — так формулируйте их именно так, о чем я вам сразу и написал.


                      А я так и сформулировал, просто надо внимательнее читать.

                      И да, у меня две минуты стартует приложение, в котором порядка 100 спринговых контекстов. Так что проблемы медленного старта тоже как правило не от спринга, а из головы. И решать их надо головой — путем профилирования, выяснения, что именно тормозит, и потом оптимизации, а не путем пустой ругани на фреймворк.


                      Решать головой — это выбирать такие инструменты, чтобы решать свои бизнес-проблемы, а не проблемы кривых инструментов.


              1. Borz
                29.07.2017 18:09

                как вы кастомизируете свои наработки без использования пропертей под разные окружения?


                1. s-kozlov
                  30.07.2017 11:11

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


                  1. Borz
                    30.07.2017 11:13

                    и как вы проверяете у себя проблему отсутствия какой-то property в каком-то окружении?


                    1. s-kozlov
                      31.07.2017 15:52

                      При запуске приложение упадет. Какая разница? В этой ветке обсуждается то, что Spring запускается долго.


                      1. fogone
                        31.07.2017 19:52

                        У меня быстро запускается, может вы что-то перепутали? Можете ссылочку дать на приложение, которое долго запускается из за спринга?


                        1. s-kozlov
                          01.08.2017 09:34

                          Не могу, т.к. оно принадлежит не мне. А в своих личных проектах я не использую Spring.
                          И вообще, аргумент про «кривые руки» даже слышать не хочу. У меня прямые.


                          1. fogone
                            01.08.2017 15:56
                            +1

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


                            1. s-kozlov
                              02.08.2017 14:03

                              Вы хотите сказать, что в большом проекте Spring противопоказан? Потому что если у меня 100500 бинов… Ну сами понимаете, их сканировать таки надо.


                              1. rraderio
                                02.08.2017 14:24
                                +1

                                Можно не сканировать а в конфигурации указать


                                1. s-kozlov
                                  03.08.2017 11:22

                                  Ну т.е. Service, @Autowire и т.д. не использовать? Или я что-то не догоняю


                                  1. rraderio
                                    03.08.2017 13:42

                                    Да. @Autowired не нужен, так как зависимости получаем чкрез конструктор. Вместо Service в конфигурации указываем бины.


                              1. Borz
                                02.08.2017 15:11

                                IMHO, в "большом" проекте (читайте — "монолите") я бы уж точно не в первую очередь заморачивался на то, за 30 секунд стартует приложение или за 2 минуты.


  1. gkislin
    27.07.2017 20:19
    +2

    Таки надеюсь что автор не призывает полностью отказаться от библиотек-фреймворков и писать все самому:)?
    Тогда вопрос встает о том, чем его заменить.


    • DI из статьи не понял хотят ли выбросить… надеюсь что нет. Заменить можно Guice например..
    • утильных классов не очень много, их вполне перекрывают apache commons / guava. Однако тот же CharacterEncodingFilter скорее всего придется скопипастить
    • для spring-security-web/spring-security-config самому на основе сервлетов тоже конечно можно написать… но лучше взять готовое
    • webmvc. Можно JAX-RS. Можно взять другой фреймворк- playframework, vert.x. Будет он проще и свободен от того, чего автор не любит? Но в любом случае не писать самому!!
    • spring-test, spring-security-test — или подбирать отдельные библиотеки или опять же взять готовый другой фреймворк
    • spring-jdbc, spring-datajpa. Есть альтернативы: jooq, mybatic… Лучше опятьже взять уже интегрированные в фреймворк. И сравнения скатываются к достоинствам-недостаткам ORM
    • spring-cloud можно заменить akka, можно еще кучу библиотек
    • … и так далее по всем остальным модулям Spring
      Что имеем в результате? Сильно сомневаюсь, что радость от программирование, скорось разработки и качество кода проекта станет выше.
      spring-boot- да, за простоту запуска и все-из-коробки приходится платить тем, что его нужно поковырять, чтобы настроить. Но там все доступно, код на java и нет никакой автогенерации.
      Те если надо сделать веб-приложение с авторизацией и базой данных (70% приложений) не вижу альтернативы писать все самому и набирать из разных библиотек. Только взять дургой фреймворк, который непонятно чем будет лучше для автора.


    1. alek_sys
      01.08.2017 10:18
      +2

      Простите, не могу удержаться, но если взять Guice + JAX-RS + библиотека для секьюрити + библиотека для тестов + JOOQ или MyBatis + Akka, научить их работать вместе, управлять их версиями и проверять на совместимость — то вы получите свой, персональный Spring :)


      Никакой из компонентов Спринга точно не уникален, возможно они и не все самые лучшие среди конкурентов — но они просто хорошо играют вместе.


      1. Borz
        01.08.2017 11:16

        я так понимаю, ключевое тут "научить их работать вместе, управлять их версиями и проверять на совместимость"


      1. s-kozlov
        02.08.2017 14:06

        но они просто хорошо играют вместе


        В конце этой фразы очень не хватает «ИМХО».

        научить их работать вместе


        Применительно к модульным библиотекам это надуманная проблема. Ее просто нет. Это фреймворки плохо дружат друг с другом.


  1. Scf
    28.07.2017 09:58

    Имхо, всё упирется в квалификацию программистов. Множество компаний при разработке ПО, особенно на заказ, предпочитает концепцию «дешево и сердито». Когда без знания HTTP пишут спринговые контроллеры, без знания яваскрипта — JSF/Vaadin, без знания SQL — Hibernate. И без умения проектировать серверный софт для продакшна берут готовый фреймворк и настраивают его через XML.

    Конечно же, если нужно сделать что-то быстро, большой старый фреймворк позволит в кратчайшие сроки сделать нечто приемлемо работающее. НО — в нагрузку к 5% нужного функционала мы получаем 95% функционала ненужного, который замедляет приложение, добавляет дыры в безопасности и ограничивает свободу маневра. Про маленькие новые фреймворки хорошо написано вот тут.

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


    1. Borz
      28.07.2017 10:35

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

      кто всё это потом поддерживать будет в случае ухода такого профессионала?


      1. Scf
        28.07.2017 12:11
        +1

        Оставшиеся профессионалы? Сейчас софт в одиночку никто не пишет. «Поддерживаемость» кода в гораздо большей степени зависит от квалификации программистов и качества процессов разработки, чем от использования стандартных фреймворков.


    1. semio
      28.07.2017 12:38

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

      Вот сейчас все, кто использует Spring вместо набора разнородных библиотек, должны почувствовать себя не профессионалами? ))


      1. Scf
        28.07.2017 12:53
        +1

        Почему же — только те, кто не имеет достаточно знаний и опыта, чтобы обойтись без спринга) Так-то, конечно, может быть множество причин сидеть на спринге.


        1. Borz
          28.07.2017 13:16

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


          1. Scf
            28.07.2017 13:43

            А вы умеете им пользоваться?


            1. Borz
              28.07.2017 15:16

              вы таки не поверите.


              А ещё могу привести пример со швейной машинкой, в которой кучка настроек на разные случаи, но зачем нужен этот "фреймворк", когда есть шило, куча иголок и различные напёрстки? Да, шить буду дольше чем на машинке, но зато мне не понадобятся всякие шпульки, одинарные-двойные иголки, лапки, да ещё и регулировать верхний и нижний натяжитель нити под разные задачи.


              1. Scf
                28.07.2017 16:06

                Если умеете, тогда выбор инструмента — это ваш выбор. Как профессионала.


                1. Borz
                  28.07.2017 16:08

                  возвращаемся к


                  Профессионалу намного удобнее взять набор маленьких, качественных библиотек


    1. fogone
      28.07.2017 18:11

      Профессионалу намного удобнее взять...

      Это вы как профессионал так хорошо обобщили?


  1. hexploy
    28.07.2017 15:43
    +1

    Для меня самая неприятная часть работы — это пытаться подружить различные фреймворки.
    Особенно неприятно когда приходится играться с их версиями. И почему-то всегда в центре месива — спринг.
    За одно только это я его, гхм, недолюбливаю.


    1. fogone
      28.07.2017 18:17
      +1

      Конечно в центре мессива спринг, ведь это фреймворк для интеграции решений. Это всё равно что сказать, что бомба падает всегда в центр воронки.


  1. rraderio
    28.07.2017 15:57

    Для меня самая неприятная часть работы — это пытаться подружить различные фреймворки.

    И как часто Вы добавляете фреймворки в проект?


    1. s-kozlov
      28.07.2017 19:25

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


      1. rraderio
        31.07.2017 11:03

        И как часто Вы меняете версии библиотек/фреймворков?


        1. s-kozlov
          31.07.2017 15:52

          При чем тут версии?


          1. rraderio
            31.07.2017 16:14

            Особенно неприятно когда приходится играться с их версиями.


            1. s-kozlov
              31.07.2017 17:37
              +1

              А, это вам надо в другую ветку


  1. nekoval
    01.08.2017 10:13
    -2

    Аннотации — это ужос и израиль, их придумали на волне анти-XML моды и они зачем-то остались, как памятник. Я бы использовал XML.

    Когда-то для интереса писал проекты без Spring, через некоторое время устал мучаться и перепилил всё на Spring, зачем делать велосипеды?