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时,获取到的对象是代理对象,每次执行获取组件方法时,都会检查容器中是否有该组件,如果有的话会直接获取不会重新创建,没有的话会直接创建!

 

posted @ 2022-05-11 21:27  努力的达子  阅读(254)  评论(0编辑  收藏  举报