• Spring Security — пример веб приложения с авторизацией по протоколу OAuth2 через BitBucket
    0

    Спасибо за работу над статьей, особенно полезны для новичков будут детали протокола OAuth2. Но и здесь есть важный момент — сам по себе OAuth2 это не протокол аутентификации, это протокол авторизации. А вот OpenID Connect это да, аутентификация, и Spring Security его отлично поддерживает.


    Но все, что касается Spring Security в статье это, скорее bad practices, так делать не надо.


    1. Для начала, стоит указать версию SS — поддержка OAuth2 в 5-й версии внесена в ядро и сильно отличается от 4-й.
    2. Если используется Spring Boot, то руками создавать ClientRegistration не нужно, SB это сделает за вас. Более того, Boot из коробки поможет сконфигурировать стандартные OpenID провайдеры вроде Facebook, Google, Github, даже Token URI не надо указывать.
    3. Ну и самое главное — своя реализация UserService не просто не нужна, а даже вредна — например, тут не проверяются многие пункты стандарта, не надо так делать в реальных проектах. Вся конфигурация, в принципе, делается так: .oauth2Login(). Все, SS создаст стандартный UserService для работы с OpenID endpoint (/userinfo), если провайдер поддерживает, провалидирует ответ, создаст IdToken и вообще сделает все правильно и хорошо.
  • Как Quarkus объединяет MicroProfile и Spring
    +1

    Глядя на постоянное упоминание Spring, я думаю очень важно включить в статью следующее замечание из этого гайда:


    Important Technical Note

    Please note that the Spring support in Quarkus does not start a Spring Application Context nor are any Spring infrastructure classes run. Spring classes and annotations are only used for reading metadata and / or are used as user code method return types or parameter types.

    Т.е. используются только аннотации Spring, вся реализация выполнена самим Quarkus и не обязательно совместима.

  • Что нового в Spring Boot 2.2?
    0

    Спасибо за перевод! Думаю, стоит так же дать ссылку на новость от самой команды Spring Boot в официальном блоге Spring.


    Поддержка сканирования classpath для @ConfigurationProperties

    Это уже откатили в версии 2.2.1, теперь такое поведение нужно явно включать используя @ConfigurationPropertiesScan


    Автор оригинала во многом пересказывает официальный анонс, но пропускает самый первый пункт:


    As part of our ongoing efforts to improve performance, we’ve made some significant progress in Spring Boot 2.2 on top of those made in 2.1. Applications will now start even faster and consume less memory while they do so. This can be particularly beneficial in environments with very tight memory constraints.

    В Spring Boot 2.2 было проделано огромное количество работы направленной на уменьшение времени запуска (старт менее чем за секунду для некоторых приложений), использования памяти, нагрузки на GC.

  • Веб-приложение на Kotlin + Spring Boot + Vue.js
    +1

    Хорошая статья, я бы только отметил пару моментов:


    1. При наличии dev-tools не нужно перезапускать приложение, достаточно его перекомпилировать и Dev Tools обновят приложение "по горячему".


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



    Basic Authentication не отвечает современному вызову угроз даже в относительно безопасной среде использования

    Но реализованный подход с отправкой имени пользователя и пароля и получения токена в ответ по большому счету ничем от basic auth не отличается. JWT токен в ответе это маленькая и незначительная деталь релизации, которая ничего не меняет вообще. Цель OAuth — это как раз избавиться от необходимости предоставлять пароль third party приложениям. Текущая реализация, описанная в статье, это single-tenant (т.к. нет client-id) реализация password grant flow из OAuth2 с самодельным IdToken-ом. Так что конкретно для безопасности в production приложении, я бы все же взял Spring Security + OpenID, вместо самодельной реализации.

  • Spring Boot — OAuth2 и JWT
    +1

    Из самых актуальных есть пример от самого Джо Гранжа — главного разработчика Oauth в Spring Security 5: https://github.com/jgrandja/oauth2-protocol-patterns


    Там разные паттерны для OAuth показаны шаг за шагом. Это пример Джо использовал в своём выступлении на Spring I/O 2019 — но видео пока нет, организаторы обещали скоро выложить.

  • Spring Boot — OAuth2 и JWT
    +2

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


    1. Как уже упомянуто выше — проект Spring Security OAuth официально в maintainence режиме и сейчас лучше использовать Spring Security 5 который включает поддержку OAuth2.
    2. Пример когда приложение является и authorization server и resource server очень неудачный и плохо показывает зачем вообще нужен OAuth flow.
    3. Ну и это самое главное — "просто добавьте, наследуйте, создайте, определите" в обучающей статье это все же вредные советы. Зачем определять порядок фильтра? Зачем включать Global Web Security? Что делают все эти странные конфигурации и что они решают? Почему не использовать Spring Boot для всех этих дефолтов?

    Лично я бы очень рекомендовал переводить статьи из качественных источников, сейчас, пожалуй, непризнанный лидер это сайт https://www.baeldung.com.

  • TDD приложений на Spring Boot: тонкая настройка тестов и работа с контекстом
    0
    Помогла бы какая-нибудь аннотация в Junit наподобие BeforeAll

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

  • TDD приложений на Spring Boot: тонкая настройка тестов и работа с контекстом
    0
    Я вот хочу запустить тесты для той же конфигурации, что и везде, но один бин заменить тестовой реализацией.

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


    Вариантов решения есть несколько, зависит от задачи:


    1. Создать базовый класс для тестов с одинаковой конфигурацией. Обычно, это означает тесты для одного и того же компонента (когда замоканы boundaries, об этом еще буду говорить в следующих статьях).
    2. Как уже отмечено — иметь одну базу для всех тестов, если пересоздавать контексты совершенно необходимо.
    3. Подумать над каким-то runtime созданием бинов, но это уже немного воевать с фреймворком.
  • TDD приложений на Spring Boot: тонкая настройка тестов и работа с контекстом
    0

    Я скорее имел в виду, что библиотеки, вроде указанной, не делают ничего магического внутри.


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


    В условном Го просто другой подход: вместо абстракций — повторения. Не лучше и не хуже — каждый выберет свой. В общем-то, в Спринг тоже никто не мешает игнорировать библиотеки тестирования — и хоть руками создавать контексты и делать все, что делает Spring Test, получив полный контроль над тестом. Просто потом захочется абстрагировать одну вещь, чтобы не повторять. Потому другую. А потом получится еще один фреймворк для тестирования.

  • Ленивая инициализация в Spring Boot 2.2
    +2
    Примечание переводчика: я запускал вот этот пример, прописав в зависимостях Spring Boot 2.2, и время запуска с ленивой инициализацией было 3 секунды, а без нее — 4. Думаю, что на более серьезных приложениях, существенного выигрыша во времени старта за счет использования ленивой инициализации мы не увидим.

    В примере используется Hibernate в режиме ddl-auto=update. То есть, во время запуска приложения Hibernate подключается к базе, сканирует структуру таблиц, сканирует структуру Entities в приложении, находит разницу, вычисляет diff sql, обновляет структуру. После всего этого сколько запускается сам Spring, уже, в общем-то, не важно.


    Hibernate вообще жадный до startup time, так что уж если хочется оптимизировать именно время запуска, то надо ставить и spring.data.jpa.repositories.bootstrap-mode=lazy (документация).

  • Как писать на Spring в 2017
    0

    Рано сдаваться :)


    Первая ошибка странная — это от Maven, а Intellij должна запускать приложение напрямую.


    А вторая совсем странно, может установка Maven сломана? Что выдает ./mvnw --version и java -version? Под Windows, кстати, нужно запускать mvnw.cmd.

  • TDD приложений на Spring Boot: работа с базой данных
    0

    Да, убедили, полезная вещь чтобы упомянуть. Добавлю в статью, спасибо!

  • TDD приложений на Spring Boot: работа с базой данных
    0

    Не запустит, но и не должен, это не его обязанность. Вообще немного лукаво называть embedded-database-spring-test embedded — это самый обычный сервер Postgres (точнее, некий lightweight bundles of PostgreSQL binaries with reduced size), библиотека его просто запускает. Почему бы тогда не иметь локальный сервер Postgres и в нем создавать тестовую базу — не совсем понятно. Ну и если уж совсем-совсем надо запустить Postgres и TestContainers не подходят, то лучше использовать проверенные и поддерживаемые библиотеки, вроде https://github.com/yandex-qatools/postgresql-embedded.

  • TDD приложений на Spring Boot: работа с базой данных
    0

    Да, отличное замечание. Стандартные методы CrudRepository возвращают Iterable и я решил вернуть его же, хотя причины на это нет — Spring Data JPA может вернуть и Stream, и даже Set. Обновлю статью и код.

  • TDD приложений на Spring Boot: работа с базой данных
    0

    Ну судя по тому, что я вижу, это просто wrapper для запуска Postgres в рамках тестов + попытка реализовать свой AutoconfigureTestDatabase. В этом, конечно, нет ничего плохого, просто непонятно, какую проблему это решает, которую не решает стандартная тестовая библиотека Spring? И Flyway, и Liquibase @DataJpaTest конфигурирует.


    Если уж хочется принести полноценный embedded postgres, я бы скорее порекомендовал TestContainers, там хотя бы будет изолированный сервер, а не просто запускалка локальной базы Postgres.

  • Как построить пирамиду в багажнике или Test-Driven Development приложений на Spring Boot
    0

    Продолжение готово https://habr.com/post/433958/, следующая статья тоже в процессе.

  • Spring + Firebird + REST. Часть 1 Конфигурирование проекта
    +1

    В общем случае @Entity не должна быть @Data классом, т.к. дата-классы это Value-objects, и, например, проверяют идентичность объектов по всем полям. Для entity же идентичность обычно значит совпадение ID или NaturalId, это важно для многих внутренних механизмов JPA.


    Здесь Влад рассказывает как раз как правильно реализовать equals / hashCode.

  • Настройка приложения — Spring Configuration Metadata
    +1

    Спасибо за статью! Пара моментов, больше для читателей, из того, что не упомянуто:


    1. Самое важное — @ConfigurationProperties это не только про загрузку свойств из application.properties файла. Возможности Spring Boot Configuration гораздо шире — поддерживается 17 (!) разных источников свойств в строгом приоритете. Можно определить дефолт в application.properties и перекрыть его через переменную окружения, JVM properties, профиль, тестовые свойства и т.п. Что дает очень мощные возможности для переконфигурирования приложения в нужном окружении и сильно упрощает конфигурацию. А в дополнение — список источников еще и можно расширять, например, добавить Hashicorp Vault как бэкенд.
    2. ConfigurationProperties аннотация — это часть Spring Boot, а не Spring Core
    3. @SpringBootApplication аннотация включает ComponentScan, так что XML конфигурацию (да и любую конфигурацию) можно убрать и просто аннотировать классы @Component. Хотя некоторые разработчики предпочитают явную конфигурацию над автоматическим поиском компонентов.
    4. Конфигурировать можно не только классы properties, а вообще любой бин — если совместить @Bean + @ConfigurationProperties или @Component + @ConfigurationProperties. По сути, все, что делает @EnableConfigurationProperties — это регистрирует бин указанного типа.
    5. Field и Property injection это, все же, моветон, хотя и не запрещено.
  • Пробуем Micronaut или Дорогая, я уменьшил фреймворк
    0

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


    Micronaut очень похож на Spring не случайно, они прямо пишут:


    "Micronaut takes heavy inspiration from Spring, and in fact, the core developers of Micronaut are former SpringSource/Pivotal engineers now working for OCI"

    Но если уж говорить про Micronaut, нужно упомянуть его killer feature — вся инъекция зависимостей там выполняется в compile time, использя annotation processor.


    Unlike Spring which relies exclusively on runtime reflection and proxies, Micronaut, on the other hand, uses compile time data to implement dependency injection.

    Что и хорошо, и плохо. Хорошо — время, потраченное в рантайме, например, при запуске, неплохо экономится (хотя еще надо замерить — насколько хорошо). Плохо — это же время тратится в compile time, т.е. чуда не произойдет, плюс все сложности работы с annotation processor, плюс совсем уж невероятный уровень магии.

  • Представляем Spring Data JDBC
    0

    Немного промахнулся, см. ниже — есть базовый класс репозитория PagingAndSortingRepository

  • Представляем Spring Data JDBC
    0

    del

  • Представляем Spring Data JDBC
    0

    Да, PagingAndSortingRepository (это не шутка, если что).

  • Представляем Spring Data JDBC
    0

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


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


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

  • Представляем Spring Data JDBC
    0

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

  • Представляем Spring Data JDBC
    0

    Да, это верно, хотя актуально и для JPA, если не брать в расчет Criteria / Metamodel API. Вообще, задача проверки статической корректности работы с базой крайне сложная, поэтому чаще всего ее делегируют в рантайм (тесты). Тот же JOOQ не сможет гарантировать что схема БД соответствует сгенерированным классам.

  • Представляем Spring Data JDBC
    0

    Я почти уверен, автоматическая генерация еще будет, просто не в этой версии.

  • Представляем Spring Data JDBC
    0
    Не мешает, но усложняет доступ к данным механизмами вроде кеширования, отслеживания изменений, сессионности, ленивой загрузки и т.п. В этом и суть нового модуля — надо все из Hibernate — берём Spring Data JPA. Не надо, но хочется Spring Data для реляционных баз — берём Spring Data JDBC.
  • Представляем Spring Data JDBC
    0
    Упрощения не в части API, это все остаётся таким же. Упрощение в том, что нет JPA и JPA провайдера, типа Hibernate.
  • Представляем Spring Data JDBC
    0
    Речь идёт не про «осилить» или нет, а просто о предоставлении очень простого механизма доступа к реляционным данным. По сути, Spring JDBC + SingleColumnRowMapper + базовое управление зависимостями (в виде aggregate roots из философии DDD) и все.

    Часто всей мощи Hibernate не нужно, например в каком-то микросервисе.
  • Представляем Spring Data JDBC
    0
    Статья от позавчера, «прикола» никакого нет — просто новый модуль в Spring Data для легковесного доступа к данным.

    Про генерацию запросов речь идёт о docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
  • Как писать на Spring в 2017
    +1

    Это поменялось в версии 2. Обновил код для Spring Boot 2.

  • Как писать на Spring в 2017
    0

    По умолчанию Spring Initializr не создает папок под View или контроллеры, он в принципе не навязывает никакую структуру.


    Нужные Imports в IDEA можно добавить самому — просто поставить курсор на подчеркнутый символ, нажать Alt+Enter и выбрать 'Import ...'.


    Ну и как план Б — исходный код этой статьи доступен на GitHub, вот например реализация IndexControllerhttps://github.com/alek-sys/spring-demo/blob/master/src/main/java/com/example/demo/IndexController.java

  • Знакомство с ConcourseCI
    0
    Он есть, только его не рекомендуется использовать иначе, как кэш. Т.е. надо всегда иметь в виду, что кэша может не быть — если джоб запущен на другом воркере и даже в рамках одного воркера.
  • Знакомство с ConcourseCI
    +1
    Киллер фич есть несколько. Одна — что Concourse CI «нативен» для билд-монитора, т.е. его легко вывести на большой экран чтобы видеть текущий статус системы. Для этого не нужны плагины, это круто выглядит и красиво анимировано Вторая — что Concourse всеми силами навязывает модель «повторяемого» билда, например передавать данные между джобами можно только через ресурсы (которые персистентные), а каждый таск работает в одноразовом контейнере. Это не уникально, конечно, можно так же сделать в Дженкинс, но тут все изначально и by design. Например мы недавно полностью переключились с одного инстанса Конкурса на другой просто сменив target. Билд завёлся сразу, без трогания воркеров или АТС. Опять же, так можно где угодно, но Конкурс к этому активно подталкивает.
  • Тестирование компонентов React
    +2
    Представьте себе простейший компонент, используемый для аутентификации, в котором есть поле для ввода имени пользователя и кнопка отправки данных. В поле вводят имя, нажимают на кнопку, это вызывает выполнение запроса fetch с введёнными данными. Запрос оказывается выполненным, имя передаётся в хранилище Redux и кэшируется в localStorage. В общем-то, всё это тоже не так уж и сложно.
    Теперь попытаемся отправить этот компонент на тестовый рендеринг. К сожалению, тест даже не запустится.

    Если этот компонент тестировать "одним куском" (и гордо "не используя shallow рендеринг") — тогда конечно, тест не запустится. Более того, без бэкенда он никогда работать не будет. Только вот отношения к юнит-тестам такой тест тоже не имеет.


    Но если разбить этот мега-компонент на составные части, то получится вполне разумная картинка (которую можно "нарисовать" через TDD):


    1. В поле вводим имя, нажимаем на кнопку — это вызывает метод сервиса signIn (мока, разумеется). Все, больше тест ничего не тестирует.
    2. В сервисе вызываем метод signIn, проверяем, что он вызывает fetch или мок http-клиента
    3. Еще в сервисе тестируем, что при успешном ответе от мока fetch или http-клиента — он вызывает нужный метод хранилища.
    4. В метода хранилища — смотрим что он вызывает кеширование...

    И т.д.


    А если для работы теста нужны reduxState, url, localStorage, fetch и т.п. — может стоит задуматься, а не слишком ли много ответственностей у тестируемого компонента?

  • Это Спарта
    +1

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


    Хочется заметить по поводу


    "В вашем подходе fail fast, fail cheap есть 2 недостатка: с одной стороны он дорогой, т.к. время тратится на разработку того, что можно было бы не делать, с другой стороны он способствует написанию плохого кода, появлению костылей и вообще ведёт к некачественному продукту".

    На это в современных lean практиках есть решения:


    • дороговизна эксперимента (а вообще если убрать свою терминологию то это и есть lean experiment) решатся за счет практик Lean UX Design и User Centric Design, т.е. любое решение начинается с проблемы пользователя и через "дешевый" прототип (банальный wireframe) валидируется на пользователях, до того как уходит в разработку
    • плохой код и костыли — TDD + CI + постоянный рефакторинг
  • Это Спарта
    0

    В современной практике продуктового дизайна "fail fast" называется Lead Product Development. Он неплохо описан в книге "The Lean Startup". Несмотря на название, там не только про стартапы и не только для стартаперов.

  • Мульти-арные функции в Java
    +5

    Функция apply тут не при чем, метод может называться как угодно. Любой интерфейс с единственным методов (SAM, single abstract method) может быть функциональным интерфейсом. И документация про это говорит: "Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted".

  • Мульти-арные функции в Java
    +2

    Я бы предложил пару вещей, которые можно сделать со статьей, чтобы она больше соответствовала формату:


    1. Оформлять блоки кода как блоки кода
    2. Пометить статью как "Tutorial", т.к. это базовые знания по Java и будут полезны начинающим
    3. Лично я бы убрал загадочные формулы с синусами и упоминание карринга, это совершенно нерелевантно
    4. Быть более снисходительным к документации, вещи вроде "И все бы хорошо, да худо только в том, что прийти к этому решению рациональным путем просто невозможно" не совсем отражают положение вещей. Мне кажется, любой, кто использует Java 8 больше чем пару дней знает про функциональные интерфейсы и они описаны в ссылке на документацию, которая приводится в статье — Function прямо говорит, что это Functional interface.
  • Наипростейший RESTful сервис на Kotlin и Spring boot
    0

    Пара полезных (надеюсь) вещей по тестам:


    1. FixMethodOrder – не уверен, насколько полезно, я бы понял если случайный порядок, но намеренно по порядку?
    2. @AutoconfigureMockMvc и потом
      @Autowired
      lateinit var mockMvc: MockMvc
    3. MockMvc не нужен baseUrl, относительные пути прекрасно распознаются — и не надо переживать про виртуальный путь
    4. Для JSON есть отличный хелпер, который помогает работать с JSON используя JSONPath, а не сравнение со строкой. Например:
      mockMvc.perform(get("/"))
                  .andExpect(jsonPath("$.*.name", hasItems("iPhone 4s")))