HK2使用详解

2024-01-02 21:18
文章标签 使用 详解 hk2

本文主要是介绍HK2使用详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • HK2介绍
  • 组件
  • 生命周期
  • 定义服务
  • 注入服务
HK2介绍

HK2是一个轻量级动态依赖注入框架,它是JSR-330的实现。

组件

在HK2组件模型中,一个组件的功能是通过服务接口-服务实现的模式声明的。一个HK2服务接口 标识并描述了一个构建模块或者应用程序扩展点。HK2服务实现实现了HK2服务接口。

组件模型

(HK2)提供了一个模块系统和组件模型来建立复杂的软件系统。该模块系统负责实例化构成应用程序功能的类。HK2运行时通过创建对象来填充该模块系统。模块系统通过以下方式装配对象:

  • 实例化一个新的对象注入到需要这个对象的对象中。
  • 为这个对象注入所需的配置信息。
  • 使新建的对象可用,这样这些对象就可以注入到其他需要这些对象的对象中。
服务

一个HK2服务(服务接口)标识并描述了一个构建模块或者应用程序扩展点。服务是一个普通的Java对象(POJO)具有以下特点:

  • 该对象(类)实现了一个接口
  • 对象(类)应该在JAR的META-INF/services文件中声明
作用范围

@Singleton

生命周期

组件可以在初始化和销毁事件发生过程中,添加切面逻辑,实现接口:org.jvnet.hk2.component.PostConstruct 和 org.jvnet.hk2.component.PreDestroy。

实现接口还是使用注解,可以根据性能决定。

PostConstruct.postConstruct() :这个方法在组件初始化并且组件的依赖被注入后调用。 PreDestroy.preDestroy() :这个方法在组件从系统移除前调用。

@Service(name="")
public class MyContainer implements Container, PostConstruct, PreDestroy {
@Inject
Logger logger;
...
public void postConstruct() {
logger.info("Starting up.");
}
public void preDestroy() {
logger.info("Shutting down.");
}
}
定义服务
默认实现
//默认只有一种实现的情况,接口定义:
@Contract
public interface Foo {
}
//具体业务在实现类中
@Service
public class FooImpl implements Foo {
}
服务命名
//为了区分相同的接口的不同实现,你可以给你的服务命名。如下例子:
@Contract
public interface Book {
}
@Service @Named
public class Moby implements Book {
}
@Service @Named
public class ParadiseLost implements Book {
}
限定服务
//服务也可以被注解限定调用。这个注解需要标注@Qualifier注解,看例子:
@Contract
public interface Color {
}
@Service @Blue
public class BlueColor implements Color {
}
@Service @Red
public class RedColor implements Color {
}
//Blue注解的实现
@Qualifier
@Retention(RUNTIME)
@Target( { TYPE, METHOD, FIELD, PARAMETER })
public @interface Blue {
}
注入服务
基础注入
//作为成员变量注入:
@Inject
ConfigService config;
//setter上注入
@Inject
public void set(ConfigService config) {...}
//也可通过构造函数注入
@Service
public class FooImpl implements Foo {
private final Book book;
@Inject
public FooImpl(Book book) {
// constructor injected!
this.book = book;
}
}
名称注入(Injection by name)
//需要给服务命名,然后通过名称才能注入,看例子:
@Service
public class FooImpl implements Foo {
@Inject @Named("Moby")
private Book mobyDick;
@Inject @Named("ParadiseLost")
private Book paradiseLost;
}
限定注入(Injection by qualifier)
//限定服务,按照以下方式注入,看例子:
@Service
public class ColorMixer {
private Color red;
private Color blue;
@Inject
private void addPrimaries(@Red Color red, @Blue Color blue) {
this.red = red;
this.blue = blue;
}
}
Provider注入

很多情况下,注入一个服务的Provider要比注入服务本身要好,因为系统可能延时创建服务,直到Provider的get方法被调用。

@Service
public class ColorMixer {
@Inject @Red
private Provider<Color> redProvider;
@Inject @Blue
private Provider<Color> blueProvider;
}
//服务中可以在需要时再调用
@Service
public class ColorMixer {
...
public Color makePurple() {
return mix(redProvider.get(), blueProvider.get());
}
}
IterableProvider注入

通常情况下,一个contract会有多个实现,如果要访问所有的实现,就需要使用IterableProvider。

@Service
public class Library {
@Inject
private IterableProvider<Book> allBooks;
public LinkedList<Book> getAllBooks() {
LinkedList<Book> retVal = new LinkedList<Book>();
for (Book book : allBooks) {
retVal.add(book);
}
return retVal;
}
}
//另外一个特性,我们可以使用named获取一个特定的实现。
@Service
public class Library {
@Inject
private IterableProvider<Book> allBooks;
public Book findBook(String name) {
return allBooks.named(name).get();
}
}
Iterable注入

Iterable can be used as an injection point rather than IterableProvider.

@Service
public class Library {
@Inject
private Iterable<Book> allBooks;
public LinkedList<Book> getAllBooks() {
LinkedList<Book> retVal = new LinkedList<Book>();
for (Book book : allBooks) {
retVal.add(book);
}
return retVal;
}
}

总结

如果对底层实现感兴趣,不如去看看这个kunJ,当然,给个star也是极好的。

这篇关于HK2使用详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/563672

相关文章

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行