Как стать автором
Обновить
66
0
alek_sys @alek_sys

Пользователь

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

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

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

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

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

1) Идея Spring во многом — это абстракции. Мы не работает с базой данных напрямую, работаем с абстракцией — база это (теоретически) заменяемая реализация. То же самое и с сервером — мы не настраиваем сервер напрямую, мы используем конфиг файл, по которому потом Spring Boot настроит сервер. Это делается в файле application.properties — там есть целая секция Web Properties (включая порт). И теперь если мы заменим Tomcat на Jetty (а это тривиальное изменение в pom.xml) — то те же настройки будут применены и там.

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

Про root думаю актуально и для Апача, просто он скорее всего уже был установлен (под рутом) и работает как демон — поэтому занимает порт 80.

2) Важный момент — модель будет автоматически создана только в нашем конкретном приложении, т.к. это in-memory база (и считается временной для разработки). При подключении к реальной базе — Spring (точнее, Spring Data, а еще точнее конкретная ORM — Hibernate) может либо создать схему автоматически, либо проверить, что модель энтитей соответствует структуре таблиц. Первый вариант в продакешене, разумеется, никто не использует — все работают с миграциями БД (flyway или liquibase). Второй вполне работает для прототипов или интеграционных тестов.

SELECT и любые другие запросы писать точно так же можно, просто они остались за рамками статьи.
А вот раз уж вы подняли такую тему — а зачем? Я уже давно работаю со Спрингом, но как циклическую зависимость сделать — не знаю. Более того, никогда не делал — и считаю наличие циклической зависимости проблемой дизайна. Т.е. круто, что человек это знает, но вот если не знает, то это о чем говорит?
Еще посоветую отличное видео про Spring Boot от двух ключевых людей в команде — Andy Wilkinson и Stéphane Nicoll. Правда, видео идет два с половиной часа на английском, но зато там как раз про внутренности Spring Boot, как и что он конфигурит, какие у него могут быть критерии и т.п.
Make JAR, not WAR! Размер JAR с включенным сервером (!) Tomcat, Spring, Spring Data, H2 in-memory DB (пример из этой статьи) — 0.028 Gb (28 Mb). Причем как я уже говорил, кроме этого файла на сервере не нужно ничего (кроме JRE). Так что сарказм, скорее, себя не оправдал :)

PS. Сразу отвечу про использование памяти — сам фреймворк съедает примерно 32 Мб памяти. У Дейва Сайера, одного из участников команды Spring Boot есть исследование про потребление памяти Спрингом.
Вообще это хорошая мысль, может я соберусь продолжить эту статью второй, и пусть на базовом уровне, но объяснить внутренности приложения — типа бинов, конфигурации, автоконфигурации, что делает Boot. Думаю, будет очень полезно. Может даже на этом же приложении рассмотреть, развеять магию и сорвать покровы!
Ссылки сейчас не найду, но общее правило, которому рекомендуют придерживаться и которое сильно облегчает рефакторинг и написание тестов это: если зависимость для вашего компонента обязательна и без нее он не работает, то это должно быть в конструкторе (т.к. это контракт), если это зависимость опциональная, и без нее компонент работает (логгер) — ее можно через property injection. Но вообще кейсов для Property Injection очень мало и с ними надо быть очень осторожным.
Здесь вопрос не в сложности, а в количестве новых понятий. Архитип — уже новое. Maven плагин для толстого Jar надо ещё настроить, для тонкого — знать какие зависимости и куда деплоить. Надо смотреть что такое WlidFly и GlassFish, выбирать из них. Получается много не сложных по отдельности составных частей — но все вместе получится не очень просто.

И цель моей статьи была как раз показать, что чтобы начать — все эти составные части знать не нужно.
Пора, пробовал, написал :)
«Напишите такую книгу, которую бы вам самим хотелось прочитать» — то же, и со статьей. Я хотел написать статью, которой мне самому не хватало когда-то. Речь в комментарии, о котором идет речь (я его оставил), шла что для новичка это не нужно. Это даже не то, чтобы сложно, это скорее лишний уровень абстракции в самый первый день. Так же, как и деплой WAR-ника на сервер (который же надо поставить и запустить, а мы новички). И там даже ниже в комментариях был вопрос — а как убрать имя WAR из пути? Конечно, мы же все знаем — назвать его root.war. Но я намекну — для человека, который первый раз в жизни видит Tomcat это не так же очевидно.

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

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

А вот по поводу Boot не соглашусь, тут я, увы, из другого лагеря — я считаю, что в наши дни не использовать Boot — это странно. Т.е. допускаю, что для некоторых команд и проектов проще без него, но в среднем по больнице — это именно то, чего не хватало Spring. Чего-то, что просто работает. А уж тем более для начинающих разработчиков.
По мотивам этой статьи написал мой взгляд на то, как начать писать на Spring
Зависит от проекта. Если это Spring без извращений — то это Spring MVC и там в пути war не будет, если задеплоить проект как root.war / root.jar. Если проект новый и там Spring Boot — то ничего деплоить не нужно, просто запустить полученный jar через java -jar . Boot предоставляет настенный и готовый к запуску embedded Tomcat.
P.S. Если все таки Spring — то есть супер вещь Spring Initializr, он может сгенерить (если выбрать Web зависимость) готовый и настроенный Maven / Gradle Спринг проект, в котором все сразу будет работать и который можно будет запустить из Idea или командной строки.
Дорогие начинающие Java-разработчики (и автор?), пользуясь случаем очень хочется сказать пару вещей. Во первых, не обращайте внимания на комментарии, некоторые люди легко забывают что сами когда-то продирались через дебри мутной и пугающей документации для сервлет контейнеров, чтобы понять что вообще там к чему. Во-вторых, не думайте сильно сервлетами и прочими низкоуровневыми абстракциями.

Первая реакция, которая возникает, когда пытаешься задеплоить Hello World в сервлет контейнер, даже следуя такому простому и понятному руководству, как в этой статье — это ужас. Особенно после простых, как бревно, Node.js, PHP, Python. И наверное возникает мысль «Зачем люди так делают?!». Так вот, в целом — не делают. Сейчас на уровне сервлетов пишут и мыслят только разработчики фреймворков, для обычных разработчиков знать и понимать их полезно, но возможно не в самую первую очередь.

Так вот, если вы смотрите на то, чтобы начать web-разработку на Java в 2017, я бы порекомендовал следующее:
1. Особо не погружайтесь в дебри JSP или сервлетов. Берите простой и понятный веб-фреймворк, типа Spark, Ninja, Jooby — там все очень удобно и понятно. Плюс современные и приличные движки для шаблонов, а не (кхм) JSP.

Вот пример на Spark:
import static spark.Spark.*;

public class HelloWorld {
    public static void main(String[] args) {
        get("/hello", (req, res) -> "Hello World");
    }
}


2. Не разбирайтесь (пока) в тонкостях сервлет-контейнеров и деплоя WAR, любой фреймворк даст embedded сервер, который запустится в командной строке

3. Даже не смотрите (пока) на сервера приложений и Java EE, там сразу слишком много новых концепций. Если хочется современного энтерпрайза — можно посмотреть на Spring, начиная с малого. Вопреки популярному заблуждению, он простой, легкий, и удобный для новичков — если брать Spring Boot.

Современная Java это все-таки не совсем ужас-ужас, вот эти все килобайты XML и JSP сейчас, к счастью, не нужны чтобы начать писать web-приложения.
Потоки: для того чтобы не перепутать что именно подразумевается под потоком я буду использовать существующий в профессиональной литературе синоним — нить, чтобы не путать Stream и Thread, всё-таки более профессионально выражаться — нить, говоря про Thread.


Я бы все таки порекомендовал переводить thread как «поток», «нить» это чаще всего fiber, который не совсем поток. По крайней мере, раньше во многих книгах использовалась именно такая терминология. Ну, либо вообще не переводить.
Я бы не советовал как пример приводить вызов suspend методов. Все-таки suspend методы это очень специфичный механизм работы корутин (экспериментальной фичи) из 1.1, который настолько интегрирована в язык и инфраструктуру что вызов из Java и будет выглядеть абсолютно чужеродно.

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

Банальный пример, Скала:
collection.mutable.Map[String, String]().isInstanceOf[java.util.Map[String, String]] // false

и Котлин
emptyMap<String, String>() is java.util.Map<*, *> // true


И хотя у Скалы есть asJava, но все равно не используя полностью всю мощь коллекций Скалы наверное жить в мире Скала не очень весело.

Еще Котлин хорошо интегрируется во все системы байт-код «хакинга» (типа Мокито, хотя и не без проблем), анализа и т.п. Поэтому с ним работают Спринг (официально) и даже магические библиотеки типа Quasar (которые от поддержки Скалы отказались как раз по причине заморочек с байт-кодом). Т.е. Котлин чувствуется именно что «лучшей Java-ой», а Скала все таки другим языком и иногда даже другой платформой. Что в целом не плохо само по себе.

На какой-то конференции была фраза, что Котлин и Джава достаточно похожи, чтобы можно было легко перейти с одного языка на другой, но достаточно разные, чтобы этот переход того стоил.
Там тоже свои страсти кипят — ASP.NET Core 2.0 внезапно оказалась несовместима с .NET Framework 4 (который полный), а только с .NET Core 2.0. Уже почти 600 комментариев к issue.
Это поменялось. Я серьезно думаю написать статью, чтобы развенчать мифы о современном Spring (Boot). Там нет XML, и пример REST приложения вполне умещается в комментарий:
@SpringBootApplication
@RestController
public class DemoWebApplication {

    @GetMapping("/")
    public String helloWorld() {
        return "Hello, World";
    }

    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(DemoWebApplication.class, args)
    }
}

Все. Это не генерит никакой код — просто автоматически конфигурирует приложение. И это полностью self-contained приложение — ему не нужно application server-а, его можно просто запустить — т.к. JAR вполне себе executable. На Kotlin или Groovy это еще лаконичнее и проще.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Зарегистрирован
Активность