使用 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
而不是 @Inject
将 PrintableDocumentsFactory
注入您的 DocumentServiceBean
。
我需要从我的系统中获取 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
而不是 @Inject
将 PrintableDocumentsFactory
注入您的 DocumentServiceBean
。