天天看點

spring注解 Configuration、Bean、Scope、Lazy注解

@Configuration注解:

        标注在類上,告訴spring這是一個配置類,配置類等同于配置檔案,在使用時,将以往的ClassPathXmlApplicationContext("spring的xml檔案全路徑名"),用AnnotationConfigApplicationContext(配置類.class)代替,這樣就可以通過配置類來建立容器。

@Configuration
public class MyConfig {
    static {
        System.out.println("配置類加載...");
    }
}

public class AnnotationTest {
    @Test
    public void testConfig(){
        System.out.println("======測試類開始======");
        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println("======IOC容器建立完成======");

    }
}
           

        測試輸出:

spring注解 Configuration、Bean、Scope、Lazy注解

@Bean注解:

        給容器中注冊一個bean,類型為傳回值的類型,bean的id預設為其方法名,也可以在Bean注解中添加參數,對其進行自定義命名。

//配置類
@Configuration
public class MyConfig {

    static {
        System.out.println("配置類加載...");
    }

    @Bean("person")   //預設為方法名小寫,傳回的bean的id
    public Person getPerson(){
        System.out.println("向容器中添加person");
        return new Person("張三",20);
    }
}

//測試類
public class AnnotationTest {

    @Test
    public void testComponentScan(){
        System.out.println("======測試類開始======");
        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println("======IOC容器建立完成======");
        String[] definitionNames = ctx.getBeanDefinitionNames();
        for (String name : definitionNames){
            System.out.println("bean 的定義名是:" + name);
        }
    }
}
           

        測試輸出:

spring注解 Configuration、Bean、Scope、Lazy注解

@Scope和@Lazy注解:

        scope注解用于設定元件的作用于,在預設值的情況下,預設建立單執行個體對象,有4個可選值,一般情況下,選擇

prototype和singleton兩種。單執行個體時,IOC容器 啟動時 就會調用方法建立對象,并将其放入IOC容器中, 以後每次擷取,都是從IOC容器中拿取該對象;多執行個體時,IOC容器啟動時不會調用方法建立對象, 而是在每次擷取對象時,調用方法建立對象。      

        懶加載可以看做scope單執行個體的一種特殊情況,IOC容器 啟動時 不建立對象第一次擷取對象時,建立對象并加入到容器中 以後每次擷取,都是從IOC容器中拿取該對象。

//配置類
@Configuration
public class MyConfig2 {

    /**
     * SCOPE_SINGLETON = "singleton":   單執行個體
     *      在單執行個體情況下:
     *          IOC容器 啟動時 就會調用方法建立對象,并将其放入IOC容器中,
     *          以後每次擷取,都是從IOC容器中拿取該對象
     * SCOPE_PROTOTYPE = "prototype":   多執行個體
     *      在多執行個體情況下:
     *          IOC容器啟動時不會調用方法建立對象,
     *          而是在每次擷取對象時,調用方法建立對象
     * @Lazy:   懶加載
     *      單執行個體bean,IOC容器 啟動時 不建立對象
     *      第一次擷取對象時,建立對象并加入到容器中
     *      以後每次擷取,都是從IOC容器中拿取該對象
     */
    //@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //也可以寫為:@Scope("prototype"),不加參數預設為單執行個體
    @Lazy
    @Bean("person")
    public Person getPerson(){
        System.out.println("向容器中添加person");
        return new Person("張三",23);
    }
}

//測試類
public class AnnotationTest {

    @Test
    public void testScope(){
        System.out.println("======測試類開始======");
        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig2.class);
        System.out.println("======IOC容器建立完成======");
        Person p1 = ctx.getBean(Person.class);
        Person p2 = (Person) ctx.getBean("person");
        System.out.println(p1==p2);
    }
}
           

     三種情況下的輸出:

spring注解 Configuration、Bean、Scope、Lazy注解
spring注解 Configuration、Bean、Scope、Lazy注解
spring注解 Configuration、Bean、Scope、Lazy注解

        通過輸出可以看到,預設時,在IOC容器建立完成之前就先建立好了Bean,而懶加載和多執行個體時,都是在使用到Bean的時候,才進行建立,懶加載建立的Bean是同一個對象,而多執行個體建立的Bean是兩個不同的對象