深入理解@Configuration,学习 @import @ConfigurationProperties @EnableConfigurationProperties 注解的作用

@import

用于直接往容器中导入某个组件,与@Bean注册组件类似,默认名称是全限定类名, 还可以把导入的bean(类)加载到容器中(就是往容器中注册这个bean);

@Configuration的作用就是说明这是一个bean(此时容器并没有把该bean注入到容器中),可理解为用spring的时候xml里面的< beans>标签,但是如果你想要这个bean注入到容器的话,你还需要使用扫描组件来扫描这个配置类:(比如使用componentScan注解来扫描,或者是使用import注解来导入),用于告诉SpringBoot这是一个配置类(类似于Spring的xml配置文件)
可以在配置类中注册组件(就是在配置类可以使用@bean注解声明其他的bean,只要配置类被注册到容器,那么这些声明的bean也会被注入到容器中),并且这些bean默认是单例;配置类本身也是一个组件;

当我们使用AnnotationConfigApplicationContext加载配置类的时候,配置类可以不添加@configuration这个注解,如下案例

public class ConfigTest {
    @Bean
    public Employee create(){
        Employee employee = new Employee();
        return employee;
    }
}
@org.junit.jupiter.api.Test
    public void test1(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigTest.class);
        ConfigTest bean = context.getBean(ConfigTest.class);
        System.out.println(bean);
    }

测试结果:

但是@Configuration注解有一个更加强大的功能,它可以保障配置类中使用方法创建的bean的唯一性。为@Configuration注解设置proxyBeanMethods属性值为true即可,由于此属性默认值为true,所以很少看见明确书写的,除非想放弃此功能。

@Configuration(proxyBeanMethods = true)  
//如果这里的属性是true,那么我们在运行对应的方法的时候,只要这个方法曾经在spring容器中加载过bean,那么再次调用这个方法来获取bean的时候,就是直接从容器中去获取bean,不会再去new;  
如果是false的话,那么使用这个方法获取几次对象得到的都是一个新对象;

//需要注意的是 这个proxyBeanMethods的默认值是ture,就是默认会帮我们开启使用代理对象,使用的代理对象方式是cjlib
public class SpringConfig33 {
    @Bean
    public Cat cat(){
        return new Cat();
    }
}

下面通过容器再调用上面的cat方法时,得到的就是同一个对象了。注意,必须使用spring容器对象调用此方法才有保持bean唯一性的特性。 把上面的ture改成false,运行看看输出的结果就会发现不一样了;

public class App33 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig33.class);  //直接把加载的类变成一个bean对象交给容器托管
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("-------------------------");
        //使用配置类的对象来调用方法,只要proxyBeanMethods = true,那么在配置类之外的类来调用配置类对象获取bean的方法获取对象获取的也是同一个对象
        SpringConfig33 springConfig33 = ctx.getBean("springConfig33", SpringConfig33.class);
        System.out.println(springConfig33.cat());
        System.out.println(springConfig33.cat());
        System.out.println(springConfig33.cat());
    }
}

@ConfigurationProperties(prefix = "tools.ip") //从配置文件去获取值注入到当前bean的属性中

tools:
  ip:
    cycle: 1
    cycleReset: false

/**
 * @author LJM
 * @create 2022/4/13
 */
@ConfigurationProperties(prefix = "tools.ip")
//注意这个注解配置的类要求该类是spring管理的bean,所以你要么就是使用@Component把这个类声明为bean,
// 要么就是在使用这个类的地方使用@EnableConfigurationProperties(IpProperties.class)
@Component("ipProperties")
public class IpProperties {
    
    private Long cycle ;
    private Boolean cycleReset ;
}

@EnableConfigurationProperties:就是把一个使用了ConfigurationProperties 注解的类加载为一个bean,bean的name是属性的前缀名-全限定名称,同时会把这个bean注册到spring容器中;以及各种带@Enable...开头的注解,都是把对应的bean往容器中注册;

猜你喜欢

转载自blog.csdn.net/weixin_53142722/article/details/124160698