Предположим, у меня есть пара весенних бобов:
<beans>
<bean name = "A" ... />
<bean name = "B" ... />
</beans>
«B» предоставляет удаленную службу, для которой не требуется «A». Предположим, что загрузка «А» требует значительного времени. Это означает, что во время цикла перезапуска приложение вешает удаленный клиент, который фактически может подключиться к серверу, но ожидает ответа, пока контейнер Spring полностью не инициализируется.
Я бы хотел иметь возможность, чтобы удаленная служба «B» отвечала немедленно, даже если (в зависимости от состояния приложения) она может возвращать только NOT_READY или что-то в этом роде. Однако контейнер заставляет ждать, пока все его bean-компоненты не будут инициализированы, даже если вы укажете bean-компоненты как lazy-init и независимо от порядка загрузки.
Я подозреваю, что наличие "B" сразу же означало бы, что Spring должна будет предоставить частично инициализированный контейнер, что звучит плохо. Однако я был бы признателен за любую информацию о порядке инициализации и о том, нашли ли вы какие-либо разумные обходные пути.




Я не понимаю, почему «A загружается очень долго», но, возможно, вы могли бы выполнить ленивую инициализацию, рефакторинг A. Не используйте InitializingBean и не обрабатывайте ApplicationEvent. Просто инициализируйте первый запрос, который нужно обработать. Это замедлит первый запрос!
Другая возможность - переместить инициализацию в отдельный поток, созданный компонентом, обрабатывающим ApplicationEvent. Поток вызывает метод инициализации компонента асинхронно. Будьте осторожны при обработке запросов к неинициализированному компоненту!
Пока A загружается, вызывающие абоненты зависают до истечения времени ожидания, так как они могут открыть сокет, но дождаться завершения инициализации сервера. Хотите вручную загрузить службу, чтобы немедленно ответить. Я надеялся избежать беспорядочной альтернативы инициализации в фоновом потоке, запускаемом вручную.
Не обращайтесь напрямую к компоненту «А». Вместо этого обратитесь к компоненту, который является FACTORY для компонента «A»; таким образом, компонент Factory может быть создан без обращения к инициализации для создания экземпляра «A». Конечно, вам нужно будет реорганизовать свои классы, которые ссылаются на «А», чтобы сначала получить «А».
Или вы можете создать bean-компонент «AA», который является контейнером для bean-компонента «A», который имеет состояние инициализации и который предоставляет интерфейс bean-компонента «A»; при вызове он устанавливает свое состояние инициализации как неинициализированное и начинает инициализацию bean-компонента «A» в некотором потоке; вызовы любых методов интерфейса «A» на «AA» могут затем либо блокировать, либо возвращать ответ «не готов» до тех пор, пока не завершится инициализация «A» в «AA».
Все это как бы зависит от того, что по вашему определению «требуется немало времени для загрузки». Почему для загрузки требуется немало времени? Происходит ли какая-то особенно сложная инициализация внутри A? Или A настолько чудовищно огромен, что подавляет JVM?
Не могли бы вы уточнить, почему Bean A требует «немалого времени» для создания самого себя? Возможный ответ - рефакторинг Bean A так, чтобы неотъемлемое время стало функцией, вызываемой вне процесса создания экземпляра?