欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
关于依赖注入
- 对一名java程序员来说,依赖注入应该是个熟悉的概念,简单的说就是:我要用XXX,但我不负责XXX的生产
- 以下代码来自spring官方,serve方法要使用MyComponent类的doWork方法,但是不负责MyComponent对象的实例化,只要用注解Autowired修饰成员变量myComponent,spring环境会负责为myComponent赋值一个实例
@Service
public class MyService {
@Autowired
MyComponent myComponent;
public String serve() {
myComponent.doWork();
return "success";
}
}
- 关于依赖注入,网上有很多优秀文章,这里就不展开了,咱们要关注的是quarkus框架的依赖注入
关于《quarkus依赖注入》系列
-
《quarkus依赖注入》共六篇文章,整体规划上隶属于《quarkus实战》系列,但专注于依赖注入的知识点和实战
-
如果您熟悉spring的依赖注入,那么阅读本系列时会发现quarkus与spring之间有太多相似之处,很多地方一看就懂
本篇概览
- 作为《quarkus依赖注入》的开篇,本文先介绍CDI,再学习如何创建bean实例,全文内容如下
graph LR L1(本篇内容) --> L2-1(官方提醒) L1 --> L2-2(CDI) L1 --> L2-3(创建bean) L2-2 --> L3-1(关于CDI) L2-2 --> L3-2(关于bean) L2-3 --> L3-3(注解修饰在类上) L2-3 --> L3-4(注解修饰在方法上) L2-3 --> L3-5(注解修饰在成员变量上) L2-3 --> L3-6(扩展组件中的synthetic bean)
- 学习quarkus的依赖注入之前,来自官方的提醒非常重要
官方提醒
- 在使用依赖注入的时候,quankus官方建议不要使用私有变量(用默认可见性,即相同package内可见),因为GraalVM将应用制作成二进制可执行文件时,编译器名为Substrate VM,操作私有变量需要用到反射,而GraalVM使用反射的限制,导致静态编译的文件体积增大
Quarkus is designed with Substrate VM in mind. For this reason, we encourage you to use *package-private* scope instead of *private*.
关于CDI
- 《 Contexts and Dependency Injection for Java 2.0》,简称CDI,该规范是对JSR-346的更新,quarkus对依赖注入的支持就是基于此规范实现的
- 从 2.0 版开始,CDI 面向 Java SE 和 Jakarta EE 平台,Java SE 中的 CDI 和 Jakarta EE 容器中的 CDI 共享core CDI 中定义的特性。
- 简单看下CDI规范的内容(请原谅欣宸的英语水平):
- 该规范定义了一组强大的补充服务,有助于改进应用程序代码的结构
- 给有状态对象定义了生命周期,这些对象会绑定到上下文,上下文是可扩展的
- 复杂的、安全的依赖注入机制,还有开发和部署阶段选择依赖的能力
- 与Expression Language (EL)集成
- 装饰注入对象的能力(个人想到了AOP,你拿到的对象其实是个代理)
- 拦截器与对象关联的能力
- 事件通知模型
- web会话上下文
- 一个SPI:允许便携式扩展与容器的集成(integrate cleanly )
关于CDI的bean
- CDI的实现(如quarkus),允许对象做这些事情:
-
绑定到生命周期上下文
-
注入
-
与拦截器和装饰器关联
-
通过触发和观察事件,以松散耦合的方式交互
-
上述场景的对象统称为bean,上下文中的 bean 实例称为上下文实例,上下文实例可以通过依赖注入服务注入到其他对象中
-
关于CDI的背景知识就介绍到这里吧,接下来要写代码了
源码下载
- 本篇实战的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos)
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本次实战的源码在quarkus-tutorials文件夹下,如下图红框
- quarkus-tutorials是个父工程,里面有多个module,本篇实战的module是basic-di,如下图红框
创建demo工程
- 您可以参考《quarkus实战之二:应用的创建、构建、部署》,创建个最简单的web工程,默认生成一个web服务类HobbyResource.java,代码如下,后面的演示代码都写在这个工程中
package com.bolingcavalry;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.time.LocalDateTime;
@Path("/actions")
public class HobbyResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy, " + LocalDateTime.now();
}
}
- 接下来,从最基础的创建bean实例创建开始
创建bean实例:注解修饰在类上
- 先来看看spring是如何创建bean实例的,回顾文章刚开始的那段代码,myComponent对象来自哪里?
- 继续看spring官方的demo,如下所示,用Component注解修饰在类上,spring就会实例化MyComponent对象并注册在bean容器中,需要用此bean的时候用Autowired注解就可以注入了
@Component
public class MyComponent {
public void doWork() {}
}
- quarkus框架下也有类似方式,演示类ClassAnnotationBean.java如下,用注解ApplicationScoped去修饰ClassAnnotationBean.类,如此quarkus