Solon Ioc 的魔法之注解注入器(也可叫虚空注入器)
很多人惊叹于 Solon 的注入能力,一个注解怎可注万物???
一、注解注入器
Solon Ioc 的四大魔法之一:注解注入器(BeanInjector<T extends Annotation>)。在扫描时,Solon 会检查相关组件的字段或者参数,上面有没有注解?如果有注解,有没有对应的注入器注册过?如果有,则执行注入器。
1、什么是注解?
注解一般也叫元数据,是一种代码级别的说明性内容。编译器在编译时,可以借助注解产生很多魔法效果;Solon Ioc 在运行时,也借助注解产生了很多魔法效果。
其中,注解注入器便是 Solon Ioc 的四大魔法之一。
2、注入器接口是怎么样的?
@FunctionalInterface
public interface BeanInjector<T extends Annotation> {
void doInject(VarHolder vh, T anno);
}
其中:
- vh,用于接收变量数据
- anno,则是申明的注解
3、Solon Ioc 的注入器注册接口
void beanInjectorAdd(Class<T> annoClz, BeanInjector<T> injector);
void beanInjectorAdd(Class<T> annoClz, Class<?> targetClz, BeanInjector<T> injector);
二、为什么也可叫“虚空”注入器?
这个是因为,Solon 的注入是执行一个接口,而不是即定的内容。内容,可以是现成的,也可以是动态构建的。所以很“虚空”。
1、分解内置的的 @Inject 注解实现
@Inject 的简单使用示例
//主入配置
@Component
public class DemoService{
@Inject("${track.url}")
String trackUrl;
@Inject("${track.db1}")
HikariDataSource trackDs;
}
//注入 bean
@Component
public class DemoService{
@Inject
private static TrackService trackService;
@Inject("userService")
private UserService userService;
}
注入器的能力实现剖析(简单的示意实现,框架的实现比这个复杂)
context.beanInjectorAdd(Inject.class, (vh, anno) -> {
//申明:是否必须要注入?
vh.required(anno.required());
if (Utils.isEmpty(anno.value)) {
//没有值,说明是 bean type 注入
vh.content().getBeanAsync(vh.type(), bean->{ //vh.content() 即 context。在“热插拨”时可能会不同
vh.setValue(bean);
});
} else {
if(anno.value().startsWith("${")) {
//说明是配置注入
String val = vh.content().cfg().getByExpr(anno.value());
vh.setValue(val);
} else {
//说明是 bean name 注入
vh.content().getBeanAsync(anno.value(), bean->{
vh.setValue(bean);
});
}
}
});
2、“类型增强”注入器。魔法的升级!
Solon 内置的注入器,你不喜欢?
想换掉实现行不行?行!完全换掉代码太多,想为特定的类型增加注入行不行?也行!比如,我们设计了一个 EsMapper<T> 用于操作 Elasticsearch。然后可以自由的扩展:
public interface AuthorMapper extends EsMapper<Author> {
}
public interface CommentMapper extends EsMapper<Comment> {
}
public interface ContactMapper extends EsMapper<Contact> {
}
public interface DocumentMapper extends EsMapper<Document> {
}
估计还会想扩展更多的子类?“类型增强” 注入器在手,一切我有。
EsMapperFactory esMapperFactory;
context.beanInjectorAdd(Inject.class, EsMapper.class, (vh, anno) -> {
EsMapper mapper = esMapperFactory.create(vh.getType());
vh.setValue(mapper);
});
可以再借用容器的“缓存”特性,同类型的注入性能就提高了:
EsMapperFactory esMapperFactory;
context.beanInjectorAdd(Inject.class, EsMapper.class, (vh, anno) -> {
EsMapper mapper = vh.context().getBean(vh.getType());
if (mapper == null) {
mapper = esMapperFactory.create(vh.type());
vh.context().wrapAndPut(mapper.getClass(), bean); //有可能被代理了,类型与 vh.getType() 不同
vh.context().wrapAndPut(vh.getType(), bean);
}
vh.setValue(mapper);
});
如果有“多源”的概念,我们还可以支持 @Inject("name"):
EsMapperFactory esMapperFactory;
context.beanInjectorAdd(Inject.class, EsMapper.class, (vh, anno) -> {
EsMapper mapper = null;
if (Utils.isEmpty(anno.value)) {
//按类型取
mapper = vh.context().getBean(vh.getType());
} else {
//按名字取
mapper = vh.context().getBean(anno.value());
}
if (mapper == null) {
mapper = esMapperFactory.create(anno.value(), vh.type());
if (Utils.isEmpty(anno.value)) {
//按类注型注入;就按类型缓存
vh.context().wrapAndPut(mapper.getClass(), bean); //有可能被代理了,类型与 vh.getType() 不同
vh.context().wrapAndPut(vh.getType(), bean);
} else {
//按类名字注入;就按名字缓存
vh.context().wrapAndPut(anno.value(), bean);
}
}
vh.setValue(mapper);
});
现在我们可以用了(吃饭喽,下班喽!):
//主入配置
@Component
public class DemoService{
@Inject
DocumentMapper documentMapper;
@Inject("es2")
DocumentMapper documentMapper2;
}
Solon Ioc 的魔法之注解注入器(也可叫虚空注入器)的更多相关文章
- Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon Ioc 的注解对比Spring及JSR330
注解对比 Solon 1.0.10 Spring JSR 330 @XInject * @Autowired @Inject 字段或参数注入 @XBean * @Component @Named Be ...
- Springboot mini - Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- Spring IOC机制之使用注解配置bean
一. 通过注解配置bean 1.1 概述 相对于XML方式而言,通过注解的方式配置bean更加简洁和优雅,而且和MVC组件化开发的理念十分契合,是开发中常用的使用方式. 1.2 ...
- 阶段3 2.Spring_05.基于XML的IOC的案例1_4 注解IOC案例-把自己编写的类使用注解配置
注解改造案例 复制之前的xml配置的pom.xml里面的依赖. 复制com文件 bean.xml配置文件也拷贝过来 测试类也复制过来 开始基于注解的IOC配置 右键项目,选择maven.选择更新 更新 ...
- Solon 的 PathVariable 不需注解
相对于 Spring boot 的 path variable :Solon 的不需注解,只要变量名对上即可: //path var demo // @XMapping("e/{p_q}/{ ...
- 死磕Spring之IoC篇 - @Autowired 等注解的实现原理
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- 死磕Spring之IoC篇 - @Bean 等注解的实现原理
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- IoC容器-Bean管理注解方式(创建对象)
IoC操作Bean管理(基于注解方式) 1,什么是注解 (1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...) (2)使用注解,注解作用在类上面,方法上面,属性上面 ( ...
- Spring(IOC自动装配-基于注解开发)
Spring IoC 自动装载 autowire: 自动装载是Spring提供的一种更加简单的方式,来完成DI,不需要手动配置property ,IoC容器会自动选择Bean玩成注入. 自动装载俩种: ...
随机推荐
- WPF 使用MediaElement,但Source带https会抛出未引用对象实列
原因和解决办法 如果恰好使用了MediaElement,在调用的时候,会出现空异常 var uri = new Uri("https://xxxx.mp4", UriKind.Re ...
- SeaTunnel DB2 Source Connector 使用文档(含详细操作步骤)
DB2是IBM的一款关系型数据库管理系统,JDBC DB2 Source Connector是一个用于通过JDBC读取外部数据源数据的连接器.Apache SeaTunnel如何支持JDBC DB2 ...
- Spring Boot 框架中配置文件 application.properties 当中的所有配置大全
Spring Boot 框架中配置文件 application.properties 当中的所有配置大全 #SPRING CONFIG(ConfigFileApplicationListener) s ...
- Docker 导出容器 / 镜像
有时由于镜像大小.网络限制等原因,我们不能将本地制作的容器 / 镜像上传到公共容器注册表.此时我们可以选择将镜像以本地文件的形式导出. 导入 / 导出容器 docker export "CO ...
- Docker学习系列3:常用命令之容器命令
本文是Docker学习系列教程中的第三篇.前几篇教程如下: 「图文教程」Windows11下安装Docker Desktop 「填坑」在windows系统下安装Docker Desktop后迁移镜像位 ...
- vscode新建html文件并快速生成标准的html代码
1.打开vscode,点击Open Folder 2.选择目标文件夹,新建一个扩展名为.html的文件: 3.在第一行输入 !(英文状态下),按tab键,新建成功.界面如下图所示:
- sicp每日一题[1.44]
Exercise 1.44 The idea of smoothing a function is an important concept in signal processing. If f is ...
- LeetCode题集-1- 两数之和
这个题目是什么意思呢?简单来说就是在一个数组中找出两个元素,使其和为我们设定的值,并且每个元素只能用一次. 如下图具体示例: 到这里不知道你是否已经有解题思路了呢? 解法一:双层循环 我第一反应就是双 ...
- .NET 9 中 LINQ 新增的功能
LINQ介绍 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称.数据查询历来都表示为简单的字符串,没有编译时类型检查或 IntelliSense 支持.此外,需要针对每种 ...
- webpack笔记-webpack初识与构建工具发展(一)
为什么需要构建工具? 转换 ES6 语法 转换 JSX CSS 前缀补全/预处理器 压缩混淆 图片压缩 前端构建演变之路 ant + YUI Tool grunt gulp.fis3 webpack. ...