标签: cdi

为什么 @ApplicationScoped bean 在我的 CDI 扩展的 BeforeShutdown 阶段有一个新实例?

我想在关闭 CDI 应用程序时对 bean 进行一些清理。例如,我想关闭一个IO连接。当然,这里的bean被标记为@ApplicationScoped。

为了管理这个问题,我编写了一个扩展并观察 BeforeShutdown 事件,然后选择我的 bean 来调用清理方法:

public void beforeShutdown(@Observes BeforeShutdown beforeShutdown) {
    SomeBean obj = CDI.current().select(SomeBean.class).get();
    obj.cleanup();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我可以在此方法中访问新实例。不是我在整个应用程序中得到的实例。

如果您想查看此实例问题,我在 github 上创建了一个存储库来展示它: https: //github.com/hasalex/cdi-extension-demo

所以我有两个问题:

  • 为什么我会得到一个新实例?
  • 还有其他方法可以在应用程序结束时清理我的 bean 吗?(在 SE 和 WildFly 环境中)

java cdi weld

2
推荐指数
1
解决办法
954
查看次数

Weld 在库 jar 中找不到 CDI 生成器方法

使用 Wildfly 8.2.0.Final(我相信它使用 Weld 2.2),我在 Maven 多模块项目中使用 2 个简单的类重现了这个问题。一个产生一个javax.ws.rs.client.Client,另一个有一个相同的注入点。Arquillian 部署失败,原因是WELD-001408:依赖关系不满足。生产者位于一个库 jar 中,该库 jar 包含在WEB-INF/lib消费者的库中。生产者有一个beans.xmlin the META-INFwith discovery-mode=annotation,消费者也有一个 in WEB-INFwith discovery-mode=all

重现步骤:下载该项目mvn clean install并从根目录运行。

这是一个严重的错误。还有一些其他关于 Weld 不满足依赖关系的帖子,但大多数都是因为beans.xml缺少 a 。对于 CDI 1.2,beans.xml它是可选的,尽管我的示例确实有几个。有任何想法吗?

全面披露:也发布在 Weld 论坛255328

cdi weld

2
推荐指数
1
解决办法
1506
查看次数

如果定义类未声明范围,CDI 生成器方法将不起作用

我正在本地 Glassfish 4.1.1 (WELD 2.2.2) 安装中运行一些关于 CDI 的概念验证。

我创建了一个名为 TipicalBean 的类 bean,它注入一个在生产者方法中生成的整数。

定义生产者方法的类如下所示

public class ProducerTest {

    @Produces @MyNumber @Dependent public static int getMyNumber() {
        return 100;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是行不通的。即使我将方法声明为静态

但如果将 @Dependent 作用域放入类定义中,它确实有效,如下所示:

@Dependent
public class ProducerTest {
Run Code Online (Sandbox Code Playgroud)

此外,如果我在注入它的同一个类中声明该生产者方法,我可以在生产者方法声明中定义 @Dependent 范围,但 WELD 会在 Glassfish 控制台中打印警告

WELD-000018: Executing producer field or method [BackedAnnotatedMethod] @Produces
@MyNumber @Dependent public mypackage.TipicalBean.produceMyNumber() on incomplete
declaring bean Managed Bean [class mypackage.TipicalBean] with qualifiers [@Any
@Default] due to circular injection
Run Code Online (Sandbox Code Playgroud)

为什么?生产者方法必须在 ManagedBeans 中定义吗?

由于我使用的是 JavaEE 7,因此我尚未创建 …

java cdi weld glassfish-4 java-ee-7

2
推荐指数
1
解决办法
5381
查看次数

@SessionScoped (CDI) 和 @Stateful (Java EE) 之间的区别

我了解到 CDI Bean 可以用于不同的基于 Web 应用程序的范围(仅限于此,对吧?)。例如:@RequestScoped、@SessionScoped等。@SessionScoped 将数据保存在整个浏览器会话上的托管 bean 中。这在逻辑上听起来很安静,因为注释名称描述了它的作用。然而,现在我更仔细地了解了 EJB 会话 Bean。到目前为止我知道,这样的状态可能具有以下三种状态之一:@Stateless、@Stateful 和@Singleton。对我来说,看起来它们和 CDI bean 的注释之间有直接的可比性:@RequestScoped --> @Stateless、@SessionScoped --> @Stateful、@ApplicationScoped --> @Singleton。但由于我正在研究一些示例,我发现了一个同时包含 @Stateful 和 @SessionScoped 注释的 bean。我寻找解释 - 但我没有找到任何可以理解的答案。那么,到底有什么区别呢?为什么我必须使用这两个注释?谢谢。

annotations stateful session-scope cdi jakarta-ee

2
推荐指数
1
解决办法
3107
查看次数

CDI 事件已触发,但未被所有线程/会话接收

我有一个简单的设置,只有一个会话支持 JSF xhtml 文件。在其中,我触发一个事件,希望同一会话和任何其他会话在提交时都会收到该事件。

然而,奇怪的是,我可以看到在事件触发期间,只有当前会话收到它,而不是任何其他会话。我通过使用两种不同的浏览器(本例中为 Safari 和 Firefox)来确保我有两个不同的会话。

我对基于 CDI 的事件的概念是否有误?

支持会话的 bean:

package testevent;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Named
@SessionScoped
public class TestEventSession implements Serializable {
  private String message = "Start Message";
  private String receivedMessage = "";
  
  @Inject
  @ForTest Event<String> messageEvent;
  
  Logger LOG = LogManager.getLogger();
  
  public void messageChanged(@Observes(notifyObserver = Reception.IF_EXISTS) @ForTest String message) {
    LOG.info("messageChanged <-- "+message);
    this.receivedMessage = message;
  }

  public String getReceivedMessage() { …
Run Code Online (Sandbox Code Playgroud)

java cdi

2
推荐指数
1
解决办法
1223
查看次数

是否需要定义一个拦截器绑定在拦截器上?

在https://javaee.github.io/tutorial/cdi-adv-examples005.html#GKHPA的 JEE8 教程中,它有一个拦截器,该拦截器用自己的拦截器绑定进行注释。以下内容摘自教程:

拦截器类 LoggedInterceptor及其拦截器绑定Logged 都在拦截器包中定义。Logged 拦截器绑定定义如下:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logged {
}
Run Code Online (Sandbox Code Playgroud)

LoggedInterceptor 类如下所示:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {    
    //...more code       
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,拦截器类本身有必要使用@Logged注解吗?我已经运行了没有 @Logged 注释的代码,即:

@Interceptor
public class LoggedInterceptor implements Serializable {
   //...
Run Code Online (Sandbox Code Playgroud)

它的行为方式似乎完全相同。通过摆弄代码,在我看来,将 @Logged 注释添加到方法 foo 就是将 foo 标记为需要拦截的方法的方式。那么将 LoggedInterceptor 类标记为 @Logged 有什么意义呢?

谢谢你的帮助。

ejb cdi jakarta-ee

2
推荐指数
1
解决办法
1555
查看次数

CDI 装饰另一个 JAR 中的服务

我想使用 CDI 的装饰器模式来增强服务提供的业务逻辑。我尝试装饰的服务位于另一个模块(用 Maven 术语来说),因此是另一个 JAR。例如,提供的服务位于模块中com.acme.provider,而装饰器位于com.acme.consumer服务消费者旁边。

我的服务按原样注入,没有任何修饰。

beans.xml装饰器在消费者模块内部声明。

我在这里提供了一个工作示例。在 上mvn install,测试打印“Hello”而不是“Hello World”,因为它会应用装饰器。

如果我将装饰器(及其 xml 声明)移至提供者模块(请参阅decorator-in-provider同一存储库的分支),则一切正常并打印“Hello World”。

如果装饰器仅在提供者 bean 和装饰器本身的代码位于同一模块中时才起作用,那么我认为它的用处不大。Java EE 装饰器模式有这样的限制吗?或者我做错了什么?

感谢您的见解。

java decorator cdi jakarta-ee

2
推荐指数
1
解决办法
286
查看次数

WeldContainer 和 SeContainer

使用有什么区别:

WeldContainer se = new Weld().initialize();

或者

SeContainer se = SeContainerInitializer.newInstance().initialize();

我只是想使用@Injection@Produce注解,但是我还没有发现这两种初始化对象实例的方式之间的区别。

java cdi jboss-weld weld weld2

2
推荐指数
1
解决办法
702
查看次数

注入实现相同接口的 bean 列表

假设我有以下界面

public interface Handler {
    void handle(Object o);
}
Run Code Online (Sandbox Code Playgroud)

和实现

public class PrintHandler implements Handler {
    void handle(Object o) {
        System.out.println(o);
    }
}
public class YetAnotherHandler implements Handler {
    void handle(Object o) {
        // do some stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我想将所有Handler子类注入某个类

public class Foo {
    private List<Handler> handlers;
}
Run Code Online (Sandbox Code Playgroud)

如何使用 Quarkus 实现这一目标?

java cdi quarkus

2
推荐指数
1
解决办法
789
查看次数

JavaEE CDI 的 SpringBoot 替代品是什么?

我知道 JakartaEE(以前称为 JavaEE)从 JavaEE 6 开始就支持 CDI。

据我所知,SpringBoot 没有 CDI,只有 DI。

SpringBoot 是否支持 CDI(上下文和依赖注入)或提供一些替代方案?

dependency-injection cdi spring-boot java-ee-8

2
推荐指数
1
解决办法
258
查看次数