Detailed explanation of @Configuration in springboot~

Function 1: Tell springboot that this is a configuration class , which is equivalent to the previous configuration file in spring, and the @Bean annotation can be used in the configuration class to register components for the container on the method. The component is also a singleton by default.

Create pet:

package com.springboot.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Pet {
    
    
    private String name;
}

Create User:

package com.springboot.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private String name;
    private Integer age;
}

In spring, we hand over components to the IOC container for management through the configuration file as shown below:

<?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 http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--使用原始的方式进行,springboot不再沿用该方法-->
    <bean id="user01" class="com.springboot.bean.User">
        <property name="name" value="张三"></property>
        <property name="age" value="18"></property>
    </bean>
    <bean id="MyPet" class="com.springboot.bean.Pet">
        <property name="name" value="小猫"></property>
    </bean>
</beans>

In springboot, we can add the @Configuration annotation to the class. The class added with this annotation is considered a configuration class and will be managed by the IOC container .@Configuration注解告诉Spring容器,该类是一个配置类,Spring会扫描该类中的@Bean注解,将其标记为一个Bean,并将其加入到IOC容器中进行管理。

As follows:

package com.springboot;

import com.springboot.bean.Pet;
import com.springboot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    
    
    @Bean//添加组件,以方法名作为组件的id,返回类型就是组件类型,返回的值就是组件在容器中的实例对象
    public User user01(){
    
    
            return new User("张三",18);
    }
    //如果不想让方法名作为组件名,那么可以在Bean注解中自定义名称,如下所示
    @Bean("tom")
    public Pet MyPet(){
    
    
        return new Pet("哈基米");
    }
}

Below we can get the component in the startup class, as shown below:

package com.springboot;

import com.springboot.bean.Pet;
import com.springboot.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MainApplication {
    
    
    public static void main(String[] args) {
    
    
      ConfigurableApplicationContext run= SpringApplication.run(MainApplication.class,args);
        //从容器中获取的每个组件都是单例的
        User user1=run.getBean("user01", User.class);
        User user2=run.getBean("user01",User.class);
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user1==user2);
        Pet pet1=run.getBean("tom", Pet.class);
        Pet pet2=run.getBean("tom", Pet.class);
        System.out.println(pet1);
        System.out.println(pet2);
        System.out.println(pet1==pet2);
    }
}

The output looks like this:

User(name=张三, age=18)
User(name=张三, age=18)
true
Pet(name=哈基米)
Pet(name=哈基米)
true

Function 2: The class added with @Configuration is regarded as a configuration class, and its configuration class itself is also a component

As shown below, we can also obtain the configuration class in the startup class

MyConfig myConfig= run.getBean(MyConfig.class);
System.out.println(myConfig);

The output looks like this:

com.springboot.MyConfig$$EnhancerBySpringCGLIB$$549b0910@347bdeef

Function 3: This annotation has an attribute proxyBeanMethods, its default value is true as shown below

Insert image description here

Set this attribute to true [Full mode] , 表明是代理对象调用方法, springboot总是会检查当前要调用的该组件是否在容器中已存在, as long as it exists, then no matter how many times the external component registration method in the configuration class is called, the single instance object of the previously registered container will be obtained , and 将该属性设置为false[Lite模式],表明配置类在容器中再也不会保存代理类对象,因此在外部类进行调用时,每次调用都会产生一个新的对象

Startup class:

package com.springboot;

import com.springboot.bean.Pet;
import com.springboot.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MainApplication {
    
    
    public static void main(String[] args) {
    
    
      ConfigurableApplicationContext run= SpringApplication.run(MainApplication.class,args);
       MyConfig myConfig= run.getBean(MyConfig.class);
       User user1=myConfig.user01();
       User user2=myConfig.user01();
       System.out.println(user1==user2);//输出true
       Pet pet1=myConfig.MyPet();
       Pet pet2=myConfig.MyPet();
       System.out.println(pet1==pet2);//输出true
    }
}

So should it be set to false or true? This depends on our actual needs. If there are no dependencies between configuration class components, then we set it to false , 因为跳过了检查容器中是否有该对象的过程,加速了容器的启动过程and if there are dependencies between configuration class components, we should set it to true because the method will be called. Get the previous single instance component.

Guess you like

Origin blog.csdn.net/m0_64365419/article/details/133542317