Можно ли повторно инициализировать Spring Bean во время выполнения?
My Bean использует статические настройки, которые в некоторых случаях меняются, и затем мне нужно повторно инициализировать bean-компонент.
Мой компонент - это функция внутри класса конфигурации. Работает ли функция обновления для этой системы?
Да, даже если вы создаете bean-компонент из метода, он по-прежнему является объектом внутри контекста Spring и к нему можно получить доступ, как к любому другому bean-компоненту.




У вас есть три варианта обновления singleton bean в контексте Spring, вы можете выбрать тот, который подходит для вашего варианта использования:
Метод перезагрузки в Bean
Создайте в компоненте метод, который обновит / перезагрузит его свойства. В зависимости от вашего триггера получите доступ к bean-компоненту из контекста Spring, а затем вызовите метод reload для обновления свойств bean-компонента (начиная с singleton), он также будет обновлен в контексте Spring и везде, где он автоматически подключается / вводится.
Удалить и зарегистрировать компонент в реестре
Вы можете использовать DefaultSingletonBeanRegistry для удаления и повторной регистрации вашего bean-компонента. Единственный недостаток в том, что он не будет обновлять / перезагружать старый экземпляр уже автоматически подключенного / внедренного bean-компонента в потребительских классах.
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();
registry.destroySingleton({yourbean}) //destroys the bean object
registry.registerSingleton({yourbeanname}, {newbeanobject}) //add to singleton beans cache
@RefreshScope
Полезно для обновления свойств значения bean-компонента из изменений конфигурации. Но у него очень ограниченная и конкретная цель. Ресурс, чтобы узнать об этом подробнее.
Так сложно перезагрузить свойства.
Почему не только bean = applicationContext.getBean(Bean.class)?
Потому что он просто доставит вам уже загруженный bean-компонент из контекста, а не обновит / перезагрузит его. Я не понимаю, когда вы говорите, это так сложно?
Создайте общедоступный метод инициализации для перезагрузки всех свойств, используйте его в конструкторе и вызове перезагрузки.
В моем случае новый компонент возвращается на applicationContext.getBean(Bean.class). Это из-за @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE).
Да, этот вопрос не относится к не-singleton beans. Объем прототипа зависит от использования, поэтому ваш bean-компонент создается новым для каждого требования, поэтому вопрос о перезагрузке не возникает.
Я попытался получить DefaultSingletonBeanRegistry из ApplicationContext DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();, объект context относится к типу ApplicationContext, но я получил следующую ошибку The method getBeanFactory() is undefined for the type ApplicationContext И также предлагает помощь по change to getParentBeanFactory(..).
Вы можете получить доступ к компоненту прямо из контекста, а затем просто создать метод
updateвнутри класса компонента, который вы можете вызвать на основе своего триггера для обновления компонента.