用NEW创建的春豆真的是单身吗

时间:2019-01-09 21:20:41

标签: spring spring-bean spring-ioc

我在这样的配置类中创建了一个spring bean:

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

每当MyClass被自动装配到需要注入的另一个类中时,是否总是通过bean定义中的new来创建一个新对象? 这样创建的bean是真正的单例吗?

2 个答案:

答案 0 :(得分:0)

Spring guarantees that whatever you do in the method annotated with Bean annotation it will be done only once. Internal Spring factories will take care about that.

Of course it depends from scope but by default scope is singleton. See docs:

  1. Scopes
  2. Bean
  3. Is spring default scope singleton or not?

Small example which should help you to understand how it works:

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;
    }
}

prints:

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

When you define bean with scope protoype

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

App prints:

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

答案 1 :(得分:0)

In your example, yes.

What will happen practically is that when Spring starts up, it will call the getMyClass() method which will new up an instance of the object. Spring will then retain that single instance and inject it into all other beans that require an instance of MyClass.

It will work this way since you've not declared a scope on the bean -- the default is singleton as indicated by the other answer.

相关问题