zoukankan      html  css  js  c++  java
  • 【SpringBoot】Re 02 Import与自定义装配实现

    Import的注册形式:

    1、使用@Import导入一个或者多个类字节对象

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
        Class<?>[] value();
    }

    使用时一般在配置类上注解,表示该注解类导入了其他配置

    @Configuration
    @Import({
            MyBeanFactoryPostProcessor.class,
            ClassA.class,
            ClassB.class,
            ClassC.class
    })
    public class TestConfiguration {
    }

    2、使用导入Bean定义登记者

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(ClassD.class);
            registry.registerBeanDefinition("classD", rootBeanDefinition);
        }
    }

    然后配置导入:

    @Configuration
    @Import(MyImportBeanDefinitionRegistrar.class)
    public class TestConfiguration {
    }

    测试运行:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = TestConfiguration.class)
    public class DefinitionTest {
        @Autowired
        private ClassD classD;
    
        @Test
        public void testSample() {
            System.out.println(classD);
        }
    }
    cn.dzz.bean.ClassD@6771beb3
    
    Process finished with exit code 0

    3、使用【导入选择器】

    原始版本是直接声明类完整路径名

    public class MyImportSelector implements ImportSelector {
    
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            return new String[] {"cn.dzz.bean.ClassD"};
        }
    }

    导入配置:

    @Configuration
    @Import(MyImportSelector.class)
    public class TestConfiguration {
    }

    测试结果:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = TestConfiguration.class)
    public class DefinitionTest {
        @Autowired
        private ClassD classD;
    
        @Test
        public void testSample() {
            System.out.println(classD);
        }
    }
    cn.dzz.bean.ClassD@682b2fa
    
    Process finished with exit code 0

    第二版本,类的限定名固定编写在源码文件中不可灵活改变:

    我们可以通过外部的配置文件来实现:

    1、创建配置读取类

    public class Tc51AutoConfigReader {
    
        public static Properties readerProperties(String resource){
            Properties properties = new Properties();
            InputStream it = Tc51AutoConfigReader.class.getResourceAsStream(resource);
    
            try {
                properties.load(it);
    
            } catch (IOException e) {
                e.printStackTrace();
            }
            return  properties;
        }
    }

    2、获取字符串,但是这个方法写的非常简单,只读取了一个类

    我们的一个Map是允许一个键存储多个值的,也就是读取多个类

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
      Properties properties = Tc51AutoConfigReader.readerProperties("/Tc51autoconfig.properties");
      String property = properties.getProperty(Tc51EnableAutoConfig.class.getName());
      return new String[]{property};
    }

    第三版本,调用Spring写好的方法和注解方式实现自动装配
    首先仿照SpringBoot创建这样的配置文件:

    内部配置信息:

    cn.dzz.annotation.MyEnableAutoConfiguration = 
      cn.dzz.config.RedisConfiguration

    声明一个自定义开启自动配置注解:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(MyImportSelector.class)
    public @interface MyEnableAutoConfiguration {
    }

    然后实现导入选择器接口的方法变成这样:

    public class MyImportSelector implements ImportSelector {
    
        private Class<?> getMyFactoryLoaderClass(){
            return MyEnableAutoConfiguration.class;
        }
    
        private List<String> getConfiguration(){
            return SpringFactoriesLoader.loadFactoryNames(
                getMyFactoryLoaderClass(),MyImportSelector.class.getClassLoader()
            );
        }
    
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            return StringUtils.toStringArray(getConfiguration());
        }
    }

    首先是得到注解类的字节对象,它被下面的方法所需要,

    获取配置方法可以从配置文件中读取信息返回一个List集合,里面装载了那些类限定名(配置信息)

    需要的参数是上面写的注解类字节对象和一个类加载器

    再返回给选择器方法,集合转换一下数组即可

  • 相关阅读:
    Android MVP架构分析
    JavaEE基本了解
    学习面试题Day09
    使用反射来实现简单工厂模式
    Android Material Design简单使用
    c语言 找最小值
    c++ 计算指定半径圆的面积
    c++ 字符串拷贝以及合并
    python yaml文件读写
    python 列表元素替换以及删除
  • 原文地址:https://www.cnblogs.com/mindzone/p/13526637.html
Copyright © 2011-2022 走看看