К основному контенту

Сообщения

IoC-контейнер изнутри

В этой статье предлагаю разобраться чем занимается IoC-контейнер и как это определяет его внутреннюю структуру. Исходить будем из задачи, которую решает контейнер: создать и скомпоновать объекты таким образом, чтобы все зависимости этих объектов были удовлетворены. Очевидно, что зависимости необходимо некоторым образом описать: объект, называемый так-то, скажем A, зависит от других объектов, например B и C. При этом контейнер ничего не знает о том, какой из объектов мы называем A, а какие — B и C. Это тоже необходимо описать. Контейнер оперирует только теми компонентами, которые он знает (часто их называют бинами). Для создания объекта контейнеру необходимо также знать к какому классу объектов он принадлежит и как долго его помнить. Самый простой способ предоставить все эти данные (с точки зрения устройства контейнера, конечно) — напрямую обратиться к регистрационному методу контейнера, передав ему в качестве параметра некоторый объект с метаданными. Второй вариант: промаркировать
Недавние сообщения

java.util.stream.Stream как результат выборки из базы данных

В этом посте предлагаю свои мысли о методе stream() интерфейса Query . Этот метод появился в Hibernate не так давно, в версии 5.2, в рамках поддержки новых возможностей Java 8. Что же за ним скрывается, какие особенности его использования и нужен ли он вам? Давайте разберемся. Сперва предлагаю задаться вопросом: почему бы не воспользоваться методом list() того же интерфейса и получать объект Stream уже из него? Так можно сделать, если результат вашей выборки относительно небольшой. Если же вам, например, надо экспортировать многомиллионную таблицу этот вариант плох в плане использования оперативной памяти. До этого вы скорее всего пользовались методом scroll() в подобных случаях, но он возвращает ScrollableResults , который не является коллекцией и не содержит метод, возвращающий Stream . Теперь вы можете воспользоваться новым методом, чтобы вычитывать данные по мере необходимости. Что же представляет собой метод stream() внутри? Это альтернативная реализация метода scroll()

Может ли TreeSet содержать дубликаты?

Не спешите давать ответ, а лучше запустите код, приведенный ниже. Возможно вы подумаете, что это надуманный пример, но это лишь немного упрощенная версия того кода, с которым мне пришлось столкнуться на практике. Для начала о проблеме, которую был призван решить этот код. В списке объектов надо было оставить объекты с различными именами, причем неважно какой объект из всего набора с таким же именем останется. Сразу же уточню, что на практике в проекте используется Java 7 и класс объектов, добавляемых в TreeSet, не вложен в какой-либо другой, а приведенный здесь вариант использован для краткости. Может возникнуть вопрос почему выбрано именно такое решение. Давайте разберемся, чтобы не повторять ошибку. Первое, что приходит в голову, когда из списка надо удалить дубликаты, - использовать Set. В данной ситуации HashSet не подходит, потому что он использует equals метод для сравнения и отсеивания дубликатов. Но наш программист не сдаётся и вспоминает, что есть же еще TreeSet, в докум

Одно приложение, несколько баз данных

Рецепт от Spring Boot Некоторое время назад мне довелось писать агрегатор информации, разбросанной по нескольким базам данных с разными схемами. Для реализации был выбран Spring Boot. Ну, потому что модный и судя по примерам существенно упрощает жизнь за счет умной автоконфигурации. В этой статье я опишу, что же необходимо сконфигурировать и как, в случае, если вы отошли от стандартного сценария. Первым делом, необходимо прописать настройки доступа к каждой из баз. Например, вот так: Следующим шагом создадим отдельный класс конфигурации (для удобства), в котором определим dataSources: Обратите внимание, как просто получить настройки с помощью @ConfigurationProperties. Правда, пришлось ввести вспомогательный класс BaseDataSourceProperties — наследник DataSourceProperties, в котором область видимости метода getDriverClassName расширена до public. И осталось совсем немного — сконфигурировать JPA-репозитории. Насчет немного я, конечно, пошутил :) В этой части предстоит больше

REST сервис как Linux служба

В этом посте я собираюсь рассказать как превратить REST сервис, написанный на Java, в Linux службу, устанавливаемую пакетным менеджером. Итак, первым делом забудьте о тяжеловесных серверах приложений вроде JBoss AS или Oracle WebLogic. Выбираем какой-нибудь легковесный встраиваемый сервер. Это может быть Jetty , Grizzly или даже Simple . Логи предпочтительнее писать в syslog. И Log4j и Logback позволяют это сделать. Для написания сервиса я выбираю Dropwizard (готовая связка Jetty + Jersey + Logback + Metrics), но это совсем необязательно. При сборке нужно положить зависимости в отдельную внешнюю папку или запаковать внутрь jar рядом c вашим кодом (maven-assembly-plugin или maven-shade-plugin в помощь). Для простоты демонстрации я выбрал второй вариант. Теперь всё готово для превращения. Для запуска службы будем использовать systemd - современную систему инициализации и менеджер служб для Linux. Нам понадобится простой shell скрипт и service файл. Выглядеть это будет примерно так:

Тестируем отправку почты. Wiser vs Dumbster

Тестируете ли вы отправку почты вашим приложением? Надеюсь, что да. Но делаете это вы, скорее всего, при помощи функциональных тестов. А разве можно иначе? Можно, и даже оправдано, если в вашем приложении много правил или они не совсем простые и очевидные. В этом случае вам понадобится много тестов. Если все они будут функциональные, вы рискуете заспамить свой почтовый ящик и временем обратной связи вряд ли останетесь довольны. Я бы предпочёл протестировать функциональными тестами основные сценарии, а различные граничные условия и исключения из правил проверять модульными тестами. Вот для этого и предназначены Wiser с Dumbster'ом. Начнём с того, что обе библиотеки легковесные, легко подключаются и просты в использовании. Итак, добавляем в pom.xml и пишем примерно вот такой тест или с использованием Dumbster такой Вам выбирать какую из этих библиотек использовать. Лично я отдал предпочтение Wiser, т.к. полученное сообщение — это стандартный javax.mail.internet.MimeMessage ,

JEEConf 2013

Этот пост посвящён конференции JEEConf, проходившей в Киеве 24-25 мая. Это мероприятие организовывается уже не первый год и с каждым разом собирает все больше и больше Java-разработчиков. В этот раз и докладов было больше и самих докладчиков, в т.ч. и зарубежных. Из тех докладов, на которых я побывал в первый день, хочется отметить доклад Олега Шелаева про Java-агенты и доклад Антона Кекса «Как вернуть Java былую славу?». Первый познакомил с интересными инструментами вроде Chronon и Byteman и породил интересные идеи применения агентов. А второй из выделенных мною докладов оставил особо яркие впечатления. Антон — отличный докладчик. Он с особым удовольствием поиздевался над трехбуквенными аббревиатурами из Ынтерпрайз мира и стилем разработки resume driven development. Конечно же, были рекомендации как нужно делать. Не все из них можно просто вот так взять и применить (все-таки работа в аутсорсе и распределённых командах накладывает определённые ограничения), но общее направление, к