SpringBoot 常用注解的原理和使用( 二 )

  • ImportBeanDefinitionRegistrar 接口的实现 。
  • @Import 的配置
    @Configuration@Import(value = https://www.huyubaike.com/biancheng/{TestA.class, TestB.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})public class ConfigurationTest {}导入一个普通类
    package com.example.ssmpdemo.entity;public class TestA {public void fun(){System.out.println("testA");}}导入一个配置类
    package com.example.ssmpdemo.entity;import org.springframework.context.annotation.Configuration;@Configurationpublic class TestB {public void fun(){System.out.println("testB");}}通过实现 ImportSelector 接口
    import org.springframework.context.annotation.ImportSelector;import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.example.ssmpdemo.entity.TestC"};}}通过重写 ImportBeanDefinitionRegistrarregisterBeanDefinitions 方法 。
    import com.example.ssmpdemo.entity.TestD;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;import org.springframework.core.type.AnnotationMetadata;public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {RootBeanDefinition root = new RootBeanDefinition(TestD.class);registry.registerBeanDefinition("testD", root);}}@ConfigurationProperties
    • 支持常见的下划线、中划线和驼峰的转换 。支持对象引导 。比如:user.friend.name 代表的是user对象中的friend对象中的name
    • 需要有set()方法
    • 只添加 @ConfigurationProperties(prefix = "xxx") 并不会生效,需要配合 @Configuration 让容器识别到 。
    • @EnableConfigurationProperties(value = https://www.huyubaike.com/biancheng/ConfigData.class ) 会将value中指定的类注册为Bean,可直接用 @AutoWired 引用 。
    1. 定义一个类用来记录所有字段 , 并使用@ConfigurationProperties(prefix = "xxx")将数据注入到ConfigData中 。
    package com.example.ssmpdemo.entity;import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;/** * 用来记录Configuration的数据 * @author wangc */@Data@ConfigurationProperties(value = "https://www.huyubaike.com/biancheng/spring.datasource.druid")public class ConfigData {private String driverClassName;private String url;private String username;private String password;}# 对应的yml文件spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:5506/ssmpdemo?serverTimezone=UTCusername: rootpassword: xxxx
    1. 使用@EnableConfigurationProperties(JDBCProperties.class)ConfigData 注册为Bean,并提供给ConfigurationTest使用。可将ConfigData作为参数注入到构造函数和普通函数中 。
    2. 可以用以下方式引用被@ConfigurationProperties(value = "https://www.huyubaike.com/biancheng/spring.datasource.druid")修饰的ConfigData
    • 可以直接把 ConfigData 当成Bean使用/*** 可直接被注入*/@Autowiredprivate ConfigData configData;
    • 可以用构造函数传入进来@Data@Configuration@EnableConfigurationProperties(value = https://www.huyubaike.com/biancheng/ConfigData.class )public class ConfigurationTest {private ConfigData configData2;/*** 作为构造函数的参数注入* @param data*/ConfigurationTest(ConfigData data){this.configData2 = data;}
    • 也可以作为@Bean的方法函数的参数 。只有当前类(ConfigurationTest)才可/*** 直接作为函数的参数* @param data* @return*/@Bean(name = "configData2")HashMap<String, String> getBean(ConfigData data){return new HashMap<>(0);}
    • 可以省略ConfigData直接将字段注入到返回结果中 。@Bean@ConfigurationProperties(value = "https://www.huyubaike.com/biancheng/spring.datasource.druid")HashMap<String, String> getBean2(ConfigData data){// 会自动为hashMap赋值,或使用set方法为对象赋值return new HashMap<>();}
    EnableConfigurationProperties注解的内部如下,它导入了一个实现了 ImportBeanDefinitionRegistrar 接口的类 。
    @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(EnableConfigurationPropertiesRegistrar.class)

    推荐阅读