sle*_*ske 3 spring jpa weld jakarta-ee
在 Spring 中,我可以javax.persistence.EntityManager
使用 annotation将 an 注入到 Spring bean 中@javax.persistence.PersistenceContext,如下所示:
@Service
public class MyRepository {
@PersistenceContext
private EntityManager entityManager;
}
Run Code Online (Sandbox Code Playgroud)
这在 Spring 文档的第20.5.2章实现基于普通 JPA 的 DAO 中有所记录。
如果我不使用 Java EE 容器,有没有办法使用 CDI(特别是 Weld)来做到这一点?
特别是,是否可以重用@PersistenceContextCDI的注释(因为现有代码将它与 Spring 一起使用)?
据我了解:使用 Java EE 容器时,容器会解释注解并注入 EntityManager。那是对的吗?有没有办法在没有 Java EE 容器的情况下使用 Weld 使其工作?
我尝试使用 Weld(在 Tomcat 中,没有 Java EE)将上面的类注入到另一个类中。发生了注入,因此 Weld 正确创建了 的实例MyRepository,但是字段MyRepository.entityManager是null,就好像注释@PersistenceContext被忽略了一样。
这里发生了什么(或者更确切地说,没有发生)?
你可以这样做:创建实体管理器工厂生产者
public class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
public EntityManagerFactory create() {
return Persistence.createEntityManagerFactory("PU");
}
public void destroy(@Disposes EntityManagerFactory factory) {
factory.close();
}
}
Run Code Online (Sandbox Code Playgroud)
并创建实体管理器生产者
public class EntityManagerProducer {
@Inject
transient EntityManagerFactory emf;
@Produces
@RequestScoped
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(@Disposes EntityManager em) {
em.close();
}
}
Run Code Online (Sandbox Code Playgroud)
那么你可以使用依赖注入(CDI 将为每个请求创建一个 em)
@Inject
EntityManager entityManager;
Run Code Online (Sandbox Code Playgroud)
您必须在主方法中启动 CDI 上下文
public static void main(String[] args) throws IOException {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Application application = container.instance().select(Application.class).get();
application.run();
weld.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
附:如果您有多个 PU,请使用 @Qualifier
虽然 MilkMaid 的答案是一个不错的方法,但我只想添加一些更多的幕后提示。
如果我不使用 Java EE 容器,有没有办法使用 CDI(特别是 Weld)来执行此操作?
简短的回答 - 有。Weld 可以允许在您希望可注入的任何对象旁边注入,但是您需要注意谁拥有/管理该对象。在你的例子中,它是EntityManager来自 JPA 的东西,所以猜猜看 - JPA 管理此类对象的生命周期。因此,您需要为此类对象创建一个“包装器”(实际上它是一个代理),该对象将由 CDI/Weld 处理。这就是你需要制作人的原因。
就好像注释 @PersistenceContext 被忽略一样。
确实,它被忽略了。这是所发生情况的简化。通常,在 EE 容器中,Weld 会使注入发生,但其背后真正的魔力不是 Weld 核心代码,而是 EE 服务器端的集成(采用 Weld SPI 来处理此类注释并将其转换为 bean)然后注入)。
一般来说,尝试在 EE 容器外部处理“EE 内容”可能会很棘手,因为您会遇到许多最初发生在容器内部的集成,但现在您需要自己处理。
从技术上讲,人们可能可以@PersistenceContext通过编写CDI 扩展来使注释起作用。然而,这是一种令人讨厌的 hack,而不是其他任何东西——人们会为了 SE 使用而改变 EE-only 注释。我建议不要这么做,但如果你仍然想这样做,那么基本上就是让 CDI 认为 @PersistanceContext 是另一个 @Inject 并提供生产者。这意味着大量的手动工作,CDI 中没有内置机制来为您处理这些工作 - 这通常是 EE 服务器的责任。
| 归档时间: |
|
| 查看次数: |
3575 次 |
| 最近记录: |