Сегодня у нас в виртуальной студии самый известный в мире докладчик по Spring — Джош Лонг.
Именно его докладами открываются Java-конференции по всему миру. Именно он отвечает на вопросы сообщества, делает Spring Tips на YouTube, именно его «This week in Spring» мы читаем каждую неделю и многое другое.
Кстати, Джош разрешил использовать все материалы в нашем собственном «This week in Java», но он делает их в таком объеме и глубине, что эти данные ни разу не получилось сжать до формата «дайджеста на 15 минут».
Иногда кажется, что он находится во всех городах одновременно, читает доклады и пишет статьи в один момент. Сегодня мы будем разбираться, как это у него получается. Узнаем про «юргенизацию кода», причины удивительной живучести Spring и то, как он умудрился прожить столько лет без глобальных переписываний всего с нуля и другие интересные фишки.
Участники
Josh Long, Spring Developer Advocate at Pivotal
Евгений Трифонов, Олег Чирухин — редакция JUG.ru Group
Все знают, что вы много путешествуете, но было бы интересно, если бы вы могли дать некоторую статистику — сколько конференций вы посетили за прошлый год, сколько совершили перелётов и тому подобное.
Хороший вопрос. У меня есть таблица, в которой записаны все встречи, которые я посещаю за год. Моя помощница, Таша, помогает мне организовать расписание и эту таблицу. Так, давайте открою эту табличку в телефоне… Двести сорок. В 2018 году, на данный момент, я посетил 240 различных мероприятий. Некоторые из этих встреч проходят в онлайне (как наша с вами), но до большинства мне приходится лететь. За этот год я пролетел больше полумиллиона миль. Позвольте я проверю, какое расстояние от Земли до Луны… Оно составляет 239 тысяч миль, так что я мог бы долететь до Луны и обратно.
«До Луны и обратно со Spring». Хорошее название для книги Толкина.
Делают ли вам авиакомпании специальные предложения из-за того, что вы так много летаете?
Ну, я не жалуюсь на обслуживание. Я часто летаю с United Airlines, и у них есть программа Global Services. Туда можно попасть, только получив приглашение — самостоятельно вы не можете её для себя попросить, и какие у неё критерии — неизвестно. Каждый год они приглашают людей, которые летают чаще всех. В прошлом году кто-то говорил, что они выбирают 1% наиболее частых клиентов по всему миру. А может, они фильтруют и по объему затрат. Так или иначе, со мной очень хорошо обращаются. Это приятно. Но даже в этом случае, я думаю, для большинства людей перелёты в тягость. Это точно касается меня. Я летаю не для самих перелётов, а чтобы встретиться с людьми, которые используют Spring. Я бы телепортировался, если бы была такая возможность. Жизнь стала бы значительно проще и интереснее.
Хороший повод ждать Hyperloop.
Да, но этого ждать придётся долго.
Давайте поговорим о теме, более близкой к Spring. Вы общаетесь о нём с людьми по всему свету — заметны ли какие-либо региональные различия в его распространённости?
Я бы не сказал. Spring всегда был на 100% опенсорсным, и пока люди пишут софт, который будет работать в интернете, Spring будет продолжать пользоваться успехом по всему миру. Правда, существуют другие опенсорсные проекты, по которым региональная специфика заметна. Статистики я привести в подтверждение сейчас не смогу, но мне кажется, что в России очень распространена GridGain.
Да, это правда.
А в Китае большой популярностью пользуется MyBatis. В США и Европе я не видел его уже лет 10, а в Китае он распространён также, как и Spring. И, в сущности, в MyBatis нет ничего плохого, он быстрый и мощный — так почему бы им не пользоваться?
Мы делали проект, в котором MyBatis работает вместе с GridGain, он там внутри.
(смеётся) Значит, вы пользуетесь и тем, и другим — прекрасно! Мне нравятся обе эти технологии. Для MyBatis не было нормальной поддержки, и я постоянно спрашивал у разных огромных компаний в Китае, которые занимались потрясающими вещами — зачем им вместе со Spring нужен MyBatis? Есть множество других вариантов, очень хорошо работает Hibernate, а MyBatis на Западе практически не используется. В итоге я решил, что, раз программой пользуются, то нужно обеспечить её нормальную работу. Eсли вы сейчас взглянете на исходники Spring Boot Starter для MyBatis, то увидите там моё имя. Мне хотелось, чтобы те, кому нужна эта программа на востоке, могли с ней нормально работать. В целом, значительная часть моей работы вытекает из такого рода открытий, которые я делаю в разных странах во время моих путешествий.
Вы — Developer Advocate в Pivotal по проектам Spring. Что это значит на практике? Чем именно вы занимаетесь?
Непростой вопрос. Концепция Developer Advocate получила распространение благодаря Apple и, в особенности, Microsoft. Началось это где-то 30 лет назад, когда в Microsoft поняли, что именно у разработчиков реальная сила. Если вы хотите, чтобы ваша платформа пользовалась успехом и была полезной, вам нужно, чтобы разработчики создавали новые ценные вещи именно на этой платформе. Соответственно, необходимо убедить их в преимуществах вашей платформы. Microsoft стали пытаться мотивировать разработчиков целым рядом различных способов. Они сделали Visual Studio очень дешёвым, т. е. предоставили доступные инструменты. Они создали много очень интересных API, с которыми можно работать под Windows. В целом, в Microsoft поняли, что необходимо сотрудничать с сообществом. Люди доверяют не софту, а другим людям. У людей нет эмоциональной привязанности к софту. Можно сколько угодно представлять, что вы станете знаменитым, просто написав программу в уединении в своём номере в отеле, а кому нужно, сами найдут документацию. Но в реальности такого обычно не происходит. Значительная часть моих обязанностей — это общение с людьми из сообщества. Я слушаю, что говорят люди, и довожу это до разработчиков, а затем передаю сообществу то, что говорят разработчики. Иначе говоря, я — своего рода проводник.
Команда Spring странная и прекрасная. Ей уже больше полутора десятков лет. Поначалу она была очень маленькой, и консультированием занимались сами разработчики. Они постоянно работали с другими командами, помогая им создавать свой софт, то есть решали реальные проблемы, а не сидели, закрывшись в башне из слоновой кости. Не делали вид, будто заранее знают, какой нужен софт, а писали то, что действительно было нужно другим, и польза всегда была для них основным критерием. Они делили с клиентами их страдания при решении проблем. Мы не создаём никому не нужных вещей. А это, как вы знаете, зачастую бывает проблемой при создании софта. По сути, первая команда Spring уже тогда состояла из Developer Advocates. Они не были похожи на то, какими обычно представляют программистов. Да, они были талантливыми разработчиками, но при этом они охотно обсуждали свои идеи с другими людьми, посещали презентации, встречались с людьми, заводили знакомства, вели диалоги. Благодаря этому Spring быстро обрёл большую популярность.
Проблема в том, что этот подход плохо масштабируется. Невозможно, чтобы все разработчики тратили половину времени на путешествия, общение и встречи. На момент, когда присоединился к команде, я уже писал код для Spring, поскольку он является опенсорсным проектом. Кроме того, у меня уже были опубликованные книги, я писал статьи и выступал с докладами. Так что я уже старался как можно лучше представить Spring сообществу и дать возможность максимальному числу людей познакомиться с ним. Поэтому команда Spring предложила мне заниматься всем тем же, но на постоянной основе и за деньги. Я думаю, я на 80% Developer Advocate и на 20% программист, в то время как остальная команда Developer Advocate на 20% и на 80% — программисты.
В целом, моя работа заключается в том, чтобы поддерживать связи с сообществом, и для этого есть множество различных способов. Я сейчас пишу свою шестую книгу, она называется «The Reactive Spring Book»; моя предыдущая вышла в издательстве O’Reilly под названием «Cloud Native Java». Я сделал много видеоуроков, которые можно посмотреть на Safari Books Online, каждый из них по 4-5 часов. Кроме того, каждую среду я выкладываю видео Spring Tips на YouTube, каждое из которых посвящено определённому узкому аспекту экосистемы. Они обычно длятся от 45 минут до часа, каждый год я делаю минимум два сезона, иногда три. Таким образом, из года в год я каждые две недели готовлю достаточно материала для полноценного доклада на конференции. Начиная с января 2011 года каждый вторник без исключений я делаю новую запись в блоге «This week in Spring», в котором я делаю обзор всего самого интересного в экосистеме. Я также веду другие блоги, последние два вечера я занимался именно этим. Помимо этого, я также пишу код и выступаю на конференциях. Так что моя работа включает в себя максимум самой разнообразной деятельности — но я вполне мог бы ограничиться чем-либо одним. Есть люди, которые только ведут блоги или только снимают видео, и делают это очень хорошо. Некоторые даже не путешествуют, а ведут семинары в онлайне. Мой подход отличается от других, но, в конечном итоге, вся эта деятельность преследует одну и ту же цель.
Кстати говоря, в мои обязанности также входит делать туториалы, вести блоги и так далее. Для меня это очень непросто и может занять произвольное количество времени. Насколько тяжело это даётся вам? Скажем, сколько времени занимает подготовка одного видео «Spring Tips»?
Забыл сказать — у меня появился новый подкаст, в нём пока ещё ничего не вышло, но уже подготовлено семь интервью :-) Что касается времени на подготовку, то здесь бывает по-разному. Если я уже знаком с темой, которую я решил освещать, то мне достаточно сесть и записать всё два или три раза — я всегда делаю много ошибок. Это занимает около четырёх часов один раз в неделю, то есть немного. Но в других случаях этого бывает недостаточно. Иногда я изучаю некоторую проблему и делаю записи по ней в течение многих месяцев, а потом решаю, что, раз эта работа уже проделана, то почему бы не снять по этим записям видео. Я постоянно учусь, как, наверное, и вы. Но такие ситуации, когда мне нужно изучить что-то специально для видео, возникают редко. Самое тяжелое здесь — решить, что нужно сесть и углубиться в тему, а не сам процесс изучения.
Иногда программисты из нашей команды выпускают что-то такое, что раньше никто никогда не создавал. В этой ситуации у людей, конечно, будут вопросы, и эти вопросы по умолчанию посыпятся на программистов. А я могу сделать видео, где всё будет объяснено, и заранее выложить его в сеть, чтобы у людей было время познакомиться. Очевидно, что в этой ситуации мне тоже приходится учиться — коль скоро речь идёт о чем-то совершенно новом.
Сколько проектов сейчас существует в Spring?
Хороший вопрос. Я думаю, несколько десятков. Есть очень специализированные модули, некоторые из которых разработаны сообществом, некоторые — командой Spring в Pivotal, или другими крупными компаниями. Вся поддержка для Google GCP была сделана в Google, поддержка для Microsoft Azure — в Microsoft. Но очень многое — как, например, MyBatis — разрабатывается сообществом. Помимо этого, у нас есть отдельные модули, например, Spring Data Neo4j, модуль для графовой базы данных Neo4j. Он является частью проекта Spring Data, но сделан он был в сотрудничестве с Neo4j, основную работу по этому проекту сделали они, он просто жил в нашем git-репозитории. Таких примеров много.
Что касается Spring Boot, у нас с ним работает замечательный механизм под названием Auto-configuration. Он предоставляет людям удобный способ сгруппировать то, над чем они будут работать. Человек просто скачивает JAR-файл в свой classpath, и он автоматически добавляется к запущенному Spring Boot App. Таких Auto-configurations в экосистеме существует очень много, о значительной части я просто не знаю. Они работают как плагины.
А как разобраться пользователям во всём этом многообразии проектов? Есть ли некоторая общая структура или идея?
Скорее всего, вам не понадобятся все проекты. Обозначьте свою цель, и выберите необходимый проект исходя из неё. Я не люблю, когда люди пытаются «научиться Spring» — это бессмысленное занятие. Вопрос надо ставить так: мне нужно написать, скажем, REST API. Мой первый шаг — отправиться на spring.io/guides, где можно найти простое и доступное руководство длиной в 10-15 минут. В нём будет всё, что необходимо знать: какой код писать, в какой папке, как это делать в IntelliJ или в Eclipse или в чём-либо ещё. Мы стараемся объяснять всё очень подробно и не опускаем ничего, потому что хотим, чтобы эти руководства были доступны всем. Чем бы вы ни занимались — JMS, Neo4j, безопасностью, circuit breaker-ами, Kafka — для каждой темы у нас есть отдельное руководство. Определитесь со стоящей перед вами задачей и выберите подходящее руководство. Вам нужно думать не о Spring, а о том, с чем вы будете интегрировать вашу систему — Spring всего лишь является инструментом, который позволяет осуществить эту интеграцию. Поэтому нет смысла «изучать Spring» — его нужно использовать в том случае, если он может упростить вашу конкретную задачу.
Какие проекты в Spring являются, с вашей точки зрения, наиболее перспективными? Или самыми недооцененными?
Большой популярностью пользуется библиотека Spring Retry. Первоначально она была разработана в Spring Batch. Не знаю, пользовались ли вы им когда-либо Spring Batch, он позволяет обрабатывать большие объемы последовательно передаваемых данных, например, документов из файловой системы, XML, CSP-файлов и так далее. В одном из вариантов использования этого инструмента вы производите чтение записи, а затем записываете её — например, из веб-сервиса в очередь сообщений. Обработка этих данных может идти часами, и было бы крайне нежелательно, если бы система из-за одной ошибки в самом конце откатывала бы всю проделанную за ночь работу. Нельзя так делать. Spring Batch работает с пакетами данных, он обрабатывает записи не по одной, а по десяти или по тысяче. Даже если обработка тысячи записей пропадёт, все остальные будут сохранены. Кроме того, при написании пакетных систем нужно иметь ввиду, что вам необходимо обращаться к другим сервисам, которые могут давать сбои. Для этого существует Spring Retry. Эта библиотека позволяет осуществлять повторные вызовы сервисов. Кроме того, в ней можно использовать экспоненциальную выдержку. Помимо Spring Batch, Spring Retry также используется в Spring Integration, Spring Cloud Stream, Spring Cloud Data Flow. В последних двух мы поддерживаем Spring Retry из-за её связей с некоторыми другими вещами. Таким образом, эта библиотека используется во множестве проектов Spring, и я не уверен, что все об этом знают. Spring Retry — очень часто используемая библиотека, которую иногда просто не замечают. В целом, у нас много различных реактивных вещей. Они, как правило, самые интересные.
Почему именно реактивщина?
У нас везде поддерживается реактивность. Преимущество Spring в том, что с ним можно и начать, и завершить проект. На этой неделе мы объявили о том, что будем осуществлять поддержку проекта Facebook RSocket. Это полностью реактивный аналог gRPC, но значительно более гибкий. Его можно использовать для pub/sub, потоковой передачи данных, client request/response — в общем, при помощи него можно реализовать много различных паттернов обмена сообщениями. И он используется в Facebook. Там есть две связки, одна на C++, другая на Java. Та, которая на Java, написана с помощью Reactor, нашей реактивной библиотеки. Её же использует Salesforce. Конечно, есть и другие варианты. Вы слышали о gRPC от Google? Он очень качественный и интересный, но он не реактивный, по умолчанию он плохо работает с реактивными типами. Этого недостатка нет у Salesforce gRPC. У него есть компилятор, который создаёт сервисы на основе Spring Reactor. Так что и Facebook, и Salesforce смогли масштабировать Reactor для своих нужд.
Сам по себе Reactor — один из самых интересных наших проектов. RxJava вышла раньше, но Reactor первым предоставил поддержку реактивных потоков. Это в значительной степени произошло потому, что замечательный программист Дэвид Карнок, руководитель проекта RxJava, работал с нами над Reactor. Так что значительная часть всего нового и интересного, что происходило в нашей экосистеме, так или иначе коснулась Reactor. Благодаря этому проект стал крайне привлекательным для компаний, которые создают большие системы. Reactor также лежит в основе фреймворка Spring WebFlux. Также на основе Reactor мы сделали поддержку для реактивной передачи сообщений, реактивных веб-сокетов, Spring Cloud Stream, реактивных circuit breaker-ов и так далее — все эти компоненты могут быть интегрированы в реактивные приложения. Можно, конечно, пользоваться просто Spring, но я предпочитаю задействовать всю экосистему при помощи этих реактивных типов.
Помимо этого, мы недавно сделали объявление об R2DBC — это наш API для доступа к данным на основе SQL для реактивных драйверов. Реактивной JDBC пока что не существует. Проблема заключается в том, что если вы используете реактивный код, то вы не можете пользоваться блокировкой. Если блокировка используется, то это взаимодействие необходимо масштабировать, увеличивая число тредов. А это противоречит изначальной цели, поскольку мы как раз хотим избежать масштабирования через увеличение количества тредов — это слишком дорого. Поэтому R2DBC предоставляет абстракцию, которая обеспечивает реактивный доступ к данным. Существуют драйверы баз данных, которые изначально реактивные — например, Postgres. Так что вы можете использовать R2DBC, помимо прочего, с Postgres и работать с реактивными SQL, не используя блокировку, поскольку у вас нет тредов. Вся эта тема кажется мне крайне интересной.
Возможно, вы могли бы ответить на некоторые часто задаваемые технические вопросы? Одна из проблем заключается в том, что при использовании нескольких проектов Spring одновременно возникает множество аннотаций. Становится сложно разобраться, что делает каждая из них — нельзя просто щелкнуть по ней, зажав Ctrl, и перейти к определению. Как себя вести в такой ситуации?
Следует запускать с параметром `--debug`. Большая часть экосистемы Spring сейчас существует в виде Auto-configuration. Некоторая часть — как импортированная конфигурация, если в этом случае вы щелкаете по аннотации, то увидите надпись `@Import`, в которой затем будет указан её класс. Если затем вы щелкните по ней, то увидите те объекты, которые были созданы для вас. Но иногда Spring действует через механизм Auto-configuration — в этой ситуации не создаётся никаких аннотаций. Есть только библиотека и classpath. Тогда действительно сложно выяснить, что происходит и почему. Мы же хотим, чтобы людям было как можно проще в этом разобраться. Для этого и существует параметр `--debug`, который необходимо ввести при запуске приложения. Тогда вы увидите отчёт, в котором будут описаны все шаги, выполненные приложением при запуске. Приложение проверяет, существуют ли некоторые поля или классы, и, в зависимости от этого, оно решает, создавать ему некоторые объекты или нет. Отчёт показывает вам, какие условия были выполнены, какие нет, а какие конфигурации не зависели от каких-либо проверок. Так что если вы, скажем, никак не можете понять, почему не работает ваше подключение к Kafka, можно посмотреть на соответствующее условие — возможно, у вас отсутствует необходимый класс в classpath.
Сейчас будет немного троллинговый вопрос. Зачастую противники Spring заявляют, что он является причиной низкокачественной архитектуры, потому что в нём можно просто использовать @Autowired
везде и всюду. Согласны ли вы с таким мнением? Десять лет назад архитектура создавалась в три слоя, значения передавались от конструктора конструктору, создавались DTO. При помощи Spring от всего этого можно избавиться. Хорошо ли это или плохо?
Spring — это инструмент. Он позволяет большему числу людей создавать софт, который доходит до продакшна и правильно работает, поэтому я не считаю, что он приносит вред. За последние годы миллионы людей создали при помощи него приложения, и у них всё прекрасно работает. Считать, что Spring в целом наносит вред — абсурдно, такое мнение иначе, как невежественным, назвать нельзя.
В Spring можно создать вполне эксплицитное связывание (wiring). Если вы беспокоитесь о том, что будет неясно, откуда данный объект был привязан, вы можете привязать его самостоятельно. Можно создать java-конфигурацию, в которой один метод будет вызывать другой, и выходное значение у вызываемого метода будет бином — Spring о нём позаботится. Даже при повторном или тысячекратном вызове одного и того же бина у вас никогда не будет больше одной ссылки, если этот объект является singleton-ом. Хотите, чтобы всё было эксплицитно — это вполне можно сделать. При желании можно обратиться к ещё более скучному варианту — XML. Суть в том, что если вы не хотите пользоваться `@Autowired`, то этого вполне можно избежать.
Если вы пользуетесь Spring Boot наиболее обычным способом, то у вас будет только один бин. Вы знаете, что вам необходим бин типа `ConnectionFactory` — в этом случае нет никакой проблемы в том, чтобы сделать инъекцию по типу. У вас всё равно только один объект, двух `ConnectionFactory` для одного `Connection` у вас не будет. У вас не будет двух сессий Hibernate, так что ничто не мешает вам сделать инъекцию `HibernateSession` — она всё равно существует в единственном экземпляре. Если же вы хотите, чтобы всё было эксплицитно, можете использовать аннотацию `@Qualifier`. При помощи неё вы помечаете то, инъекцию чего вы совершаете по типу. Это позволит отличать различные реализации бинов друг от друга. Предположим, у вас есть сервис, при помощи которого приложения в одном месте могут связываться с iTunes, в другом — с Amazon, в третьем — с Android Play Store. Это будет три различных bean-а разного типа, но каждый будет иметь аннотацию `@Qualifier`. Далее, эту аннотацию можно наложить на другую аннотацию, таким образом обеспечив типобезопасность. Вы привяжете этот тип, и поверх него у вас будет аннотация, а когда bean будет создан, у него будет аннотация `@Qualifier` в т. ч. на сайте потребителя. Таким образом, эти аннотации обеспечат вам ссылки, и, даже если у вас во время работы программы будет три реализации, вы всё равно сможете найти ту, которая вам необходима.
То есть в целом, на ваш взгляд, гибкость является положительным свойством. Придерживаетесь ли вы и команда Spring некоторых основополагающих принципов, наподобие дзена Python?
Да, придерживаемся. Кстати говоря, я программирую на Python с конца 90-х годов, и являюсь большим сторонником дзена Python, у него очень правильная общая мысль. Что касается вашего вопроса, тут надо рассказать про Юргена Хёллера, со-основателя Spring и второго по счёту разработчика, работавшего над проектом. Это милейшей души человек, очень тихий, один из лучших, с кем мне приходилось общаться. С ним очень легко разговаривать, если вы, например, встретили его на конференции. При этом он обладает мощным интеллектом, и его вклад в Spring сложно переоценить. Конференция JAX — очень важная, хоть, конечно, и не дотягивает до Joker :) — дала ему специальную награду за работу, которую никто, кроме него, раньше не получал. Обычно награды выдаются в какой-то специальной категории, но эта — без категории и принадлежит только Юргену. Spring является единственным проектом в экосистеме Java, ни разу не переписанным за 15 лет — потому что в этом нет потребности. Юргена очень ясное представление о том, как писать модули, как выражать типы, в целом — как создавать базу качественного кода, которая может жить десятилетиями и легко меняться при необходимости. Других таких проектов в экосистеме Java нет. Значительной части проектов уже не существует, и даже среди тех, что были когда-либо переписаны с нуля, очень немногие прожили 15 лет.
Без того, чтобы быть переписанным, просуществовал 15 лет только Spring, потому что он с самого начала был написан очень чисто. Юрген научил нас некоторым основополагающим принципам, которым мы следуем: как делать модули, как делать пакеты-реализации (в противоположность публичной части), как как описывать поверхностный уровень API и проектировать для него типы, какие паттерны стоит использовать. Пользуясь Spring, вы неизбежно знакомитесь с паттернами проектирования, и оно так было всегда. Сразу приходит в голову пример паттерна Template. Фреймворк Spring Integration знакомит вас с enterprise integration patterns, Spring MVC — с MVC. Все эти паттерны являются частью фреймворка, и мы используем их, опираясь на проверенные практики. Наш дзен — это принципы, которым нас научил Юрген. В этом отношении мы все — его ученики. Юрген известен за свой немного странный подход к тому, как нужно писать код — из-за его манеры даже возник специальный термин, «юргенизовать». В нашей команде много по-настоящему умных людей с большим опытом, у некоторых уже есть степени и лысины. И тем не менее, Юрген вносит свои правки в их код. Иногда это мелочи вроде добавления пробелов, чистки и так далее, но иногда он переписывает код с нуля в тысячу раз лучше, и при этом он не меняет авторства кода, то есть коммитит под фамилией изначального автора. В этих случаях говорят, что код был «юргенизован», то есть он его исправил. Благодаря Юргену наш код очень чистый. Для инструментов по анализу кода считается знаком высокого качества найти хоть какую-то неисправность в Spring, потому что там очень чистый код. В общем, я не могу вам в подробностях сейчас изложить наши принципы, но они есть, они были заложены Юргеном, и все проекты Spring им следуют. Что же касается именно Spring Boot, то у нас есть очень точные правила создания модулей, которые мы называем starters.
Хорошо, спасибо за ответ. Мой последний вопрос будет касаться производительности и Java 11. Насколько я знаю, Spring всегда генерирует контекст в рантайме. Это может занимать от минут до нескольких часов в некоторых старых банковских программах.
Да ладно? Не верю.
Честное слово, видел своими глазами.
Но это не может быть Spring. Скорее всего, там делается что-то жуткое с Hibernate. Бины можно генерировать миллионами, пустой bean можно скомпилировать и запустить очень быстро. Время занимает загрузка информации из базы данных, валидация и так далее, это может вызвать задержку Spring. Но сам Spring очень быстрый.
Да, я думаю там действительно было какая-та жуть с Hibernate. И тем не менее, Spring запускается 30 секунд, иногда минуту или две — это всё-таки довольно долго, вам не кажется? Если, скажем, мы запускаем его в Docker, то нам нужно, чтобы контейнер запустился сразу же. Можно ли сократить время запуска Spring?
У меня запуск Spring занимает меньше двух секунд. А с помощью Spring Cloud Function это время можно сократить до половины секунды и меньше. У нас есть проекты, которые без проблем запускаются за полсекунды — например, Spring Boot в Spring Cloud Function. Так что, опять-таки, проблема не в Spring, а в том, что вы им делаете, что у вас происходит на фоне — получаете ли вы доступ к другому источнику данных в интернете, загружаете ли файлы из интернета, загружаете ли данные в грид. Если всё, что вы делаете — это маленькие микросервисы, то ваша система должна работать очень быстро. Если ваше приложение запускается очень долго — с ним что-то не так.
Понятно. Кстати говоря, вы слышали о GraalVM и AOT?
Да. Скажу вам больше: у нас есть проект Spring Fu. Он экспериментальный, я снял о нём видео из серии Spring Tips. Писали мы его на Kotlin, сейчас к нему есть Java API. Создавался этот проект для сред наподобие GraalVM. Spring Fu не пользуется динамически генерируемыми прокси или `@Configuration`. Генератору native image в GraalVM нужно знать, какие классы будут загружены. Но если у вас происходит динамическая загрузка при помощи cglib или Byte Buddy, то это затрудняет использование GraalVM. Hibernate, Spring и все другие библиотеки, которые пользуются динамически сгенерированными прокси, плохо подходят для создания native image. Поэтому в Spring Fu ничего подобного нет, об этом прямо говорится. В нём по-прежнему используется Spring, но подход к созданию приложений другой. И одно из преимуществ Spring Fu как раз в том, что он хорошо работает с GraalVM. И теперь приложение запускается мгновенно. В смысле, вообще мгновенно: раз и оно целиком в памяти! При этом нужно помнить, что генератор native image в GraalVM находится ещё на очень ранней стадии разработки. Из-за этого иногда возникают трудности, потому что людям кажется, будто запущенное GraalVM приложение сразу же станет грузиться очень быстро, а в рантайме скорость будет такая же, как и раньше. Но так оно не бывает, потому что в рантайме с GraalVM вы уже не используете JVM, поведение системы будет уже другим. Так что тестируйте этот проект на здоровье, но помните, что он не является бесплатным ускорением запуска. И всё же, я в восторге от GraalVM, их команда очень много усилий приложила, чтобы он лучше работал с фреймворками.
Мой последний вопрос, будет, конечно же, о Java 11.
Да, она прекрасна.
Что в ней есть полезного для Spring?
Для разработчиков Spring есть два главных критерия, по которым мы выбираем ту или иную технологию: 1. подходит ли она для нужд бизнеса, 2. подходит ли она нам как программистам. Что касается первого критерия, обеспечивает ли эта технология более высокую скорость, стабильность, имеет ли она долгосрочную поддержку. Всё это у Java 11 присутствует. Скоро прекратится поддержка Java 8, поэтому имеет смысл перейти на следующий релиз с долгосрочной поддержкой. Кстати сказать, друзья мои, если вы будете переходить на следующую версию, возьмите сборку OpenJDK — она отличная во всех отношениях. Правильную версию получить очень легко, я уже писал об этом на Twitter. Этот релиз очень хорошо работает со Spring — он стабилен. Вы можете хоть сейчас выйти на https://start.spring.io, сгенерировать новый проект, выбрать Java 11 и всё заработает. Поддержка Java 11 есть и в IntelliJ, и в Eclipse.
Что же касается второго критерия, то тут для разработчиков Spring в Java 11 существенных изменений нет. Приятно, что появились `var` и HTTP Client, но в Spring уже был реактивный WebClient, так что я не уверен, что от HTTP Client нам будет какая-то польза. Некоторые удобные вещи были добавлены в Java 10 и Java 9. Кроме того, стало возможным запускать программу Java как скрипт — это неплохо. Я не уверен, что это имеет смысл делать со Spring — хотя с другой стороны, почему бы и нет. Как это будет выглядеть, я не знаю.
Трудно ли было для Spring перейти на Java 11?
Нет. В основе Spring лежат очень качественные библиотеки и экосистема. Имейте ввиду, что фреймворк Spring сам по себе поддерживает как classpath, так и modulepath, но лично я не рекомендую использовать modulepath. Чтобы правильно им пользоваться, всё остальное тоже должно поддерживать modulepath. А это пока что невозможно, сейчас слишком мало людей, обеспечивающих поддержку modulepath в библиотеках. Режим classpath же вполне работает. У нас были вполне стандартные проблемы с CGLib, AspectJ и XML-библиотеками JAXB, которые были у всех при переходе на Java 9. Все эти проблемы были решены примерно за последний год, так что для нас переход на Java 11 был простым.
Кстати говоря, у нас планируется много интересного для следующих версий Java, например, проект Loom — это fibers для Java.
Это будет в Java 12?
Скорей всего нет, это будут делать довольно долго.
В Kotlin тоже используются coroutines, поэтому этот проект нам очень интересен. Когда бы он ни вышел, польза от него будет большая. Возможность выражать реактивные pipelines, при этом не создавая реактивный код, очень важна. Лично я же с нетерпением жду появления многострочных String. Может, это не лучшим образом свидетельствует обо мне — у меня много кода, в котором требуется большое количество строк, например, SQL-запросы и тому подобное.
Так это потому, что у тебя значительная часть кода оптимизирована для показа на слайдах. На слайдах во время докладов будет удобно отображать строку целиком на экране.
Да, иначе становится сложно читать. В IDE они будут выглядеть значительно лучше. Опять-таки, Python, Kotlin, Scala, Groovy — любой язык последних 20 лет предоставляет поддержку многострочных String. По-моему, это вполне естественно.
Возможно, вы хотели бы оставить какой-нибудь совет нашим читателям? Он может касаться Spring или Pivotal, а может быть относительно Java в целом.
Как и с любой технологией, лучшая часть Spring — это его сообщество. Технически, Spring — крайне интересный набор проектов, но секрет его долгожительства — замечательное сообщество. Никому не нужен ваш прекрасный софт, если ради него нужно общаться с невыносимыми людьми. Поэтому мы стараемся быть как можно более дружелюбными. Наши разработчики, в том числе руководители проектов отвечают на вопросы на Stack Overflow и следят там за различными тегами. У нас есть чатрумы на Гиттере, а каждой чатрум в нём соответствует репозиторию на GitHub. Например, https://gitter.im/spring-projects/spring-boot. Там вы можете найти разработчиков Spring и задать те вопросы, которые вас интересуют.
Меня часто спрашивают — как помочь проекту, как начать писать код для Spring. У нас есть множество проблем с тегами вроде «ideal for contribution» на GitHub. Мы рады всем желающим, но не все проекты всем подходят, некоторые баги сложнее других. Так что если вы хотите с нами работать — ищите эти теги и помогайте с проблемами. Именно так происходит пополнение нашего сообщества. Мы ценим работу всех, кто помогает улучшить нашу экосистему.
Минутка рекламы. Джош Лонг приедет на конференцию Joker 2018 с докладом «Reactive Spring». Приобрести билеты можно на официальном сайте конференции.
Автор: Олег Чирухин