SpringBoot的@Configuration注解

发布时间 2023-05-09 12:22:09作者: zwGitOne

  本文主要讲述SpringBoot的@Configuration注解。

一.POJO类的声明

  例如有两个pojo类,分别是User和Pet

  User类的声明如下:

public class User {

    private String name;
    private Integer age;

    public User(){

    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

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

  Pet类的声明如下:

public class Pet {

    private String name;
    private String clasz;

    public Pet() {
    }

    public Pet(String name, String clasz) {
        this.name = name;
        this.clasz = clasz;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClasz() {
        return clasz;
    }

    public void setClasz(String clasz) {
        this.clasz = clasz;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                ", clasz='" + clasz + '\'' +
                '}';
    }
}

二.在Spring的xml中配置组件

  1.pojo无依赖关系,bean.xml的声明如下:

<?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="user01" class="com.atguigu.boot.pojo.User">
        <property name="name" value="tom"></property>
        <property name="age" value="18"></property>
    </bean>

    <bean id="pet01" class="com.atguigu.boot.pojo.Pet">
        <property name="name" value="maomi"></property>
        <property name="clasz" value="cat"></property>
    </bean>
</beans>

  2.pojo有依赖关系,user类依赖pet类

  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 +
                ", pet=" + pet +
                '}';
    }
}

  bean.xml的声明如下:

<?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="user01" class="com.atguigu.boot.pojo.User">
        <property name="name" value="tom"></property>
        <property name="age" value="18"></property>
        <property name="pet" ref="pet01"></property>
    </bean>

    <bean id="pet01" class="com.atguigu.boot.pojo.Pet">
        <property name="name" value="maomi"></property>
        <property name="clasz" value="cat"></property>
    </bean>
</beans>

三.SpringBoot的@Configuration配置组件

  @Configuration注解作用在类上,声明该类是配置组件类;

  @Bean注解作用在配置组件类的方法上,声明该方法是ioc容器的组件。

  POJOConfig组件配置类声明如下:

/**
 * @Configuration 标识配置组件的类
 * @Bean 标识配置对象的方法
 */
@Configuration
public class POJOConfig {
    
    @Bean
    public User user01(){
        return new User("张三",19);
    }

    @Bean
    public User user02(){
        return new User("张三",19);
    }

    @Bean
    public Pet pet01(){
        return new Pet("tom","cat");
    }
}

  在MainApp启动类中验证注册的组件是否唯一。

@SpringBootApplication
public class MainApp {

    public static void main(String[] args) {
        // 1.获取ioc容器【应用程序的上下文】
        ConfigurableApplicationContext run = SpringApplication.run(MainApp.class, args);

        // 2.获取上下文所有的bean的name
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        // 3.获取指定类型的bean的对象
        // 只注册了一个User类的对象,ioc容器获取的也只有一个对象
        // 注册了同一个类的多个对象
        User user01 = run.getBean("user01", User.class);
        User user02 = run.getBean("user01", User.class);
        System.out.println(user01 == user02);  // true

        // 4.获取配置组件类的对象
        POJOConfig bean = run.getBean(POJOConfig.class);
        System.out.println(bean);

        User user1 = bean.user01();
        User user2 = bean.user01();
        System.out.println(user1 == user2);

    }
}

  证明user01和user02对象,都是从ioc容器中取出的 id=user01的对象。

  @Configuration中有一个参数proxyBeanMethod,默认为 true,

  这个注解主要有以下两个作用:

  1. 声明一个类为 Spring 配置类。@Configuration 注解告诉 Spring 这是一个配置类,需要在应用程序上下文中注册 bean。通常情况下,配置类中包含了多个 @Bean 方法,这些方法都会返回一个对象,供其他 bean 使用。

  2. 控制 Spring 是否会为 @Bean 方法创建代理对象。当 proxyBeanMethods 设置为 true 时,Spring 会为每个 @Bean 方法创建一个代理对象,这个代理对象会缓存方法的调用结果,从而提高应用程序的性能。当 proxyBeanMethods 设置为 false 时,Spring 不会为 @Bean 方法创建代理对象,而是每次调用 @Bean 方法时都会创建一个新的对象。

  需要注意的是,如果使用了 @Configuration(proxyBeanMethods = true),那么 @Bean 方法必须是非 final 的,因为 Spring 使用 CGLIB 生成子类来实现代理。如果 @Bean 方法是 final 的,那么就无法生成子类,从而导致代理失败。因此,如果你的 @Bean 方法必须是 final 的,就需要将 proxyBeanMethods 设置为 false。