【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集合,里面装载了那些类限定名(配置信息)
需要的参数是上面写的注解类字节对象和一个类加载器
再返回给选择器方法,集合转换一下数组即可
【SpringBoot】Re 02 Import与自定义装配实现的更多相关文章
- java框架之SpringBoot(10)-启动流程及自定义starter
		启动流程 直接从 SpringBoot 程序入口的 run 方法看起: public static ConfigurableApplicationContext run(Object source, ... 
- SpringBoot入门(五)——自定义配置
		本文来自网易云社区 大部分比萨店也提供某种形式的自动配置.你可以点荤比萨.素比萨.香辣意大利比萨,或者是自动配置比萨中的极品--至尊比萨.在下单时,你并没有指定具体的辅料,你所点的比萨种类决定了所用的 ... 
- springboot - 返回xml error 从自定义的 ErrorController
		1.概览 2.在<springboot - 返回JSON error 从自定义的 ErrorController>基础上,做如下调整: 1).新增Attribute类和Error类 pac ... 
- springboot + 拦截器 + 注解 实现自定义权限验证
		springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ... 
- @Import导入自定义选择器
		@Import导入自定义选择器 之前一篇博文:Spring中的@Import注解已经详细介绍了@Import注解,不赘述. 需求描述 通过@import注解自定义组件选择器,将满足我们自定义的规则的b ... 
- springBoot进阶02
		SpringBoot进阶02 1. 日志的使用 1.1 基本使用 /** * 获取日志记录器 */ Logger logger = LoggerFactory.getLogger(this.getCl ... 
- SpringBoot自定义装配的多种实现方法
		Spring手动装配实现 对于需要加载的类文件,使用@Configuration/@Component/@Service/@Repository修饰 @Configuration public cla ... 
- springboot系列十四、自定义实现starter
		一.starter的作用 当我们实现了一个组建,希望尽可能降低它的介入成本,一般的组建写好了,只要添加spring扫描路径加载spring就能发挥作用.有个更简单的方式扫描路径都不用加,直接引入jar ... 
- thymeleaf教程-springboot项目中实现thymeleaf自定义标签
		转载: http://www.9191boke.com/466119140.html 91博客网 开始: 在使用thymeleaf的过程中有时候需要公共部分渲染页面,这个时候使用自定义标签实现自 ... 
- SpringBoot核心特性之组件自动装配
		写在前面 spring boot能够根据依赖的jar包自动配置spring boot的应用,例如: 如果类路径中存在DispatcherServlet类,就会自动配置springMvc相关的Bean. ... 
随机推荐
- rsync备份任务练习
			06-备份任务实战 今天的任务主要以实际备份任务入手,完成综合练习,完成对rsync的综合运用. 先看需求 再讲解 再次动手实践 客户端需求 客户端需求: 1.客户端每天凌晨1点在服务器本地打包备份( ... 
- Vue3:项目创建
			Vue 3 相对于 Vue 2 带来了许多改进和优点,这些改进主要是为了提高性能.开发体验和可维护性.但是对于创建项目,Vue3也可以采用跟Vue2相同的方式. 使用CLI创建 1. 安装Vue CL ... 
- kooder安装及本地搜索git仓库代码
			kooder安装及本地搜索git仓库代码 需求背景:如果需要从Git代码仓库查询某个配置项做批量的更新替换,如果一个一个找不合适且容易遗漏,需要借助第三方工具来模糊查询来实现. 1.下载及文档地址ht ... 
- Android查看apk安装包的AndroidManifest.xml文件
			Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` Android查看apk安装包的AndroidManife ... 
- re.search()用法详解
			re.search() 是 Python 的正则表达式库 re 中的一个方法,用于在字符串中搜索与正则表达式模式匹配的第一个位置,并返回一个匹配对象.如果没有找到匹配项,则返回 None. 以下是 r ... 
- 深入了解身份认证和授权机制,看看API请求到底发生了什么?
			前段时间写了一篇基于.NetCore环境使用IdentityServer4为API接口鉴权的文章,更多的是从快速上手的角度描述了IdentityServer4的使用.后续使用过程中,自己有了一些其他想 ... 
- 剖析 Kafka 消息丢失的原因
			目录 前言 一.生产者导致消息丢失的场景 场景1:消息体太大 解决方案 : 1.减少生产者发送消息体体积 2.调整参数max.request.size 场景2:异步发送机制 解决方案 : 1.使用带回 ... 
- glog_bash:在bash中优雅输出日志
			介绍 官方仓库:https://github.com/GuoFlight/glog_bash .下载其中的glog_bash.sh即可. 这是专门用于bash脚本中的logger,名为glog_bas ... 
- UG二次开发 PYTHON 环境配置
			NX 二次开发 PYTHON VSCODE 环境配置 我电脑上装的是WIN11 NX1988 在电脑的UG的安装文件夹内找到 python 一般在 xx\NXBIN 在所在的文件夹内,运行python ... 
- Java基础:线程的三种创建方式
			一.继承Thread类 定义一个类继承线程类Thread 重写run()方法 创建线程对象 调用线程对象的start()方法创建线程 Thread类的常用API setName(String name ... 
