In this post under Spring Core, I will explain with example how to change scopes of Spring beans annotated with “@Bean” annotation.
By default the “@Bean” annotated beans have singleton scope.
Which means that whenever a dependee bean asks for a reference to dependent bean and the dependent bean scope is “singleton” then Spring makes sure that there will always be only one instance of the
dependent bean (not more than one) and the same bean reference is returned to the dependee bean.
We can change this default behavior as shown in the below example.
For our example I will declare three beans as shown below
Beans
package package11;
public class Bean1 {
private Bean3 bean3;
public Bean1(Bean3 bean3) {
this.bean3 = bean3;
}
@Override
public String toString() {
return "Hello its Bean1 and its dependent Bean3 with id: " + bean3.toString();
}
}
package package11;
public class Bean2 {
private Bean3 bean3;
public Bean2(Bean3 bean3) {
this.bean3 = bean3;
}
@Override
public String toString() {
return "Hello its Bean2 and its dependent Bean3 with id: " + bean3.toString();
}
}
package package11;
public class Bean3 {
private static int counter = 0;
private int id;
public Bean3() {
Bean3.counter = Bean3.counter + 1;
this.id = Bean3.counter;
}
@Override
public String toString() {
return String.valueOf(this.id);
}
}
As you can see from the above code snippet that “Bean1” and “Bean2” depends on “Bean3”.
“Bean3” is injected to “Bean1” and “Bean2” using constructor injection.
In the “Bean3” code we have a static field named “counter” which will keep track of how many instances of “Bean3” is created and also assigns a unique id to each instance of “Bean3” class.
Now below is the main method code
Main class
1 package package11;
2
3 import org.springframework.context.ApplicationContext;
4 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.context.annotation.Scope;
8
9 @Configuration
10 public class Example11 {
11 @Bean
12 @Scope("prototype")
13 public Bean3 bean3() {
14 return new Bean3();
15 }
16
17 @Bean
18 public Bean2 bean2() {
19 return new Bean2(bean3());
20 }
21
22 @Bean
23 public Bean1 bean1() {
24 return new Bean1(bean3());
25 }
26
27 public static void main(String[] args) {
28 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example11.class);
29 Bean1 bean1 = applicationContext.getBean("bean1", Bean1.class);
30 System.out.println(bean1);
31 Bean2 bean2 = applicationContext.getBean("bean2", Bean2.class);
32 System.out.println(bean2);
33 }
34 }
In the above main class, from line 11 to 15, we add definition of “Bean3” and marked its scope to “prototype” using “@Scope” annotation.
The “prototype” scope means we will get new instance of “Bean3” whenever we call “bean3()” method.
In this way we can change the scope of the beans.
Below is the output for your reference
Output
Hello its Bean1 and its dependent Bean3 with id: 2
Hello its Bean2 and its dependent Bean3 with id: 1