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集合,里面装载了那些类限定名(配置信息)

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

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

【SpringBoot】Re 02 Import与自定义装配实现的更多相关文章

  1. java框架之SpringBoot(10)-启动流程及自定义starter

    启动流程 直接从 SpringBoot 程序入口的 run 方法看起: public static ConfigurableApplicationContext run(Object source, ...

  2. SpringBoot入门(五)——自定义配置

    本文来自网易云社区 大部分比萨店也提供某种形式的自动配置.你可以点荤比萨.素比萨.香辣意大利比萨,或者是自动配置比萨中的极品--至尊比萨.在下单时,你并没有指定具体的辅料,你所点的比萨种类决定了所用的 ...

  3. springboot - 返回xml error 从自定义的 ErrorController

    1.概览 2.在<springboot - 返回JSON error 从自定义的 ErrorController>基础上,做如下调整: 1).新增Attribute类和Error类 pac ...

  4. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...

  5. @Import导入自定义选择器

    @Import导入自定义选择器 之前一篇博文:Spring中的@Import注解已经详细介绍了@Import注解,不赘述. 需求描述 通过@import注解自定义组件选择器,将满足我们自定义的规则的b ...

  6. springBoot进阶02

    SpringBoot进阶02 1. 日志的使用 1.1 基本使用 /** * 获取日志记录器 */ Logger logger = LoggerFactory.getLogger(this.getCl ...

  7. SpringBoot自定义装配的多种实现方法

    Spring手动装配实现 对于需要加载的类文件,使用@Configuration/@Component/@Service/@Repository修饰 @Configuration public cla ...

  8. springboot系列十四、自定义实现starter

    一.starter的作用 当我们实现了一个组建,希望尽可能降低它的介入成本,一般的组建写好了,只要添加spring扫描路径加载spring就能发挥作用.有个更简单的方式扫描路径都不用加,直接引入jar ...

  9. thymeleaf教程-springboot项目中实现thymeleaf自定义标签

    转载: http://www.9191boke.com/466119140.html    91博客网 开始: 在使用thymeleaf的过程中有时候需要公共部分渲染页面,这个时候使用自定义标签实现自 ...

  10. SpringBoot核心特性之组件自动装配

    写在前面 spring boot能够根据依赖的jar包自动配置spring boot的应用,例如: 如果类路径中存在DispatcherServlet类,就会自动配置springMvc相关的Bean. ...

随机推荐

  1. php分组查询和聚合函数 数据显示的顺序

      // 分组查询和聚合函数         // 分组查询 : 将指定字段中的数据,按照不同的具体数值,进行分组         //           数据相同的分在一个分组中          ...

  2. kettle从入门到精通 第四十四课 kettle 去重

    1.我们平常在写应用程序的时候,会有去重的业务场景,可以在数据库层面解决,也可以在内存层面解决. 同样kettle也有去重的步骤[唯一行(哈希值)]和[去除重复记录] 唯一行(哈希值):使用 Hash ...

  3. ABC332

    D 我们可以把矩阵 \(\text{A}\) 看成 \({p,q}\). \(p\) 指现在一行最开始在哪里,\(q\) 指现在这一列最开始在哪里. 于是我们枚举 \(p\) 和 \(q\) 所有可能 ...

  4. C# .NET HttpWebRequest 按每个(单个)请求跳过证书校验

    C# .NET HttpWebRequest 按每个(单个)请求跳过证书校验 自签名证书 HTTPS TLS . 使用.NET 4.5 新加的属性 HttpWebRequest.ServerCerti ...

  5. 使用 eBPF 在云中实现网络可观测性

    可观测性是一种了解和解释应用当前状态的能力,也是一种知道何时出现问题的方法.随着在 Kubernetes 和 OpenShift 上以微服务形式进行云部署的应用程序越来越多,可观察性受到了广泛关注.许 ...

  6. NetCore Benchmark 基准测试

    基于NetCore的基准测试Demo(控制台程序) 创建控制台程序,输入工程名称    LinqConsole 通过NuGet引用BenchmarkDotNet至工程中 编写测试代码  类:Bench ...

  7. Luban小试牛刀

    Luban小试牛刀 LubanUnity LubanUnity配置工具配置解决方案 简介 Github  文档   视频教程  Unity工具 个人感觉挺强大,便捷的,适合中大型游戏项目的配置工作.小 ...

  8. nginx 信号量

    nginx支持的信号量 TERM, INT fast shutdown QUIT graceful shutdown HUP changing configuration, keeping up wi ...

  9. 颠覆传统编程,用ChatGPT十倍提升生产力

    我们即将见证一个新的时代!这是最好的时代,也是最坏的时代! 需求背景 背景: 平时会编写博客,并且会把这个博客上传到github上,然后自己买一个域名挂到github上. 我平时编写的博客会有一些图片 ...

  10. Linux中的IDR机制

    # Linux中的IDR机制 背景 最近在学习 Linux的i2c子系统,看到代码中有关于IDR的调用.了解了一下有关的文档,发现是用来管理指针(对象实例). //based on linux V3. ...