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


    }

}

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

}

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

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 + '\'' +
                '}';
    }
}

  • 169
    点赞
  • 461
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值