You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Quarkus中使用SpEL(或其他表达式语言)实现对象转换

在Quarkus中用表达式语言处理对象转换(支持GraalVM)

一、轻量集成SpEL的方案

Quarkus提供了对Spring核心模块的扩展支持,不用引入全量Spring就能用SpEL,完全满足基础对象转换需求:

  • 添加依赖
    直接在pom.xml里引入Spring核心扩展:
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-spring-core</artifactId>
</dependency>

Gradle用户对应在build.gradle里添加implementation 'io.quarkus:quarkus-spring-core'

  • 封装SpEL转换器
    创建一个应用级的Bean来封装SpEL的解析逻辑,方便复用:
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class SpelObjectConverter {
    private final ExpressionParser parser = new SpelExpressionParser();

    public <T> T convert(Object source, String spelExpr, Class<T> targetType) {
        Expression expression = parser.parseExpression(spelExpr);
        return expression.getValue(source, targetType);
    }
}
  • 实际使用示例
    比如把User对象转成UserDto,直接注入转换器后用SpEL表达式描述转换逻辑:
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/convert")
public class ConvertResource {
    @Inject
    SpelObjectConverter converter;

    @GET
    public UserDto convertUser() {
        User user = new User("Johnny", 30);
        // 用SpEL直接构造DTO,支持属性提取、方法调用等
        return converter.convert(user, "new com.example.UserDto(name, age)", UserDto.class);
    }
}
  • GraalVM适配注意
    • 确保Quarkus版本在2.10以上,这个版本对Spring扩展的原生镜像支持更稳定
    • 如果转换逻辑用到自定义类的构造、字段或方法,需要添加反射配置。在src/main/resources/native-image.properties里加:
      quarkus.native.additional-build-args=--reflect-config-file=reflect-config.json
      
    然后在reflect-config.json里配置需要反射的类:
    [
      {
        "name": "com.example.User",
        "allPublicFields": true,
        "allDeclaredConstructors": true
      },
      {
        "name": "com.example.UserDto",
        "allPublicFields": true,
        "allDeclaredConstructors": true
      }
    ]
    

二、Quarkus原生EL替代方案

如果不想依赖Spring相关组件,Quarkus自带的EL 3.0扩展更轻量,而且原生支持GraalVM:

  • 添加依赖
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-el</artifactId>
</dependency>
  • 封装EL转换器
import jakarta.el.ExpressionFactory;
import jakarta.el.ValueExpression;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.el.StandardELContext;

@ApplicationScoped
public class ElObjectConverter {
    private final ExpressionFactory exprFactory = ExpressionFactory.newInstance();

    public <T> T convert(Object source, String elExpr, Class<T> targetType) {
        StandardELContext context = new StandardELContext(exprFactory);
        // 把源对象设为EL上下文里的变量,方便表达式引用
        context.getVariableMapper().setVariable("source", exprFactory.createValueExpression(source, source.getClass()));
        ValueExpression expression = exprFactory.createValueExpression(context, elExpr, targetType);
        return targetType.cast(expression.getValue(context));
    }
}
  • 使用示例
@Path("/el-convert")
public class ElConvertResource {
    @Inject
    ElObjectConverter converter;

    @GET
    public UserDto convertUser() {
        User user = new User("Johnny", 30);
        // 通过source变量访问原对象属性,构造DTO
        return converter.convert(user, "new com.example.UserDto(source.name, source.age)", UserDto.class);
    }
}
  • GraalVM适配
    这个扩展原生支持GraalVM,只要你的自定义类能被Quarkus的构建工具扫描到,基本不用额外配置,测试时直接用quarkus build --native构建镜像验证即可。

三、避免冗余的实用技巧

  • 只引入所需的轻量依赖,别用全量Spring或Camel,避免不必要的包体积和复杂度
  • 可以把转换表达式抽离到配置文件中,用@ConfigProperty注入,方便统一管理:
    @ConfigProperty(name = "conversion.user-to-dto")
    String userToDtoExpr;
    
    // 使用时直接传入表达式
    converter.convert(user, userToDtoExpr, UserDto.class);
    
  • 原生镜像构建前,先在JVM模式下测试转换逻辑,确保表达式正确,再构建原生镜像排查兼容性问题

内容的提问来源于stack exchange,提问作者Johnny Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:10:21