Spring中@configuration的实际用法是什么?

时间:2018-12-03 10:31:59

标签: spring spring-mvc spring-boot spring-data

我只是想知道为什么即使我在AppConfig类上不使用@Configuration注释,下面的程序仍能正常工作。你能让我知道它是如何工作的吗?

情况1:

AppConfig.java(带有@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());

    }
}

案例2:

AppConfig.java(不带@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;
    }
}

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

@Bean Lite模式

  @pBean方法也可以在非   用@Configuration注释。例如,bean方法可能是   在@Component类中甚至在普通的旧类中声明。在这样的   在这种情况下,@ Bean方法将以所谓的“精简”模式进行处理。

     精简模式下的

Bean方法将被视为普通工厂方法   容器(类似于XML中的工厂方法声明),   作用域和生命周期回调已正确应用。包含类   在这种情况下仍保持不变,并且没有异常约束   包含类或工厂方法。

Source - Spring Documentation.