使用 EJB 的无状态工厂

Stateless Factory with EJB

我需要从我的系统中获取 pdf 文档。我为此使用 Apache Fop - 这个库使用 2 个文件生成 pdf - 具有结构和样式的 xsl 文件以及 xml 和数据。所以我从网络资源中获取 xsl 文件,但现在我需要使用数据库中的数据生成 xml。我试过这个解决方案: 我有这个界面:

public interface PrintableDocument {
    Object getJaxBOjbect(Long personId);
}

这是获取对象的无状态 bean 之一,我需要 10 个这样的 bean 来为不同的文档获取不同的数据。

@Stateless
@PrintableDocumentOneQualifier
public class PrintableDocumentOne implements PrintableDocument {

    @Inject
    private SomeRepository repository;

    public Object getJaxBOjbect(Long personId) {
    // Getting information from database
    // formulating Object with data and returning it
    }
}

所以现在我想创建这样的工厂:

@Stateless
@LocalBean
public class PrintableDocumentsFactory {

    @Inject
    @PrintableDocumentOneQualifier
    private PrintableDocument printableDocumentOne;

    @Inject
    @PrintableDocumentTwoQualifier
    private PrintableDocument printableDocumentTwo;

    private Map<String, PrintableDocument> map = new HashMap<>();

    @PostConstruct
    public void init() {
        map.put("one", printableDocumentOne);
        map.put("two", printableDocumentTwo);
    }

    public PrintableDocument getPrintableDocument(String type) {
        return map.get(type);
    }

}

我想在服务 bean 上使用这个工厂:

@Stateless
@Local(DocumentService.class)
public class DocumentServiceBean {

    @Inject
    private PrintableDocumentsFactory factory;

    public byte[] getPdf(InputStream xsl, Long id, String type) {
        PrintableDocument printableDocument = 
             factory.getPrintableDocument(type);
        Object jaxBOject = printableDocument.getJaxBObject(id);
        //Use this object to get pdf and return it to web controller.
    }

}

但是现在我从工厂的 getPrintableDocument 中得到了 null。我认为问题在于我需要无状态 bean,当 getPrintableDocument 方法结束时,它们将被挑选回 EJB 容器。所以我的问题是:我该如何处理这种情况?

编辑 1: 在 Factory 的 init 上缺少 PostConstruct 注释。修复了,问题依旧。

编辑 2: 如果我的工厂有 @Singleton,它会只保存一个无状态 PrintableDocument beans 的实例,还是会 return 池实例代替?因为现在我必须在系统需要另一个 been 来回答请求时在 factory 上重新填充 strategy holder map。

尝试向 PrintableDocumentsFactory.init() 方法添加 @PostConstruct 注释。目前 init 方法不会被调用,所以没有在地图中注册。

您可以尝试使用 @EJB 而不是 @InjectPrintableDocumentsFactory 注入您的 DocumentServiceBean