复杂豆映射

2022-09-04 22:55:51

我试图为我在映射一个简单的bean结构时遇到的问题找到最佳解决方案,该结构被发送到基于浏览器的JavaScript应用程序。当前要求是管理旧 Java 后端上的大部分显示控件。目前,我们有一个服务样式层,它正在生成价值对象,其中没有内置显示逻辑,例如:

public class Example1 {
    String value1;
    Boolean value2;
    Example3 value3;

    public String getValue1(){...}
    public void setValue1(){...}
    ....
 }

我的目标是能够在所有字段上映射通用结构,以便添加前端所需的新显示结构。我只想管理原始结构类(Example1类)结构,只需将包装器中的额外值设置为旧的服务层。

泛型结构将采用以下类的形式:

public class Presentable<T> {
    T value;
    boolean visible = true; 
    boolean mandatory = false;
    List<String> errors = new ArrayList<>();

    public T getValue() {...}
    public void setValue(T value) {...}
    ...
}

最终结果将如下所示,其中值等于原始结构中的值:

public class Example2{
    Presentable<String> value1;
    Presentable<Boolean> value2;
    Presentable<Example3> value3;

    public Presentable<String> getValue1(){...}
    public void setValue1(){...}
    ...
}

在没有编写 Example2 样式类并复制每个值的情况下,是否有解决此问题的方法?我愿意修改 Example1 类,因为它不会影响旧服务的使用者。

谢谢。


答案 1

你可以将AOP(面向方面编程)与Spring一起使用。在春季,您可以创建一个代理对象,其中包含您需要的额外信息。好的起点是:http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/

面向方面的编程的官方页面:http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html

此示例/答案可能很有用:仅使用注释的Spring AOP拦截方法


答案 2

所以我不确定我是否正确地理解了你。然而。。。

这是一个我们可以非常容易地使用反射的地方。

对于我们的类 Example1.class我们调用 getDeclaredMethods,getDeclaredFields(在简单用例中)或 getMethods,getFields 在更复杂的(简单的 pojo 但有继承)。您可能需要一些简单的逻辑,例如使用修饰符或类似的东西删除字段。static

对于每个方法/字段,我们从示例2中获得适当的方法/字段.class使用getMethod(字符串名称)或getField(字符串名称)

并通过字段或 setter 将我们的值设置为新对象。如果修饰符(如 private)存在问题,我们使用 setAccessible。

一些简单用例的代码:

public Example2 decorateWithWrapper(Example1 obj) {
    Example2 wrapped = new Example2();
    for (Field field : obj.getClass().getDeclaredFields()) {
        Field toAssign = wrapped.getClass().getField(field.getName());
        toAssign.setAccessible(true);
        toAssign.set(wrapped, field.get(obj));
    }
    return wrapped;
}

如果需要,很容易从上面做更多的通用方法。

您不需要任何外部库或工具。


推荐