• @Configuration详解


    @Configuration详解,功能:将想要的组件添加到容器中

    首先,需要准备三个文件:

    ps:完整代码片在文章最后,建议看完教程。
    1.主程序类:
    在这里插入图片描述
    2.宠物类
    在这里插入图片描述

    3.用户类
    在这里插入图片描述

    对比以前原生spring添加组件的区别
    如果是以前的原生spring,想要将组件添加到容器中
    1.需要在resources目录下创建一个xml配置文件
    2.创建bean标签
    在这里插入图片描述

    现在的Spring Boot已经不需要向以前一样了,有一个注解@Configuration(翻译:配置)可以供使用
    1.创建一个类。
    2.使用注解@Configuration,告诉Spring Boot这是一个配置类。
    在这里插入图片描述

    这个时候在类里边不能写bean标签了需要使用@bean注解,想要构建出user和pet对象需要自己将它创造出来。
    @bean:给容器中添加组件,以方法名作为组件的id。返回类型为组件类型,返回的值,就是组件在容器中的实例
    在这里插入图片描述

    怎么验证创建这俩组件成功了呢?
    首先来到主程序
    在这里插入图片描述

    运行主程序就能查到刚刚创建好的组件:
    在这里插入图片描述

    当然,如果不喜欢这个原本的名字是可以换的
    在这里插入图片描述

    给容器中注册的组件默认是单实例的。
    就是说无论我们从容器中获取多少次,它们都是一样的
    在这里插入图片描述

    可以看到,返回的都是true,也就说明都是相等的 。
    所以:配置类里面使用@Bean标注在方法上给容器注册组件,默认是单实例的。
    同时还有一点,被@Configuration标注的类本身也是一个组件
    可以从容器中取这个类来验证一下。
    在这里插入图片描述

    同时,在Spring Boot 5.2之后的@Configuration注解多了一个属性proxyBeanMethods,默认为true(翻译:代理bean的方法)
    在这里插入图片描述

    顾名思义,既然默认为true了,也就是默认代理。
    代理就会保持组件的单实例。
    也就是说,虽然写的Myconfig是在容器中注册组件用的,但是在注册组件之前会在容器中查找有没有该组件。如果有,则取该组件用于保证单实例,如果没有再注册一个新的组件。
    这里可以调用两次注册组件的方法来确认是否使用了代理:
    在这里插入图片描述

    虽然是调用了两次,可它们两个是相等的,也就是说使用了代理,取的都是同一个值。
    如果将@Configuration(proxyBeanMethods = true)改为false
    在这里插入图片描述

    再次运行就会发现这次取的不是代理对象,也就是每一个方法都新注册了一个组件,所以两个不相等。
    因为改为false后久不会再保存代理对象了。
    在这里插入图片描述

    proxyBeanMethods:代理bean的方法
    有两种模式:
    1.Full:(proxyBeanMethods = true) //全模式
    使用代理模式,保证组件的单实例,启动不如false快,但是重复利用率高,适用于会重复使用组件的场景。
    2.lite:(proxyBeanMethods = false) //轻量级
    不是用代理模式,不用保证组件的单实例,启动最快。单每次调用组件都会重新创建一个新的组件,组件可重复使用率低。适用于需要组件但不会重复使用的场景
    总结:用于解决组件依赖
    可有验证方法:
    1.在User类加入Pet类,同时增加get和set方法
    在这里插入图片描述

    2.在Myconfig类使用user01调用pet01
    在这里插入图片描述

    3.在主程序中获取user01和pet01组件,并将user01组件中的Pet类和组件pet01组件进行对比。
    在这里插入图片描述

    4.对比结果:
    当proxyBeanMethods = true时,两者是相等的,代表使用了代理模式没用重新创建pet01组件
    在这里插入图片描述

    当proxyBeanMethods = false时,两者对比不相等,表示重新创建了组件
    在这里插入图片描述

    最终程序代码片:
    1.主程序类:

    /**
     * 这是一个主程序类
     * @SpringBootApplication:表明这是一个SpringBoot应用
     */
    @SpringBootApplication(scanBasePackages="com.shiyi")
    public class MainApplication {
    
        public static void main(String[] args) {
            //1、返回我们ioc容器
            ConfigurableApplicationContext run =
                    SpringApplication.run(MainApplication.class, args);
    
            //2、查看容器里面的组件
            String[] names = run.getBeanDefinitionNames();
            for(String name : names){
                System.out.println(name);//打印出所有的组件名称
            }
    
            //3、从容器中获取组件
    //        Pet pet01 = run.getBean("德玛西亚~",Pet.class);
    //
    //        Pet pet02 = run.getBean("德玛西亚~",Pet.class);
    
    //        System.out.println("是否相等"+(pet01 == pet02));
    //        System.out.println("是否相同"+pet01.equals(pet02));
    
            Myconfig bean = run.getBean(Myconfig.class);
            System.out.println("配置类---"+bean);//进度08:15
    
            User user = bean.user01();
            User user1 = bean.user01();
            System.out.println("验证是否使用代理:"+(user == user1));
    
            User user01 = run.getBean("user01", User.class);
            Pet pet011 = run.getBean("pet01", Pet.class);
    
            System.out.println("用户的宠物:"+(user01.getPet() == pet011));
    
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    2.配置类

    /**
     * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
     * 2、配置类本身也是组件
     * 3、proxyBeanMethods:代理bean的方法
     *      Full:(proxyBeanMethods = true)  //全模式
     *      lite:(proxyBeanMethods = false) //轻量级
     *      用于解决组件依赖
     */
    @Configuration(proxyBeanMethods = true) //告诉springboot这是一个配置类 == 配置文件
    public class Myconfig {
    
        @Bean//给容器中添加组件,以方法名作为组件的id。
        // 返回类型为组件类型,返回的值,就是组件在容器中的实例
        public User user01(){
            User wangcai = new User("wangcai",23);
            //user组件依赖了pet组件
            wangcai.setPet(pet01());
            return wangcai;
        }
    
        @Bean
        public Pet pet01(){
            return new Pet("旺财");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.User类

    /**
     * 用户
     */
    public class User {
    
        private String name;
    
        private Integer age;
    
        private Pet pet;
    
        public User(){
    
        }
    
        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public Pet getPet() {
            return pet;
        }
    
        public void setPet(Pet pet) {
            this.pet = pet;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + ''' +
                    ", age=" + age +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    4.Pet类

    /**
     * 宠物
     */
    public class Pet {
    
        private String name;
    
        public Pet() {
        }
    
        public Pet(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + ''' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    Django批量插入数据及分页器
    JS逆向-韵达快递滑块分析
    Jmeter-Beanshell取样器中引入自制的java脚本(jar java class)
    Java安全之CC2
    MySQL主从复制与读写分离
    6.1 使用scikit-learn构建模型
    web前端网页实例:深度剖析与实践指南
    【LeetCode】C++:数组类算法-运用基础算法思想
    Nginx网络服务的配置
    MySQL索引、使用场景、失效场景、回表、索引覆盖
  • 原文地址:https://blog.csdn.net/bsegebr/article/details/126098367