Потокобезопасность и утечка ресурсов в классе @Configuration

Мне пришлось создать singleton bean-компонент вручную в классе @Configuration, чтобы поделиться им, не раскрывая его в контексте (который запускает условные выражения/автоконфигурации). Мне было указано на осознание определенных рисков, чтобы справиться с этим самостоятельно:

  • Потокобезопасность: объект Datasource не является апатридом
  • Утечка ресурсов: объект источника данных явно не закрыт контекстом

Код следующий:

    private DataSource nonExposedDatasource;

    public DataSource nonExposedSingletonDataSource() {
        if (Objects.isNull(this.nonExposedDatasource)) {
            this.nonExposedDatasource = this.myPrivateDatasourceProperties.initializeDataSourceBuilder().build();
        }
        return this.nonExposedDatasource;
    }

    @Bean
    public TaskConfigurer taskConfigurer() {
        return new DefaultTaskConfigurer(this.nonExposedSingletonDataSource());
    }

    @Bean
    public BatchConfigurer batchConfigurer() {
        return new DefaultBatchConfigurer(this.nonExposedSingletonDataSource());
    }

У меня вопрос: действительно ли у меня есть риск не заметить это? Разве Спринг недостаточно умен?

  • Что касается безопасности потоков, я понимаю, что мой код должен быть проблематично, должно произойти 2 потока, обрабатывающих @Конфигурация. Spring так делает??

  • Что касается утечки ресурсов, если бы мой источник данных был @Bean, управляемым Spring, как работает большинство приложений, не было бы это потенциальной ловушкой, если приложение все равно закроется?

Как бы вы сделали этот код безопаснее?

DataSource это не закрываемый, поэтому я не уверен, что вы имеете в виду под «незакрытым явно». В документах DataSource также не обсуждаются гарантии потокобезопасности конкретного источника или его соединений — вам придется уточнить у разработчика драйвера, какие гарантии предоставляются. Кроме того, учтите, что транзакции Spring всегда привязаны к потоку (атрибуты — это ThreadLocal), поэтому я полностью ожидаю, что он также будет связывать потоки с объектами Connection.
M. Prokhorov 22.03.2019 13:11

Это относится к одному из комментариев здесь: stackoverflow.com/questions/55248571/… «При выполнении подобных действий убедитесь, что вы также регистрируете обратный вызов для закрытия соединений, когда приложение остановлено. В противном случае вы можете оставить открытые (tcp) соединения, обычно это будет обрабатываться из-за к тому, что это фасоль». (но это не @Bean)

Whimusical 22.03.2019 15:03

Я даже не знаю, как можно было бы закрывать соединения, открытые из источника данных, если бы вы не открывали его в первую очередь: интерфейс не дает возможности сделать это. Хотя, учитывая, что в связанном вопросе вы говорите, что это источник HikariCP, вы можете зарегистрировать отключение, если хотите. Что касается безопасности данных, я ожидаю, что HikariDS будет потокобезопасным, но что не является потокобезопасным, так это доступ к его экземплярам. Вам нужно как-то синхронизировать это самостоятельно.

M. Prokhorov 28.03.2019 14:21

Итак, если я правильно понимаю, мне не следует беспокоиться об утечке соединения, но я должен беспокоиться о синхронизации, значит ли это, что Spring может загружать @Configuration через разные потоки?

Whimusical 02.04.2019 19:29

Здесь следует отметить, что единственным использованием моего объекта источника данных является Spring Framework через DefaultTaskConfigurer и DefaultBatchConfigurer (как показано в коде), поэтому я предполагаю, что вопрос заключается в том, требует ли факт отсутствия управления как @Bean какой-либо специальной обработки для синхронизации

Whimusical 02.04.2019 19:46

если я правильно понимаю, вы можете объявить свои bean-компоненты как lazy-init, и в этот момент Spring не будет заботиться о создании ваших bean-компонентов, если от них что-то не зависит. Эта зависимость может быть реализована вашим кодом, вызывающим BeanFactory для получения экземпляра из разных потоков. В вашей настройке, я думаю, конфигурация будет однопоточной.

M. Prokhorov 03.04.2019 16:02

Поскольку это уже довольно длинная дискуссия, могу ли я спросить, почему вы делаете все это в первую очередь (т.е. почему ваш источник данных не является @Bean)? Если вы не хотите, чтобы bean-компонент выставлялся наружу, тогда Spring тебя уже прикрыли, не нужно проходить через всю эту чепуху. Также обратите внимание, что если ваш bean-компонент вообще является Closeable, то Spring также вас прикрыл.

M. Prokhorov 03.04.2019 16:04

Я уже видел эту документацию, но она должна быть старой или что-то в этом роде, так как у меня она не работала. stackoverflow.com/questions/55063611/…

Whimusical 03.04.2019 17:40

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

M. Prokhorov 03.04.2019 17:50

Как раз наоборот. Я хотел, чтобы Spring управлял компонентом, но не из @Configuration, чтобы мои автоконфигураторы не запускались.

Whimusical 04.04.2019 12:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
10
52
0

Другие вопросы по теме