Apache DeltaSpike 快速入门与集成示例
Apache DeltaSpike 快速入门:从环境准备到第一个可运行 CDI 程序,覆盖配置注入、国际化与运行时引导,并给出 Weld SE、Java EE 与 Spring Boot 集成示例与运行输出。
Apache DeltaSpike 快速入门与集成示例
DeltaSpike 是一组可移植的 CDI 扩展库,为 Java EE / Jakarta EE 应用补充配置、国际化、仓储、调度等能力。本文先给出在独立服务器上可跑通的第一个示例,再给出 Weld SE、Java EE 与 Spring Boot 三类集成方式。
一、环境准备
| 项目 | 要求 |
|---|---|
| 操作系统 | Ubuntu 22.04 / CentOS 8 等 Linux |
| JDK | 8 或 11 |
| 构建工具 | Maven 3.5+ |
| 网络 | 可访问 Maven Central |
安装 JDK 与 Maven(以 Ubuntu 22.04 为例):
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-11-jdk maven
java -version
mvn -version
真实回显:
openjdk version "11.0.32.1" 2026-08-18
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.32.1, vendor: Ubuntu
二、第一个 DeltaSpike 程序
2.1 工程结构
deltaspike-demo/
├── pom.xml
└── src/main
├── java/com/example/{App,GreetingService,I18nService}.java
└── resources/META-INF/{beans.xml,apache-deltaspike.properties}
2.2 Maven 依赖
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<deltaspike.version>1.9.6</deltaspike.version>
<weld.version>3.1.9.Final</weld.version>
<exec.mainClass>com.example.App</exec.mainClass>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-api</artifactId>
<version>${deltaspike.version}</version>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-impl</artifactId>
<version>${deltaspike.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.cdictrl</groupId>
<artifactId>deltaspike-cdictrl-weld</artifactId>
<version>${deltaspike.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>${weld.version}</version>
</dependency>
</dependencies>
2.3 配置与代码
META-INF/beans.xml:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2.0.xsd"
bean-discovery-mode="all" version="2.0"/>
META-INF/apache-deltaspike.properties:
app.greeting=Hello DeltaSpike
app.name=Apache DeltaSpike
app.version=1.9.6
GreetingService.java:
package com.example;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.deltaspike.core.api.config.ConfigProperty;
import org.apache.deltaspike.core.api.config.ConfigResolver;
@Named
public class GreetingService {
@Inject
@ConfigProperty(name = "app.greeting", defaultValue = "Hi")
private String greeting;
@Inject
@ConfigProperty(name = "app.name")
private String name;
public void run() {
System.out.println("[DeltaSpike] app.greeting = " + greeting);
System.out.println("[DeltaSpike] app.name = " + name);
System.out.println("[DeltaSpike] ConfigResolver app.version = "
+ ConfigResolver.getPropertyValue("app.version", "unknown"));
System.out.println("[DeltaSpike] message = " + greeting + ", " + name + "!");
}
}
I18nService.java:
package com.example;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.deltaspike.core.api.message.MessageContext;
@Named
public class I18nService {
@Inject
private MessageContext messageContext;
public void run() {
String msg = messageContext.message()
.template("Welcome %s, running DeltaSpike %s")
.argument("Apache DeltaSpike").argument("1.9.6")
.toString();
System.out.println("[DeltaSpike i18n] " + msg);
}
}
App.java:
package com.example;
import org.apache.deltaspike.core.api.provider.BeanProvider;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
public class App {
public static void main(String[] args) {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
try {
BeanProvider.getContextualReference(GreetingService.class).run();
BeanProvider.getContextualReference(I18nService.class).run();
} finally {
container.shutdown();
}
}
}
2.4 运行输出
cd /root/deltaspike-demo
mvn -q -B compile
mvn -B exec:java
真实回显(节选):
INFO: Custom config found by DeltaSpike. Name: 'META-INF/apache-deltaspike.properties', URL: 'file:/root/deltaspike-demo/target/classes/META-INF/apache-deltaspike.properties'
INFO: WELD-ENV-002003: Weld SE container ... initialized
[DeltaSpike] app.greeting = Hello DeltaSpike
[DeltaSpike] app.name = Apache DeltaSpike
[DeltaSpike] ConfigResolver app.version = 1.9.6
[DeltaSpike] message = Hello DeltaSpike, Apache DeltaSpike!
[DeltaSpike i18n] Welcome Apache DeltaSpike, running DeltaSpike 1.9.6
INFO: WELD-ENV-002001: Weld SE container ... shut down
[INFO] BUILD SUCCESS
2.5 代码解读
beans.xml开启 bean 发现,DeltaSpike 扩展随deltaspike-core-impl自动注册。@Inject @ConfigProperty(name="app.greeting")从META-INF/apache-deltaspike.properties按优先级取值,缺失时用defaultValue。ConfigResolver.getPropertyValue展示编程式取值。MessageContext由 DeltaSpike 注入,%s占位符由默认插值器替换。BeanProvider.getContextualReference在非注入点获取 bean;Weld负责运行时生命周期。
三、集成示例一:Weld SE 应用
Weld SE 用于无 Servlet 运行环境场景(命令行工具、批处理、测试)。除 Weld().initialize() 外,也可用 DeltaSpike 统一引导 API:
package com.example;
import org.apache.deltaspike.cdise.api.CdiContainer;
import org.apache.deltaspike.cdise.api.CdiContainerLoader;
import org.apache.deltaspike.core.api.provider.BeanProvider;
public class BootstrapApp {
public static void main(String[] args) {
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
try {
System.out.println("[DeltaSpike] CdiContainer impl = "
+ cdiContainer.getClass().getName());
BeanProvider.getContextualReference(GreetingService.class).run();
} finally {
cdiContainer.shutdown();
}
}
}
运行:
mvn -B exec:java -Dexec.mainClass=com.example.BootstrapApp
真实回显:
[DeltaSpike] CdiContainer impl = org.apache.deltaspike.cdise.weld.WeldContainerControl
[DeltaSpike] app.greeting = Hello DeltaSpike
[INFO] BUILD SUCCESS
四、集成示例二:Java EE / Jakarta EE 应用
本节为集成方式说明(示例代码与依赖),未在本次实验中部署到完整应用服务器运行。
在 Java EE 7/8 应用服务器(提供 CDI 1.1/2.0)中,只需把 DeltaSpike 依赖打入 WEB-INF/lib,无需手工引导 CDI 运行时。pom.xml 依赖:
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-api</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-impl</artifactId>
<version>1.9.6</version>
<scope>runtime</scope>
</dependency>
资源仍放在 WEB-INF/classes/META-INF/apache-deltaspike.properties。此时应用服务器已托管 CDI,直接 @Inject 使用 DeltaSpike 能力,无需 Weld 或 CdiContainerLoader:
@Named
public class GreetingService {
@Inject
@ConfigProperty(name = "app.name", defaultValue = "DeltaSpike")
private String name;
public String greet() {
return "Hello, " + name;
}
}
五、集成示例三:Spring Boot 应用
本节为集成方式说明(示例代码与依赖),未在本次实验中运行。
Spring 自身不提供 CDI,若要在 Spring Boot 中复用 DeltaSpike 的配置/国际化能力,可在应用启动时以 Weld SE 内嵌方式一并引导 CDI 运行时。依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-api</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-impl</artifactId>
<version>1.9.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.1.9.Final</version>
</dependency>
将 CDI 运行时作为一个 Spring Bean 托管生命周期:
package com.example;
import javax.annotation.PreDestroy;
import org.apache.deltaspike.core.api.provider.BeanProvider;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringBootApp {
private WeldContainer container;
@Bean
public WeldContainer cdiContainer() {
this.container = new Weld().initialize();
return this.container;
}
@Bean
public String runGreeting() {
BeanProvider.getContextualReference(GreetingService.class).run();
return "started";
}
@PreDestroy
public void shutdown() {
if (container != null) {
container.shutdown();
}
}
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
启动后,DeltaSpike 会在 Spring Boot 进程内读取 META-INF/apache-deltaspike.properties 并完成 @ConfigProperty 注入。为节省资源,可通过 java -Xmx512m -jar app.jar 限定堆内存。
六、常见问题
Q1:运行时报 Unable to locate CDI provider?
缺少 CDI 实现。纯 SE 场景需引入 weld-se-core 或 deltaspike-cdictrl-* 对应实现。
Q2:@ConfigProperty 未取到值?
确认配置文件为 META-INF/apache-deltaspike.properties 且在运行时 classpath 中;可用 -Ddeltaspike.config.log=true 打印配置源与已解析值。
Q3:MessageContext 模板占位符未替换?
默认插值器使用 String.format 风格,占位符应写 %s,而非 {0}。
Q4:如何控制内存占用?
构建用 MAVEN_OPTS="-Xms256m -Xmx512m",运行用 java -Xms256m -Xmx512m,堆内存保持在 256–512MB。