Apache DeltaSpike 快速入门与集成示例

Apache DeltaSpike 快速入门:从环境准备到第一个可运行 CDI 程序,覆盖配置注入、国际化与运行时引导,并给出 Weld SE、Java EE 与 Spring Boot 集成示例与运行输出。

Apache DeltaSpikeApache DeltaSpike2026/10/11

Apache DeltaSpike 快速入门与集成示例

DeltaSpike 是一组可移植的 CDI 扩展库,为 Java EE / Jakarta EE 应用补充配置、国际化、仓储、调度等能力。本文先给出在独立服务器上可跑通的第一个示例,再给出 Weld SE、Java EE 与 Spring Boot 三类集成方式。

一、环境准备

项目要求
操作系统Ubuntu 22.04 / CentOS 8 等 Linux
JDK8 或 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。