У меня есть сценарий, в котором мне нужно инициализировать bean-компонент на основе конфигурации приложения во время запуска. Позже, из-за динамической конфигурации, выбранной на основе события, мне нужно обновить компонент.
Этот bean-компонент не может быть обновлен, а может быть заменен только новым экземпляром.
Инициализирует ли использование оператора new только локальный экземпляр или он изменит bean-компонент?
@Component
public class TestComp {
@Autowired
private BeanA beanA;
public void updateBean() {
beanA = new BeanA("new value");
}
}
Я направил компонент в другой класс и проверил его после того, как инициализировал его с помощью new. В нем отражался новый объект. Но мне нужно подтверждение от экспертов, если это так.




Похоже, вам нужен заводской вместо. Ниже приводится примерное представление о том, как это может выглядеть; ваши потребности могут отличаться.
@Component
public class BeanFactory {
private volatile BeanA beanAInstance;
public BeanA createBeanA(String value) {
if (null == beanAInstance) {
synchronized (this) {
if (null == beanAInstance) {
beanAInstance = new BeanA(value);
}
}
}
return beanAInstance;
}
public void refreshBeanA(String newValue) {
synchronized (this) {
beanAInstance = new BeanA(newValue);
}
}
}
Затем вы подключаете его, и в зависимости от конфигурации вы можете обновить и использовать новое значение. Имейте в виду, что это изменит ценность, которую вы получаете от этого bean-компонента.
I have a scenario where I need to initialize a bean based on application configuration during startup.
Все нормально. Одноэлементный прицел здесь - хороший выбор.
Later, due to dynamic configuration fetched based on an event, I have to update the bean.
Это проблема. Обновление bean-компонента в контексте - сложный процесс: вам нужно удалить существующее определение bean-компонента, добавить новое и обновить все bean-компоненты, которые так или иначе связаны с bean-компонентом (повторно инициализировать эти компоненты, обновить контекст). Технически это возможно, и это было упрощено @RefreshScope Spring Cloud.
Does using new operator initialize only the local instance or will it change the bean?
Это влияет только на поле этого класса. Никто не знает об изменении. ApplicationContext#getBean по-прежнему вернет старый объект, и все компоненты будут (или уже были) инициализированы старым экземпляром.
I referred the bean in another class and checked after I initialized it with new. It reflected the new object.
Это не может быть правдой. Вероятно, это относится к полю TestComp#beanA, а не к собственному полю BeanA.
Предлагаемое мной решение - для определения настраиваемой области действия bean-компонента, основанное на событиях, которые вы получаете. Он будет обновлять компонент и контекст.
Это может быть очень сложно. В простейшем случае, предполагая, что вам нужен Spring для внедрения зависимостей для каждого BeanA, вам нужно будет использовать this вместо new:
beanA = context.getBean(BeanA.class)после того, какcontextстанет автоматически связанной переменной экземпляра типа ApplicationContext. И вам нужно будет сделать BeanA bean-компонентом с областью видимости прототипа, чтобы вы получали новый BeanA каждый раз, когда вызываете этот метод getBean ().