1. 程式人生 > 其它 >4.@configuration註解(標明當前類是springboot的配置類)

4.@configuration註解(標明當前類是springboot的配置類)

1.spring註冊bean元件:使用的是配置進行註冊

2.springboot註冊bean元件:使用的是@configuration配置類的方式

1.配置類:(
   1.配置類中使用@Bean標註在方法上給容器註冊元件,預設是單例項的
   2.配置類本身也是元件
   3.外部無論對配置類中的元件的註冊方法(Person01()/dog01())獲取的都是之前註冊在容器中的單例項(即使通過Myconfiguration該元件直接呼叫方法)
   )
    //告訴springboot這是一個配置類==配置檔案
    @Configuration
    public class Myconfiguration {
        /**
         * 給容器中新增元件
         * 1.以方法名作為元件的id
         * 2.返回型別就是元件的型別
         * 3.返回值就是元件在容器中的例項
         */
        @Bean
        public Person person01(){
            return new Person("吳孟達",18);
        }
        @Bean("dog")-->可以指定bean的name
        public Dog dog01(){
            return new Dog("劉丹",18);
        }
    }

3.@configuration標籤詳解

1.springboot 2有個最新的變化,@Configuration標籤中添加了boolean proxyBeanMethods() default true;
    public @interface Configuration {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    
        boolean proxyBeanMethods() default true;---->springboot2添加了是否是代理物件方法的設定
    }

2.下面針對@Configuration中proxyBeanMethods的true/false來進行討論
    2.1 當設定proxyBeanMethods=false時,獲取到的物件不是代理物件
        @Configuration(proxyBeanMethods = false)
        public class Myconfiguration {
            @Bean
            public Person person01(){
                return new Person("吳孟達",18);
            }
            @Bean
            public Dog dog01(){
                return new Dog("劉丹",18);
            }
        }
        
    2.2 啟動類代理如下:
        @SpringBootApplication(scanBasePackages = "com.atguigu")
        public class MainApplication {
            public static void main(String[] args) {
                ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
                Myconfiguration myconfiguration = run.getBean("myconfiguration", Myconfiguration.class);----->
                Myconfiguration myconfiguration1 = run.getBean("myconfiguration", Myconfiguration.class);---->這兩個獲取到的配置類物件是同一物件,但不是代理物件
                System.out.println(myconfiguration);
                System.out.println(myconfiguration1);
                Person person01 = myconfiguration.person01();
                Person person02 = myconfiguration.person01();
                System.out.println(person01==person02);---->但當設定proxyBeanMethods=false時,每次獲取到的物件都是新物件
            }
        }
        輸出:
            com.atguigu.boot.configuration.Myconfiguration@78c7f9b3
            com.atguigu.boot.configuration.Myconfiguration@78c7f9b3
            false
           
   2.3 如果當proxyBeanMethods=true時,
       輸出:
            com.atguigu.boot.configuration.Myconfiguration$$EnhancerBySpringCGLIB$$56efdd6c@27e32fe4
            com.atguigu.boot.configuration.Myconfiguration$$EnhancerBySpringCGLIB$$56efdd6c@27e32fe4
            true                
        發現:每次獲取到的配置類物件是代理物件,並且每次執行配置類中的方法獲取到的元件都是同一組件
        
        

3.結論:
    1. 當proxyBeanMethods = false時,獲取到的配置類物件不是代理物件,每次執行獲取元件方法時,不會檢查容器中是否有該元件,每次都執行方法!
    2. 當proxyBeanMethods = true時,獲取到的物件是代理物件,每次執行獲取元件方法時,都會檢查容器中是否有該元件,如果有的話會直接獲取不會重新建立,沒有的話會直接建立!