- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用 BeanManager 而不是 Instance .select().get() 创建 CDI 托管 bean 的实例。
这被建议作为解决我一直遇到的 ApplicationScoped bean 及其依赖项的垃圾收集问题的解决方法 - 请参阅 CDI Application and Dependent scopes can conspire to impact garbage collection?对于背景和这个建议的解决方法。
如果您在 ApplicationScoped bean 上使用 Instance 编程查找方法,则 Instance 对象和您从中获得的任何 bean 最终都依赖于 ApplicationScoped bean,因此共享它的生命周期。但是,如果您使用 BeanManager 创建 bean,那么您将拥有 Bean 实例本身的句柄,并且显然可以显式销毁它,我理解这意味着它将被 GC。
我目前的方法是在 BeanManagerUtil 类中创建 bean,并返回 Bean、实例和 CreationalContext 的复合对象:
public class BeanManagerUtil {
@Inject private BeanManager beanManager;
@SuppressWarnings("unchecked")
public <T> DestructibleBeanInstance<T> getDestructibleBeanInstance(final Class<T> type,
final Annotation... qualifiers) {
DestructibleBeanInstance<T> result = null;
Bean<T> bean = (Bean<T>) beanManager.resolve(beanManager.getBeans(type, qualifiers));
if (bean != null) {
CreationalContext<T> creationalContext = beanManager.createCreationalContext(bean);
if (creationalContext != null) {
T instance = bean.create(creationalContext);
result = new DestructibleBeanInstance<T>(instance, bean, creationalContext);
}
}
return result;
}
}
public class DestructibleBeanInstance<T> {
private T instance;
private Bean<T> bean;
private CreationalContext<T> context;
public DestructibleBeanInstance(T instance, Bean<T> bean, CreationalContext<T> context) {
this.instance = instance;
this.bean = bean;
this.context = context;
}
public T getInstance() {
return instance;
}
public void destroy() {
bean.destroy(instance, context);
}
}
据此,在调用代码中,我可以获取实际实例,将其放入映射中供以后检索,然后正常使用:
private Map<Worker, DestructibleBeanInstance<Worker>> beansByTheirWorkers =
new HashMap<Worker, DestructibleBeanInstance<Worker>>();
...
DestructibleBeanInstance<Worker> destructible =
beanUtils.getDestructibleBeanInstance(Worker.class, workerBindingQualifier);
Worker worker = destructible.getInstance();
...
当我完成它时,我可以查找可破坏的包装器并对其调用 destroy(),然后应该清理 bean 及其依赖项:
DestructibleBeanInstance<JamWorker> workerBean =
beansByTheirWorkers.remove(worker);
workerBean.destroy();
worker = null;
但是,在运行几个 worker 并离开我的 JBoss (7.1.0.Alpha1-SNAPSHOT) 20 分钟左右后,我可以看到 GC 发生了
2011.002: [GC
Desired survivor size 15794176 bytes, new threshold 1 (max 15)
1884205K->1568621K(3128704K), 0.0091281 secs]
然而,JMAP 直方图仍然显示旧 worker 及其相关实例悬而未决,未进行 GC。我错过了什么?
通过调试,可以看到创建的bean的context字段有正确Worker类型的contextual,没有incompleteInstances,也没有parentDependentInstances。它有许多 dependentInstances,这是从 worker 的字段中预期的。
Worker 上的其中一个字段实际上是一个实例,当我将这个字段与通过编程实例查找检索到的 Worker 的字段进行比较时,它们的 CreationalContext 构成略有不同。通过 Instance 查找的 Worker 上的 Instance 字段在 incompleteInstances 下有 worker 本身,而从 BeanManager 检索到的 Worker 上的 Instance 字段则没有。它们都具有相同的 parentDependentInstances 和 dependentInstances。
这表明我没有正确地镜像实例的检索。这会不会导致破坏力不足?
最后,在调试时,我可以看到在我的 DestructibleBeanInstance.destroy() 中调用了 bean.destroy(),这会进入 ManagedBean.destroy,我可以看到相关对象作为 .release( ).然而,他们仍然没有收集垃圾!
如有任何帮助,我们将不胜感激!谢谢。
最佳答案
我会更改您粘贴的代码中的一些内容。
BeanManager.createCreationContext(null)
创建一个新的 CreationalContext,这实际上会给你一个依赖范围,当你完成调用 CreationalContext.release()
。 假设没有其他 Bean
在那个会弄乱你的应用程序的 CreationalContext 中。先试试看它是否会把事情搞砸。
关于java - 如何通过 BeanManager 创建和销毁 CDI (Weld) Managed Beans?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8420070/
我正在尝试从 Glassfish+Jersey+Weld 迁移到 Jetty。 我有这样的设置:gist of pom.xml, web.xml and Java launcher . 应用程序似乎可
注意:我已经尝试过类似问题的可用解决方案。 我正在使用JSF,Java 8,Tomcat 9,Maven,H2 db开发一个简单的CRUD应用程序。 当我尝试启动服务器时,发生以下异常 由以下原因
我刚刚将 Weld 从版本 2.4.4 更新到 3.0.1。我在应用程序启动时遇到以下错误,但找不到解决方案。我正在使用 Weld SE。 Sep 15, 2017 1:25:12 PM org.jb
我想使用 WELD SE 和 JEE8 (CDI 2.0) 创建 REST 资源的单元测试。 这是 REST 资源类的代码: @Path("/members") @RequestScoped publ
我正在使用 NetBeans 和 Glassfish 4.1.1 开发一个 Web 应用程序。我使用 JSF 和 CDI 来管理 Facelets 的支持 bean。由于在更改代码中的任何内容后不久,
从 JPA 2.1 开始,可以将 EJB 注入(inject)到实体监听器中。然而,WildFly 9.0.2 final 失败并出现以下异常。 15:41:12,125 ERROR [org.jbo
我使用 Weld SE 创建了一个简单的 JavaSE 应用程序。我正在尝试使用 gradle run 运行它会抛出异常: :compileJava UP-TO-DATE :processResour
我正在尝试在 DAO 类中注入(inject)一个实体管理器并使用 Weld 容器对其进行测试,但我不断收到以下异常: org.jboss.weld.exceptions.NullInstanceEx
由于某种原因,以下代码不起作用,我不明白为什么。我目前的,相当随意的,从大惊小怪的几个细微变化的信念是,因为 bean 是在 ExternalContext 之前创建的。它导致异常。但是,Extern
我有一个 Java 8 项目和一个 JBoss 7.1.0GA 服务器。我有一个带有全局变量的批处理类 @EJB public MyInterface delegate; 它在我的 ejb-jar.x
我的项目昨天运行良好。我唯一做的就是将结构从单一 war 更改为多模块 pom。如果我正确理解堆栈跟踪,则焊接和omnifaces websocket lib之间存在歧义。但是,在堆栈跟踪上似乎没有对
我按照文档(https://docs.jboss.org/weld/reference/latest/en-US/html/injection.html)创建限定符,现在我在wildfly-10.1.
我正在开发一个 JavaFX 2 项目,并且该应用程序必须使用另一个 main 方法(根据生成的 JAR list 为 com.javafx.main.Main)启动。据官方焊缝reference引导
我们有一个 Web 应用程序,目前正在使用 Java EE 7、JSF 2.2 和 Glassfish 4.0 开发。有两个特定的托管 Bean,它们具有循环依赖关系。 Usuario Control
我正在使用 Weld 来观察事件。我认为有一种方法可以指定观察者是否异步,但我没有找到该注释或文档。 观察者可以是异步的吗?如果是这样,我需要做什么才能做到这一点? 最佳答案 有一个开放请求:CDI-
我正在尝试将 war 部署到 JBoss AS 7.1.1 服务器中,但在尝试注入(inject) EntityManager 时部署失败: 17:44:48,037 ERROR [org.jboss
我尝试在 Weld 中制作装饰器,但 Weld 返回错误。我不明白我的错误是什么。我使用了相同的 Weld 示例“weld-se-numberguess”,并创建了一个装饰器扩展游戏。 Set 18
我使用 JBoss AS 7.1.1 + CDI (Weld) + JSF + Intellij IDEA。我创建了项目并下载了文件: 1. jsf-api.jar 2. jsf-impl.jar 3
我正在搭建学习 JavaEE7 中 CDI 的基础环境。我有以下用于启动 Weld 的代码。只是启动和关闭。 package com.anshbansal; import org.jboss.weld
我使用 weld se 2.0 和其他简单的依赖项构建了一个应用程序。在我的开发环境(eclipse)中这工作正常,没有错误,但是......在生产中应用程序完全崩溃并且焊接的实习生依赖部分抛出“模糊
我是一名优秀的程序员,十分优秀!