Apache DeltaSpike 配置参数详解

详解 Apache DeltaSpike 配置体系:配置文件位置与加载验证、四类配置源与取值优先级、@ConfigProperty 与 ConfigResolver 用法,以及 Data 模块 JPA 事务配置。

Apache DeltaSpikeApache DeltaSpike2026/10/11

Apache DeltaSpike 配置参数详解

DeltaSpike 的配置能力由 deltaspike-core 提供:把属性文件、系统属性、环境变量、JNDI 统一抽象为配置源(ConfigSource),按优先级解析,并支持 @ConfigProperty 声明式注入与 ConfigResolver 编程式取值。本文中的优先级与覆盖结论均经真实运行验证。

一、配置文件与加载位置

1.1 默认配置文件

DeltaSpike 默认读取类路径下的 META-INF/apache-deltaspike.properties。文件内容即普通 key=value:

app.greeting=Hello DeltaSpike
app.name=Apache DeltaSpike
app.version=1.9.6

1.2 文件位置与生效验证

在 DeltaSpike 1.9.6 上分别验证了多个候选位置,实测结论如下:

文件位置是否生效
META-INF/apache-deltaspike.properties生效(默认)
deltaspike.properties(类路径根)不生效
apache-deltaspike.properties(类路径根)不生效

仅 META-INF/apache-deltaspike.properties 会被加载。启动时日志会打印命中信息:

INFO: Custom config found by DeltaSpike. Name: 'META-INF/apache-deltaspike.properties', URL: 'file:/root/deltaspike-demo/target/classes/META-INF/apache-deltaspike.properties'

二、配置源与取值优先级

2.1 内置配置源与 ordinal

调用 ConfigResolver.getConfigSources() 打印各源,真实回显:

[DeltaSpike] #1 ordinal=400 source=org.apache.deltaspike.core.impl.config.SystemPropertyConfigSource
[DeltaSpike] #2 ordinal=300 source=org.apache.deltaspike.core.impl.config.EnvironmentPropertyConfigSource
[DeltaSpike] #3 ordinal=200 source=org.apache.deltaspike.core.impl.config.LocalJndiConfigSource
[DeltaSpike] #4 ordinal=100 source=org.apache.deltaspike.core.impl.config.PropertyFileConfigSource

ordinal 越大优先级越高,即:

  1. 系统属性(system-properties,400)
  2. 环境变量(environment-properties,300)
  3. JNDI(200)
  4. 属性文件(property-file,100)

2.2 覆盖实验

以 app.greeting 为例,分别在真实环境执行:

实验命令片段取值结果
属性文件默认无额外参数Hello DeltaSpike
系统属性覆盖-Dapp.greeting=SYS_PLAINSYS_PLAIN
环境变量覆盖环境变量 app_greeting=ENV_VALENV_VAL

结论:系统属性与环境变量都能覆盖属性文件;环境变量名由属性键把 . 替换为 _ 得到(app.greeting → app_greeting)。

三、@ConfigProperty 使用详解

3.1 基本注入

在 bean 中对字段使用 @ConfigProperty 声明键名:

import javax.inject.Inject;
import org.apache.deltaspike.core.api.config.ConfigProperty;

@Inject
@ConfigProperty(name = "app.name")
private String name;

键不存在且未提供默认值时,注入结果为 null。

3.2 提供默认值

@Inject
@ConfigProperty(name = "app.greeting", defaultValue = "Hi")
private String greeting;

当 app.greeting 在所有配置源中都不存在时,使用 Hi。实测在缺失该键时输出 app.greeting = Hi。

3.3 与 ConfigResolver 编程式配合

不适合注入的场景可编程取值:

import org.apache.deltaspike.core.api.config.ConfigResolver;

String v = ConfigResolver.getPropertyValue("app.version", "unknown");

getPropertyValue(key) 与 getPropertyValue(key, defaultValue) 两个重载分别返回键值或默认值。实测输出 app.version = 1.9.6。

四、deltaspike 保留命名空间与系统属性前缀

4.1 deltaspike. 前缀

DeltaSpike 自身配置项统一使用 deltaspike. 前缀命名空间,例如 deltaspike.application.name、deltaspike.config.log、deltaspike.bean.isolation.level。这些键可像普通键一样通过系统属性传入,并被 ConfigResolver 读取。实测:

mvn -B -Ddeltaspike.bean.isolation.level=LENIENT exec:java \
  -Dexec.mainClass=com.example.ConfigSourcesApp

回显:

[DeltaSpike] deltaspike.bean.isolation.level = LENIENT

4.2 环境变量前缀形态

由于环境变量名不允许出现 .,环境源在按原名查不到时会把 . 替换为 _ 再查一次。因此 deltaspike. 命名空间下的键,其环境变量形态为 deltaspike_...,例如 deltaspike.application.name 对应环境变量 deltaspike_application_name。

4.3 常见内置配置键

从 deltaspike-core 制品中可提取到的内置键(节选):

配置键说明
deltaspike.application.name应用名
deltaspike.config.log置为 true 时在启动阶段打印全部配置源与已解析值
deltaspike.bean.isolation.levelBean 隔离级别
deltaspike.scope.window.maxWindow 作用域窗口数量上限
deltaspike.mbean.auto / deltaspike.mbean.categoryMBean 自动注册与分类
deltaspike.interdyn.enabled / deltaspike.interdyn.rule动态拦截开关与规则
deltaspike.interceptor.priority拦截器优先级
deltaspike.futureable.termination异步结果终止行为
deltaspike.validation.violation校验违规处理策略

开启配置日志实测:

mvn -B -Ddeltaspike.config.log=true exec:java

回显中会看到 ConfigSources: 与 Configured Values: 明细,便于排查键名与优先级问题。

五、i18n 与 messageResolver

5.1 MessageContext 注入与插值

MessageContext 由 DeltaSpike 生产,可直接注入 bean:

import javax.inject.Inject;
import org.apache.deltaspike.core.api.message.MessageContext;

@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(msg);
}

实测输出:Welcome Apache DeltaSpike, running DeltaSpike 1.9.6。默认插值器按 String.format(%s)风格解析,占位符应使用 %s。

5.2 替换消息解析器 messageResolver

MessageContext 支持替换消息解析器与消息源,以对接自定义国际化资源:

MessageContext ctx = messageContext.clone()
        .messageResolver(myMessageResolver)   // 自定义 MessageResolver
        .messageSource("com.example.messages") // 资源基名
        .localeResolver(myLocaleResolver);
  • messageResolver(MessageResolver):替换默认解析器,用于从自定义载体(数据库、远端配置中心等)取消息模板。
  • messageSource(String...):指定消息资源基名,配合 @MessageBundle 使用。
  • localeResolver(LocaleResolver):指定语言环境解析策略。

六、Data 模块的 JPA 事务与数据源配置

本节为 Data 模块的集成用法参考(基于 DeltaSpike 公开 API),未在本次实验中逐项运行。

6.1 依赖与 @Repository

引入 Data 模块:

<dependency>
  <groupId>org.apache.deltaspike.modules</groupId>
  <artifactId>deltaspike-data-module-api</artifactId>
  <version>1.9.6</version>
</dependency>
<dependency>
  <groupId>org.apache.deltaspike.modules</groupId>
  <artifactId>deltaspike-data-module-impl</artifactId>
  <version>1.9.6</version>
  <scope>runtime</scope>
</dependency>

声明仓储接口,DeltaSpike 会生成实现:

@Repository
public interface UserRepository extends EntityRepository<User, Long> {
    List<User> findByNameLike(String name);
}

6.2 数据源与持久化单元

数据源与持久化单元仍由标准 JPA 机制配置,放在 META-INF/persistence.xml:

<persistence-unit name="demoPU" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
  <properties>
    <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1"/>
    <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
    <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
  </properties>
</persistence-unit>

6.3 事务

  • 受管事务:在 EJB/JTA 环境下由应用服务器事务管理,仓储方法参与 JTA 事务。
  • 非受管(RESOURCE_LOCAL):使用 @Transactional 显式划分事务边界:
import org.apache.deltaspike.jpa.api.transaction.Transactional;

@Transactional
public void createUser(User user) {
    userRepository.save(user);
}

@Transactional 也可通过 deltaspike.jpa.api.transaction.Transactional 的 qualifier 属性指定事务管理器。

七、配置排错

Q1:@ConfigProperty 注入值为 null?

依次检查:配置文件是否位于 META-INF/apache-deltaspike.properties;键名拼写是否一致;是否被更高优先级源覆盖。必要时用 -Ddeltaspike.config.log=true 打印全部配置源。

Q2:系统属性为什么不生效?

exec:java 与直接 java -Dkey=value 场景下,系统属性都属最高优先级源;若使用 -Dfoo 却读取 bar,则是键名不匹配,而非优先级问题。

Q3:环境变量配置不生效?

确认变量名由键名的 . 替换为 _ 得到,且未被同名系统属性或属性文件以外的更高优先级源覆盖。

Q4:如何限制 JVM 堆以节省资源?

构建或运行示例时可设置 MAVEN_OPTS="-Xms256m -Xmx512m"。