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. B站login-极验逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 https:// ...

  2. LVGL8文本框设置长文本会自动滚动到文本最后解决方法

    在创建完成并设置完文本之后加一句 lv_obj_scroll_to_y(obj,0, LV_ANIM_OFF); 就可以了 原因:官方控件里面设置文本的接口里面设置文本后会设置一次光标位置到文本末尾, ...

  3. 解密Prompt系列31. LLM Agent之从经验中不断学习的智能体

    Agent智能体的工作流可以简单分成两种:一种是固定的静态工作流,一种是智能体自主决策的动态工作流. 静态流程的Agent举几个例子,例如新闻热点追踪推送Agent,每日新论文摘要总结Agent,它们 ...

  4. 副本集replicaSet

    mongodb高可用架构 https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/ 复制是跨多个服务器同步数据的过程. 复制提供 ...

  5. 关于mybatis中的${}、#{},

    mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...

  6. Interceptor拦截器demo

    Interceptor拦截器demo ##接口测试类 @RestController public class TestController { @RequestMapping(value = &qu ...

  7. typroa破解

    Typora 一款 Markdown 编辑器和阅读器 风格极简 / 多种主题 / 支持 macOS,Windows 及 Linux 实时预览 / 图片与文字 / 代码块 / 数学公式 / 图表 目录大 ...

  8. 06-Python类与对象

    什么是类 百度百科: 类是对象的抽象,对象是对客观事物的抽象. 用通俗的话来说: 类是类别的意思,是数据类型. 对象是类别下的具体事物. 也就是说: 类是数据类型,对象是变量. 比如: 自定义一种数据 ...

  9. Java开发者的神经网络进阶指南:深入探讨交叉熵损失函数

    前言 今天来讲一下损失函数--交叉熵函数,什么是损失函数呢?大体就是真实与预测之间的差异,这个交叉熵(Cross Entropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异 ...

  10. Linux 错误码

    背景 Linux的错误码包含在/usr/include/asm-generic/errno-base.h和/usr/include/asm-generic/errno.h 这两个文件内. 可用于查询. ...