SpringBoot常用注解 | @Configuration

「这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战」。

前言

SpringBoot 中简化了大量的配置文件,取而代之的是利用注解完成之前通过配置文件完成的工作。操作上便捷了很多,但是也隐藏了一些内部实现细节,在使用的时候不能盲目,应该了解在以往 Spring 项目中是如何配置的,这样可以加深我们对 SpringBoot 的理解

概述

类上加这个注解就说明这个类是一个配置类

  • Spring 项目中添加配置类

在传统的 Spring 项目中,我们想要引入一个配置类,通常是定义一个 bean.xml ,然后通过 bean 注解给容器中添加组件,注入到 Spring 容器中。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       
    <bean id="config01" class="com.example.helloworlddemo.config.User">
        <property name="name" value="zhangsan"/>
        <property name="age" value="18"/>
    </bean>
    
</beans>
复制代码
  • SpringBoot 项目中添加配置类

SpringBoot 项目中,我们只需要创建一个配置类,然后在这个类上直接加上 @Configration 注解,这个时候,这个类就等同于之前创建的 bean.xml,之前是针对 xml 操作,这里我们直接操作配置类即可。通过 @bean 注解添加组件。当项目启动的时候就会自动检测到该类,然后将这个类加载注入到容器中,省略了我们之前手动配置注入,扫描配置文件的步骤。

@Configuration // 告诉SpringBoot 这是一个配置类 = bean.xml
public class MyConfig {

    /**
     * @Bean 等同于 <bean></bean> 标签。
     * 方法名 作为组件id
     * 返回值类型 组件类型
     * 返回值 组件在容器中的实例对象,单例的
     */
    @Bean
    public User config01() {
        return new User("张三", "18");
    }
}
复制代码
  • 验证是否注入成功

我们可以将容器中所有的组件名称打印出来

public static void main(String[] args) {
    // 返回IOC容器对象
    ConfigurableApplicationContext run = SpringApplication.run(HelloworldDemoApplication.class, args);
    // 查看容器内的所有组件
    String[] beanDefinitionNames = run.getBeanDefinitionNames();
    for (String name : beanDefinitionNames) {
        System.out.println(name);
    }
}
复制代码

可以看到,我们刚刚自己定义的已经注入到容器中了

image.png

并且这个组件实例是单例的,无论获取多少次都是一样的。

    // 获取组件
    User config01 = run.getBean("config01", User.class);
    User config02 = run.getBean("config01", User.class);
    System.out.println(config01);
    System.out.println(config02);
复制代码

image.png

SpringBoot2.x中的变化

相比于 1.0 版本,2.0版本 @Configuration 注解添加了新的属性 proxyBeanMethods()

image.png

这个属性的作用是,设置配置组件中获取组件实例对象的方式。简单理解为单例和多例的区别。默认为 true 单例的。

  • @Configuration(proxyBeanMethods = true)

当我们设置为 true 的时候,我们获取到的配置对象(MyConfig)其实是一个代理对象(com.example.helloworlddemo.config.MyConfig$$EnhancerBySpringCGLIB$$97588a67@632aa1a3),每次我们调用这个对象去获取组件实例的时候,会先从容器中检查,有就拿容器内的,没有就新建一个。这样做的目的是为了保证容器中必然存在我们需要的实例对象,解决组件依赖的问题。想想如果一个组件依赖另一个组件, A 组件依赖 B 组件 ,我们获取 A 的时候容器内没有 B 那么这个时候就会出现空指针的问题。总之一句话,true 的时候,SpringBoot 每次都会检查容器中是否存在我们需要的实例对象,保证实例存在。

  • @Configuration(proxyBeanMethods = false)

当我们设置为 false 的时候,返回的就是原始对象(com.example.helloworlddemo.config.MyConfig@c1a4620),这个时候每次我们调用获取实例方法都会返回一个新的实例对象,并且 SpringBoot 会跳过实例检查的步骤,所以这种方式下项目启动加载速度会更快,所以当我们的配置类仅仅是为了返回一个组件实例的时候,可以设置为 false 提高项目加载速度。

总结

  1. 配置类里面使用 @Bean 标注在方法上给容器注册组件,默认也是单实例的
  2. 配置类本身也是组件
  3. proxyBeanMethods:代理 bean 的方法
    • Full 模式 :(proxyBeanMethods = true)
    这种模式下,保证每个 @Bean 方法,被重复调用返回的组件都是单实例的,直接从容器中拿,没有就新建。
    • Lite 模式:(proxyBeanMethods = false)
    这种模式下:每个 @Bean 方法 每次调用返回的实例对象都是新创建的

组件存在依赖必须使用Full模式默认。其他默认是否Lite模式

猜你喜欢

转载自juejin.im/post/7034421582034370597