有没有办法将依赖项传递给JPA转换器?

时间:2015-04-28 14:10:11

标签: java jpa

我有一个需要使用少量依赖项的自定义转换器。

由于转换器是由JPA管理的,因此我无法找到从其他组件(如依赖注入器)传递依赖关系的方法。有这样的方式吗?

@Converter
public class CompressingJsonConverter implements AttributeConverter<CompressedJson, Byte[]> {

    private final Compressing compressing;
    private final ObjectMapper objectMapper;

    public CompressingJsonConverter() {
        // I would like to inject those dependencies instead
        compressing = new Compressing();
        objectMapper = new ObjectMapper();
    }

3 个答案:

答案 0 :(得分:0)

尝试使用静态字段。您的DI框架支持静态注入(我知道Guice和Salta会这样做),或者您必须在启动时手动完成。考虑在实用程序类中注册Injector(Guice,Salta)或Instance(JavaEE / CDI),并在任何需要的地方使用它。

答案 1 :(得分:0)

您可以尝试将实用程序类用作单例。从你的问题来看,我想你有一些依赖注入系统。

如果您可以确保在转换器类使用它之前完全初始化实用程序对象,并且如果您的DI系统允许在注入后调用初始化方法(Spring确实如此),您可以使用以下内容:

class Util {
    @Inject // or whatever you use for injection
    private Compressing compressing;
    @Inject // or whatever you use for injection
    private ObjectMapper objectMapper;
    // getters and setters omitted for brevity

    private static Util instance;
    public Util getInstance() {
        return instance;
    }

    // DI initialization method after attributes have been injected
    public void init() {
        instance = this;
    }
}

然后您可以在转换器中执行此操作:

@Converter
public class CompressingJsonConverter implements
        AttributeConverter<CompressedJson, Byte[]> {

    private Compressing compressing = null;
    private ObjectMapper objectMapper = null;

    private Compressing getCompressing() {
        if (compressing == null) {
            // load it first time from util, then caches it locally
            compressing = Util.getInstance().getCompressing();
        }
        return compressing;
    }
    // same for objectMapper
    ...
}

并始终在转化器中使用getCompressing()getObjectMapper

如果您确定在Util实例完全初始化之前永远不会构造转换器,您可以在构造函数中进行初始化:

public CompressingJsonConverter() {
    // I would like to inject those dependencies instead
    compressing = Util.getInstance().getCompressing();
    objectMapper = Util.getInstance().getObjectMapper();
}

但请务必仔细检查它是否有效并以红色闪烁字体记录,因为它可能会破坏任何组件的每个新版本(DI,JPA,Java等)

答案 2 :(得分:0)

这取决于您的两个物体生活在哪个世界:

  • 如果两者都是由CID创建的,那么仅使用javax.inject就不会有任何问题。
  • 如果使用不同的DI框架(例如GUICE)创建一个,则需要编写一些粘合代码来连接它们。

在我的一个项目中使用的一种这样的技术是创建一个像这样的类:

// create a new class
class Bridge { @Inject public static ObjectMapper objectMapper; }

// in GUICE module 
requestStaticInjection(Bridge.class)

// in Convertor 
class MyConvertor {

  private ObjectMapper objectMapper;

  public MyConvertor(){
    this.objectMapper = Bridge.objectMapper;
  }
}