SpringBoot Import及自定义装配实现方法解析

网友投稿 246 2022-11-26


SpringBoot Import及自定义装配实现方法解析

Import的注册形式:

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

@Target({ElementNsEjcRType.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 getConfiguration(){

return SpringFactoriesLoader.loadFactoryNames(

getMyFactoryLoaderClass(),MyImportSelector.class.getClassLoader()

);

}

public String[] selectImports(AnnotationMetadata annotationMetadata) {

return StringUtils.toStringArray(getConfiguration());

}

}

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

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

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

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:快速解决List集合add元素,添加多个对象出现重复的问题
下一篇:使用Java程序模拟实现新冠病毒传染效果
相关文章

 发表评论

暂时没有评论,来抢沙发吧~