gpt4 book ai didi

java - @InterceptorBinding/CDI/EJB 3.2 - 注入(inject)问题

转载 作者:行者123 更新时间:2023-11-29 07:40:22 26 4
gpt4 key购买 nike

我的开发环境是:WildFly 8.1、CDI、EJB 3.2、JDK 1.7。应用程序打包为 ear archive(一个 ejb + 一个 war),因为将来它可能会有其他 web 模块。

我正在努力处理在我的 EJB 无状态 bean 中使用的自定义 @InterceptorBinding 类型。

@Inherited
@InterceptorBinding
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
public @interface DetectIntegrityConstraintsViolation {
}

@javax.annotation.ManagedBean // make it a CDI bean. @Interceptor itself should be enough, but WildFly 8.1 seems to have a bug, since it doesn't work without this line.
@Interceptor
@DetectIntegrityConstraintsViolation
public class ReferentialIntegrityConstraintViolationInterceptor {

@PersistenceContext
private EntityManager em;

@Resource
private SessionContext sessionContext;

// ....
}

beans.xml:

<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_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">

<interceptors>
<class>com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor</class>
</interceptors>
</beans>

当我通过 REST 服务调用我的 EJB 方法时,我得到了Error injecting resource into CDI managed bean:

javax.naming.NameNotFoundException: Caused by java.lang.IllegalStateException: JBAS011048: Failed to construct component instance  Caused by: java.lang.IllegalArgumentException: JBAS016081: Error injecting resource into CDI managed bean.
Can't find a resource named java:comp/env/com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor/sessionContext defined on private javax.ejb.SessionContext com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor.sessionContext at org.jboss.as.weld.services.bootstrap.WeldResourceInjectionServices.resolveResource(WeldResourceInjectionServices.java:188) [wildfly-weld-8.1.0.Final.jar:8.1.0.Final]

所以在黑暗中行走,我转向了 ResourceLookup 方法:

@ManagedBean
@Interceptor
@DetectIntegrityConstraintsViolation
public class ReferentialIntegrityConstraintViolationInterceptor {

@PersistenceContext
private EntityManager em;

private SessionContext sessionContext;

@PostConstruct
public void init(InvocationContext ctx) {
try {
InitialContext ic = new InitialContext();
this.sessionContext = (SessionContext)ic.lookup("java:comp/EJBContext");
} catch (NamingException ex) {
throw new RuntimeException(ex.getMessage());
}
}

// .....
}

然后注入(inject)开始工作,但是我得到了一个新的错误:

Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000619: An interceptor for lifecycle callbacks Interceptor [class com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor intercepts @DetectIntegrityConstraintsViolation] declares and interceptor binding interface com.xxx.ejb.DetectIntegrityConstraintsViolation with METHOD as its @Target.

因此,当从 DetectIntegrityConstraintsViolation 中删除一个 METHOD 目标时:

@Inherited
@InterceptorBinding
@Target({ TYPE /*, METHOD*/ }) // CRUCIAL
@Retention(RUNTIME)
@Documented
public @interface DetectIntegrityConstraintsViolation {
}

然后它开始工作。但是为什么??
为什么我不能在方法上放置注释?有人知道吗?

顺便说一句:更奇怪的是,当我没有使用@InterceptorBinding,而是使用普通的旧代码时:

@Override
// @DetectIntegrityConstraintsViolation
@Interceptors(ReferentialIntegrityConstraintViolationInterceptor.class)
public User updateUser(final User user) {
// ...
}

拦截器即使在方法级别也能完美运行。

我发现 EJB 和 Weld 很难用...

最佳答案

CDI spec 中描述了您的一条错误消息:

An interceptor for lifecycle callbacks may only declare interceptor binding types that are defined as @Target(TYPE). If an interceptor for lifecycle callbacks declares an interceptor binding type that is defined @Target({TYPE, METHOD}), the container automatically detects the problem and treats it as a definition error.

您已经使用 @PostConstruct init(InvocationContext ctx) 创建了一个生命周期回调。此回调旨在在您拦截的 bean 的构造上运行,因此将其应用于方法没有意义。

至于为什么普通的旧 @Interceptor 可以工作,这也在 documentation 中有所描述。 :

An around-invoke interceptor may be defined to apply only to a specific method of the target class. Likewise, an around-timeout interceptor may be defined to apply only to a specific timeout method of the target class. However, if an interceptor class that defines lifecycle callback interceptor methods is defined to apply to a target class at the method level, the lifecycle callback interceptor methods are not invoked.

至于这个:

I find EJB and Weld so awkward to use...

如果你放慢脚步并边学边学,你会过得更轻松。您似乎在尝试随机的事情并且对结果感到困惑,如果您不熟悉 CDI 和 EJB,这是可以预料的。

我还担心您正在使用 @ManagedBean 注释。第一,实际上是 deprecated ,第二,它用于 JSF,您没有说您正在使用它。

关于java - @InterceptorBinding/CDI/EJB 3.2 - 注入(inject)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30894880/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com