【问题标题】:What is the actual usage of @configuration in spring?Spring中@configuration的实际用法是什么?
【发布时间】:2019-05-04 15:17:37
【问题描述】:

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

案例一:

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

【问题讨论】:

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


    【解决方案1】:

    当您从 AppConfig 类中删除 @Configuration 注释时,调用 item() 方法将是一个普通的 java 方法调用,您将获得 Item 的 新实例,它不会保留 单身

    为了证明这一点,首先在 Item 类中添加一个构造函数,如下所示:

    public class Item {
        ...
        public Item() {
            System.out.println("Item instance created")
        }
        ...
    }
    

    然后定义另一个将使用 Item 实例的 bean,如下所示:

    public class ItemConsumer {
    
        public ItemConsumer(Item item) {
            System.out.println("ItemConsumer created");
        }
    
    }
    

    并将其用作 AppConfig 类中的 bean,如下所示:

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

    如下更改ItemTest:

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

    现在,当您运行 ItemTest 类时,它会生成以下输出:

    Item instance created
    Item instance created
    ItemConsumer created
    

    所以 Item 类实例化了两次,这意味着它不是 singleton

    现在再次使用 @Configuration 注解来注解 AppConfig 类并运行 ItemTest 类。这次的输出如下:

    Item instance created
    ItemConsumer created
    

    【讨论】:

      【解决方案2】:

      @Bean 精简模式

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

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

      Source - Spring Documentation.

      【讨论】:

        猜你喜欢
        • 2017-01-02
        • 1970-01-01
        • 1970-01-01
        • 2019-03-03
        • 2019-12-18
        • 2018-09-06
        • 1970-01-01
        • 2011-04-02
        • 2019-05-17
        相关资源
        最近更新 更多