Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a spring bean created with NEW really a singleton

I created a spring bean in a configuration class like this:

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

Whenever MyClass is autowired in another class that needs it injected, will it always create a new object by virtue of new in bean definition? Is a bean created this way a real singleton ?

like image 258
Hary Avatar asked Sep 10 '25 09:09

Hary


1 Answers

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
like image 79
Michał Ziober Avatar answered Sep 13 '25 06:09

Michał Ziober