Reputation: 564
I just wanted to know why the below program is working even if I dont use @Configuration annotation on AppConfig class. Can you please let me know how it is working ?
Case 1:
AppConfig.java(with @Configuration)
@Configuration
public class AppConfig {
@Bean
public Item item(){
Item item = new Item();
item.setItemNo(46789);
item.setItemName("chair");
item.setItemType("ART");
item.setItemSize("A4");
return item;
}
}
Item.java
public class Item {
int itemNo;
String itemName;
String itemType;
String itemSize;
public int getItemNo() {
return itemNo;
}
public void setItemNo(int itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemType() {
return itemType;
}
public void setItemType(String itemType) {
this.itemType = itemType;
}
public String getItemSize() {
return itemSize;
}
public void setItemSize(String itemSize) {
this.itemSize = itemSize;
}
}
ItemTest.java
public class ItemTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(AppConfig.class);
Item item = ct.getBean(Item.class);
System.out.println(item.getItemNo());
}
}
Case 2 :
AppConfig.java ( without @Configuration)
public class AppConfig {
@Bean
public Item item(){
Item item = new Item();
item.setItemNo(46789);
item.setItemName("chair");
item.setItemType("ART");
item.setItemSize("A4");
return item;
}
}
Upvotes: 2
Views: 247
Reputation: 764
When you remove the @Configuration annotation from AppConfig class, calling item() method will be a plain java method call and you will get a new instance of Item and it won’t remain singleton.
To prove this point, first add a constructor to Item class as following:
public class Item {
...
public Item() {
System.out.println("Item instance created")
}
...
}
then define another bean that will be using Item instance as following:
public class ItemConsumer {
public ItemConsumer(Item item) {
System.out.println("ItemConsumer created");
}
}
and use it as bean in AppConfig class as following:
public class AppConfig {
@Bean
public Item item(){
Item item = new Item();
item.setItemNo(46789);
item.setItemName("chair");
item.setItemType("ART");
item.setItemSize("A4");
return item;
}
@Bean
public ItemConsumer itemConsumer() {
return new ItemConsumer(item());
}
}
change ItemTest as below:
public class ItemTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(AppConfig.class);
Item item = ct.getBean(Item.class);
ItemConsumer itemConsumer = ct.getBean(ItemConsumer.class);
}
}
Now when you run the ItemTest class, it generates following output:
Item instance created
Item instance created
ItemConsumer created
So Item class instantiated twice that means it is not singleton.
now annotate AppConfig class with @Configuration annotation again and run the ItemTest class. This time output will be like below:
Item instance created
ItemConsumer created
Upvotes: 3
Reputation: 2593
@Bean methods may also be declared within classes that are not annotated with @Configuration. For example, bean methods may be declared in a @Component class or even in a plain old class. In such cases, a @Bean method will get processed in a so-called 'lite' mode.
Bean methods in lite mode will be treated as plain factory methods by the container (similar to factory-method declarations in XML), with scoping and lifecycle callbacks properly applied. The containing class remains unmodified in this case, and there are no unusual constraints for the containing class or the factory methods.
Source - Spring Documentation.
Upvotes: 2