Является ли боб, созданный с помощью NEW, действительно синглтоном? - PullRequest
0 голосов
/ 10 января 2019

Я создал боб пружины в классе конфигурации, подобном этому:

@Bean
MyClass getMyClass() {
    MyClass mc = new MyClass()
    return mc;
}

Всякий раз, когда MyClass автоматически подключается к другому классу, который нуждается в его внедрении, будет ли он всегда создавать новый объект в силу new в определении бина? Боб, созданный таким образом, настоящий синглтон?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

В вашем примере да.

На практике произойдет то, что, когда Spring запустится, он вызовет метод getMyClass(), который запустит экземпляр объекта. Затем Spring сохранит этот единственный экземпляр и вставит его во все остальные bean-компоненты, для которых требуется экземпляр MyClass.

Это будет работать таким образом, поскольку вы не объявили область действия для bean-компонента - по умолчанию используется singleton, как указано в другом ответе.

0 голосов
/ 10 января 2019

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

Конечно, это зависит от scope, но по умолчанию область действия singleton. Смотрите документы:

  1. Прицелы
  2. Bean
  3. Является ли область действия пружины одноэлементной или нет?

Небольшой пример, который должен помочь вам понять, как это работает:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
import java.util.Random;

@Configuration
public class SpringApp {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringApp.class);

        System.out.println(ctx.getBean(MyClass.class));
        System.out.println(ctx.getBean(MyClass.class));
        System.out.println(ctx.getBean(MyClass.class));
        System.out.println(ctx.getBean(MyClass.class));
    }

    @Bean
    public MyClass getMyClass() {
        System.out.println("Create instance of MyClass at " + LocalDateTime.now());
        MyClass myClass = new MyClass();

        return myClass;
    }
}

class MyClass {

    private int value = new Random().nextInt();

    @Override
    public String toString() {
        return super.toString() + " with values = " + value;
    }
}

печать:

Create instance of MyClass at 2019-01-09T22:54:37.025
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221

Когда вы определяете бин с областью действия protoype

@Scope("prototype")
@Bean
public MyClass getMyClass()

Приложение печатает:

Create instance of MyClass at 2019-01-09T22:57:12.585
com.celoxity.spring.MyClass@282003e1 with values = -677868705
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@7fad8c79 with values = 18948996
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@71a794e5 with values = 358780038
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@76329302 with values = 868257220
...