我正在從 Hibernate 實作一個 EmptyInterceptor 來審核資料庫更改。
問題是所有注入的依賴項(@Inject)都是 null,在攔截器內部以及在攔截器執行中使用 new() 運算子實體化的任何其他類內部。
我看到另一個同樣問題的問題,但是使用 Spring 框架,該框架通過使攔截器成為一個 bean,然后 CDI 可以向它注入所有依賴項來解決問題。
我想使用我的 DAO 和物體管理器來持久化這些新的審計物體,有沒有辦法讓 WELD/CDI 在攔截器中注入我的依賴項?
使用 Wildfly 17、CDI 2.0
歷史攔截器
@Interceptor
@Historico
public class HistoricoInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 6271759158996755175L;
@Inject
@Any
private Instance<HistoricoInterceptadorI> historicoInterceptadorI;
@Inject
private RequestQueryParamExtractor requestQueryParamExtractor;
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[]
propertyNames,
Type[] types) {}
豆類.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
version="2.0" bean-discovery-mode="all">
<interceptors <class>br.com.procempa.tesouro.pessoaapi.util.interceptor.HistoricoInterceptor</class>
</interceptors>
請求查詢引數提取器
@RequestScoped
public class RequestQueryParamExtractor {
private static final String LOTACAO_PARAM = "lotacaoId";
private static final String LOGIN_PARAM = "nomeLogin";
@Inject
private HttpServletRequest httpServletRequest;
public Optional<String> getLotacaoId() {
String lotacaoId = httpServletRequest.getParameter(LOTACAO_PARAM);
return Optional.ofNullable(lotacaoId);
}
public Optional<String> getNomeLogin() {
String nomeLogin = httpServletRequest.getParameter(LOGIN_PARAM);
return Optional.ofNullable(nomeLogin);
}
}
持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="primary">
<jta-data-source>java:jboss/datasources/pessoaDSHom</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.SQL" value="DEBUG"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.default_schema" value="poasiat" />
<property name="hibernate.jpa.compliance.global_id_generators"
value="false"/>
<property name="hibernate.session_factory.interceptor"
value="br.com.procempa.tesouro.pessoaapi.util.interceptor.HistoricoInterceptor"/>
</properties>
</persistence-unit>
</persistence>
uj5u.com熱心網友回復:
攔截器是 Hibernate 攔截器,而不是 CDI 攔截器。這并沒有錯,只需注意名稱“攔截器”在此背景關系中被多載(CDI 也使用具有不同 FQCN 的攔截器)。
現在,從 CDI 的角度來看,Hibernate 攔截器是一個非背景關系物件,因此不會由 CDI 處理。這意味著,除其他外,沒有注射。
您可以通過執行動態決議來獲取您的 bean 來解決此問題:
// invoke this from within a method where you want to use that bean
Instance<Object> instance = CDI.current().getBeanManager().createInstance();
RequestQueryParamExtractor rqpe = instance.select(RequestQueryParamExtractor.class).get();
這個 OFC 假定你正在決議的類是一個已知的 bean。
最后但并非最不重要的一點是,如果您@Dependent以這種方式決議任何作用域 bean,那么您也要對它們的銷毀負責。一旦完成與他們的合作,您應該通過呼叫來處理它們Instance.destroy(beanInstance)。對于正常范圍的 bean(例如RequestQueryParamExtractor您的代碼顯示的實體),無需執行此操作。這是為了防止記憶體泄漏,因為您正在對生命周期不受 CDI 控制的非背景關系物件執行動態決議。因此,已解決的依賴實體可能會留在那里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/463975.html
下一篇:以多次插入為條件
