Повторно инициализировать Spring @Autowire bean

У меня есть сценарий, в котором мне нужно инициализировать bean-компонент на основе конфигурации приложения во время запуска. Позже, из-за динамической конфигурации, выбранной на основе события, мне нужно обновить компонент.

Этот bean-компонент не может быть обновлен, а может быть заменен только новым экземпляром.

Инициализирует ли использование оператора new только локальный экземпляр или он изменит bean-компонент?

@Component
public class TestComp {

  @Autowired
  private BeanA beanA;

  public void updateBean() {
    beanA = new BeanA("new value");
  }

}

Я направил компонент в другой класс и проверил его после того, как инициализировал его с помощью new. В нем отражался новый объект. Но мне нужно подтверждение от экспертов, если это так.

Это может быть очень сложно. В простейшем случае, предполагая, что вам нужен Spring для внедрения зависимостей для каждого BeanA, вам нужно будет использовать this вместо new: beanA = context.getBean(BeanA.class) после того, как context станет автоматически связанной переменной экземпляра типа ApplicationContext. И вам нужно будет сделать BeanA bean-компонентом с областью видимости прототипа, чтобы вы получали новый BeanA каждый раз, когда вызываете этот метод getBean ().

moilejter 05.10.2018 00:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
2 943
2

Ответы 2

Похоже, вам нужен заводской вместо. Ниже приводится примерное представление о том, как это может выглядеть; ваши потребности могут отличаться.

@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-компонента, основанное на событиях, которые вы получаете. Он будет обновлять компонент и контекст.

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