Если компонент создается с использованием тега @Bean, мы можем создать два компонента. Как это одноэлементно для каждого applicatonContext

#java #spring #singleton

#java #весна #одноэлементный

Вопрос:

Здесь, если класс StudentInfo является прототипом, он создаст две отдельные ссылки, что нормально, но в случае одноэлементного компонента он также создает два компонента с именами student и student1, тогда это нарушает правило одноэлементности для контекста приложения. Если я чего-то не хватает, пожалуйста, дайте мне знать. Как мы можем создать одноэлементный компонент для контекста приложения в этом случае?

 @Configuration
@ComponentScan("com.spring")
public class AnnotationConfiguration {
    @Bean(name="student")
    public StudentInfo info() {
        return new StudentInfo("girraj","gupta");
    }
    @Bean(name="student1")
    public StudentInfo info1() {
        return new StudentInfo("girraj1","gupta1");
    }
}
 

Комментарии:

1. я не думаю, что в spring есть правило, согласно которому контекст приложения должен содержать одноэлементные компоненты

2. Если два компонента равны, это не означает одноэлементность

3. Да, правильно, но если мы хотим создать одноэлементный компонент и хотим ограничить, чтобы ни одному телу не разрешалось создавать его снова. как мы можем сделать это на основе аннотаций?

4. Тогда почему бы не объявить этот класс с помощью @Component и оставить это spring

Ответ №1:

Из Spring Docs

Когда компонент является одноэлементным, будет управляться только один общий экземпляр компонента, и все запросы на компоненты с идентификатором или идентификаторами, соответствующими этому определению компонента, приведут к тому, что один конкретный экземпляр компонента будет возвращен контейнером Spring.

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

Ответ №2:

Внедрение зависимостей — это двухэтапный процесс, который состоит из:

  • Определите компонент.
  • Введите компонент.

Когда вы объявляете определение компонента с аннотацией @Bean, вы объявляете рецепт для создания реальных экземпляров класса, определенного этим определением компонента. Это означает, что вы можете создать много экземпляров объекта из одного рецепта.

Когда JavaConfig встречает такой метод, он выполняет этот метод и регистрирует возвращаемое значение как компонент в контейнере Spring IoC.

В вашем примере вы объявили два определения компонента. Таким образом, оба компонента регистрируются как отдельный компонент в контейнере Spring IoC. Для одноэлементного компонента Spring перехватит любые вызовы к нему и гарантирует, что компонент, созданный этим методом, будет возвращен, а не разрешен его повторный вызов.

Пожалуйста, обратитесь к областям Bean и базовой конфигурации bean

Ответ №3:

Здесь, если класс StudentInfo является прототипом…

Не имеет значения, является ли StudentInfo это прототипом. На самом деле вы делаете то, что вы создаете экземпляр a StudentInfo с new помощью оператора, например:

 return new StudentInfo("girraj1","gupta1");
 

Фактическое определение компонента — это созданный вами фабричный метод, и у вас есть два из них, так что два компонента.

Так что — и наоборот — когда вы вводите компонент, который на самом деле является экземпляром StudentInfo , вы вводите не StudentInfo компонент, а компонент с именем student или student1, например:

 @Qualifier("student1")
@Autowired
private StudentInfo studentInfo;
 

И student1, student они оба могут быть одиночными.

Комментарии:

1. ДА. вы правы, но можем ли мы ограничить контекст приложения созданием только одного одноэлементного компонента для каждого контекста приложения, означает, что если кто-то попытается создать объект снова, он не должен разрешать, или он вернет вам ту же ссылку.