Hash BeanManager始终返回相同的引用

Hash BeanManager始终返回相同的引用,hash,scope,cdi,custom-scope,Hash,Scope,Cdi,Custom Scope,我正在创建一个自定义CDI作用域,并使用BeanManager注入我的NavigationHandler自定义类。但是它返回的豆子很奇怪 因此,我这样使用BeanManager: public class ScreenContext implements Context { private NavigationHandler getNavigationHandler() { final Set<Bean<?>> beans = m_bean

我正在创建一个自定义CDI作用域,并使用
BeanManager
注入我的
NavigationHandler
自定义类。但是它返回的豆子很奇怪

因此,我这样使用BeanManager:

public class ScreenContext implements Context
{
    private NavigationHandler getNavigationHandler()
    {
        final Set<Bean<?>> beans = m_beanManager.getBeans(NavigationHandler.class);
        final Bean<?> bean = m_beanManager.resolve(beans);

        NavigationHandler reference =
            (NavigationHandler) m_beanManager.getReference(bean, NavigationHandler.class,
                m_beanManager.createCreationalContext(bean));

        System.out.println("Found "+reference+" (hash="+reference.hashCode()+")");
        return reference;
    }
    ...
}
@Named
@WindowScoped
public class NavigationHandler
    implements Serializable, INavigationHandlerController
但是当我测试
reference1==reference2
时,我的调试器返回
true
。我还得到奇怪的散列码:

Found NavigationHandler@593e785f (hash=1261587818)
Found NavigationHandler@b6d51bd (hash=1261587818)

我不明白为什么toString()中使用的哈希值不同,但hashCode()中使用的哈希值相同。

我想我找到了这两个关联问题的原因,这是一个棘手的问题

m_beanManager.getReference(..)
不返回NavigationHandler实例,而是返回一个代理,该代理应该在范围上下文中的现有实例中选择并充当正确的NavigationHandler

了解代理/上下文/BeanManager概念的链接:

因此,我的
getNavigationHandler()
方法不适合此工作:调用此方法的池将保存NavigationHandler代理,而不是NavigationHandler。因为我的池不是一个
@Inject
ed字段,所以CDI不会自动更新代理,因此返回的引用始终是代理当前使用的上一个上下文中的引用

出于与此输出相同的原因:

Found NavigationHandler@593e785f (hash=1261587818)
Found NavigationHandler@b6d51bd (hash=1261587818)
在一种情况下,我得到
NavigationHandler
实例的哈希值,在另一种情况下,我得到
NavigationHandler
代理的哈希值。但我不知道哪个是哪个。我愿意相信使用了代理的toString(),因为
beanManager.getReference(…)
每次都应该为一个新的代理服务,并且hashCode对于每个实例都应该是唯一的

说明每个实例的hashcode都是唯一的hashcode且不能随时间变化的链接:

因此,实现
getNavigationHandler()
的正确方法是:

private getNavigationHandlergetgetNavigationHandler()
{
    final Set<Bean<?>> beans = m_beanManager.getBeans(getNavigationHandler.class);
    final Bean<?> bean = m_beanManager.resolve(beans);

    /* Works : pure reference (not proxied) */
    Class<? extends Annotation> scopeType = bean.getScope();
    Context context = m_beanManager.getContext(scopeType);
    CreationalContext<?> creationalContext = m_beanManager.createCreationalContext(bean);
    // Casts below are necessary since inheritence does not work for templates
    getNavigationHandler reference =
        context.get((Bean<NavigationHandler>) bean, (CreationalContext<NavigationHandler>) creationalContext);

    return reference;
}
private GetNavigationHandlerGetNavigationHandler()
{
final Set bean=m_beanManager.resolve(bean);
/*作品:纯参考(非代理)*/
Class creationalContext=m_beanManager.createCreationalContext(bean);
//下面的强制转换是必需的,因为继承不适用于模板
getNavigationHandler引用=
获取((Bean)Bean,(CreationalContext)CreationalContext);
返回参考;
}
解释
beanManager.getReference(..)
beanManager.getContext(..).get(..)之间区别的链接: