@Anotación de configuración y anotación @bean en la clase de configuración SpringBoot

1. @ Anotación de configuración

Uso:
actuar sobre la clase Rol: decirle a SpringBoot que esta es una clase de configuración, que es equivalente al archivo de configuración xml en Spring.

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件
public class Config {
    
    
}

2.Anotación @ bean

Uso: La anotación @Bean se usa en la clase de configuración para registrar componentes en el contenedor de IoC en el método. De forma predeterminada, también es una instancia única.
Rol: Agregar componentes al contenedor es equivalente a la etiqueta <bean> en el archivo de configuración xml en Spring.
Comprensión: utilice el nombre del método como id del componente. El tipo de retorno es el tipo de componente. El valor devuelto es la instancia del componente en el contenedor.

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件
public class Config {
    
    

    @Bean   //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public Person person1(){
    
    
        return new Person("Mr.Yu",21,"male");
    }

    @Bean("customize")  //id值也可以指定
    public Person person2(){
    
    
        return new Person("小明",20,"male");
    }
}

Imprima los objetos en nuestro contenedor IoC en la clase del programa principal para ver si nuestra person1 y custom se agregan al contenedor

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

Resultado de salida:
Inserte la descripción de la imagen aquí
puede ver que hay dos objetos que almacenamos en el contenedor de IoC en el resultado de salida

3. Instancia única

La instancia almacenada en el contenedor de IoC con la anotación @Bean también es una instancia única

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

        //单实例
        Person person1 = run.getBean("person1",Person.class);
        Person person2 = run.getBean("person1",Person.class);
        System.out.println("person1 == person2 :"+ (person1 == person2));
}

Resultado de salida:
Inserte la descripción de la imagen aquí

4. La clase de configuración también es un componente del contenedor.

@SpringBootApplication
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);
        }
        
        //配置类本身也是组件
        Config bean = run.getBean(Config.class);
        //com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
        System.out.println(bean);


    }
}

Resultado de salida:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

5. Llame directamente al método person1 () en la clase de configuración

¿Qué sucede si llamamos directamente al método person1 () en la clase de configuración, ya sea que se tome del contenedor de IoC o que sea directamente un objeto nuevo?

  1. En el caso de una clase de configuración de new, llame al método person1, que devuelve el objeto de new
  2. Pero si obtenemos la clase de configuración del contenedor, no importa cuántas veces se elimine el método person1, siempre devolverá el mismo objeto de instancia única, que es el objeto tomado del contenedor de IoC.
@SpringBootApplication
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);
        }

        //配置类本身也是组件
        Config bean = run.getBean(Config.class);
        //获取到的本身就是代理对象
        //com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219
        System.out.println(bean);

        //如果我们直接调用person1方法,它是从IoC容器中拿还是直接new一个对象呢,
        //在new一个配置类出来的情况下,调用person1方法,它返回的是new出来的对象
        Config config = new Config();
        Person person3 = config.person1();
        Person person4 = config.person1();
        System.out.println("person3 == person4 :"+ (person3 == person4));

        //但是如果我们从容器中取得的配置类,无论再去掉用多少次person1方法,它始终返回的都是同一个单实例对象,也就是从IoC容器中拿的对象。
        //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有;
        //保持组件单实例
        Person person5 = bean.person1();
        Person person6 = bean.person1();
        System.out.println("person5 == person6 :"+ (person5 == person6));

    }
}

Resultado de salida:

Inserte la descripción de la imagen aquí

6.proxyBeanMethods-métodos de bean proxy

El resultado de salida del objeto de configuración obtenido del contenedor:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

En el resultado de salida anterior, podemos ver que el objeto de clase de configuración obtenido del contenedor es en sí mismo un objeto proxy mejorado por SpringCGLIB

  • @Configuration () por defecto es proxyBeanMethods = true.
  • Si @Configuration (proxyBeanMethods = true), el objeto proxy llama al método. SpringBoot siempre comprobará si este componente ya existe en el contenedor, y al llamar al método en la clase de configuración, devolverá el componente que ya está en el contenedor (es decir, el objeto que ya existe en el contenedor de IoC).
  • Si @Configuration (proxyBeanMethods = false), no es un método de llamada de objeto proxy. SpringBoot no verificará si este componente ya está en el contenedor, y se devolverá un nuevo objeto cuando se llame al método en la clase de configuración.

@Configuration (proxyBeanMethods = false) Ejemplo: Cambie
@Configuration () en 5 arriba a @Configuration (proxyBeanMethods = false). El
resultado de salida es:
Inserte la descripción de la imagen aquí
Resumen:

  • Modo completo (proxyBeanMethods = true): para garantizar que se llame a cada método @Bean cuántas veces el componente devuelto es una sola instancia
  • Modo básico (proxyBeanMethods = false): cuántas veces se llama a cada método @Bean, los componentes devueltos se crean nuevamente
  • Las dependencias de componentes deben utilizar el modo completo predeterminado. Si otro modo básico predeterminado
  • No hay dependencia entre los componentes de la clase de configuración. El modo Lite se usa para acelerar el proceso de inicio del contenedor. Cuando se llama al método en la clase de configuración, SpringBoot no juzgará si el objeto ya existe en el contenedor cada vez, lo que reduce el proceso de juicio.
  • Existe una relación de dependencia entre los componentes de la clase de configuración. Al llamar a un método en una clase de configuración, SpringBoot determinará si el objeto ya existe en el contenedor cada vez, y se llamará al método para obtener el componente de instancia única anterior, utilizando el modo completo

Supongo que te gusta

Origin blog.csdn.net/MrYushiwen/article/details/111880916
Recomendado
Clasificación