2

我想使用 @Inject 向 CDI 应用程序公开由外部框架管理的实例。这些实例必须由其他框架提供,因为它们的生命周期基于各种缓存策略。

例如:同一实例在同一线程范围内可见,可能存在于许多请求范围内,会话范围不适用。似乎我需要定义一个针对这些实例的新范围?

做这个的最好方式是什么?扩展,生产者方法可以吗?

我几乎可以使用以下方法使用生产者方法:

@Inject
@CustomInject
FwObject obj;

@Produces
@CustomInject
FwObject createConfig(InjectionPoint p) {
  return (FwObject) ctx.get((Class<?>) p.getType());
}

但这迫使我明确生成的类型,这是不可能的,因为没有通用的框架接口。

任何帮助表示赞赏。

4

2 回答 2

1

也许使用生产者方法,一切都取决于您的需要,但扩展可能是最好的方法。如果您需要使用新的范围(如果您使用 JSF,则对话范围可能会起作用),您肯定需要创建一个扩展。

于 2012-11-03T05:13:01.070 回答
0

我想我通过创建自定义范围解决了这个问题。下面的文章真的很有帮助:

这是我如何解决它的非常简短的描述。

创建自定义范围注释。

import javax.enterprise.context.NormalScope;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@NormalScope
public @interface CustomScope {
}

创建自定义上下文。

import javax.enterprise.context.spi.Context;
public class CustomContext implements Context {
  private MyFw myFw = .... ;

  @Override
  public Class<? extends Annotation> getScope() {
    return CustomScope.class;
  }
  @Override
  public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) {
    Bean bean = (Bean) contextual;
    return (T) myFw.get(bean.getBeanClass());
  }
  @Override
  public <T> T get(Contextual<T> contextual) {
    Bean bean = (Bean) contextual;
    return (T) myFw.get(bean.getBeanClass());
  }
  @Override
  public boolean isActive() {
    return true;
  }
}

创建扩展并注册上下文。

import javax.enterprise.inject.spi.Extension;
public class CustomContextExtension implements Extension {
  public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
    event.addContext(new CustomContext());
  }
}

注册分机。

将 CustomContextExtension 添加到 META-INF/javax.enterprise.inject.spi.Extension

将 CustomScope 添加到框架对象。

@CustomScope
public class FwObject { ... }

在需要的地方使用 @Inject 注入 FwObject。

public class MyService {
  @Inject
  FwObject obj;
}
于 2012-11-03T14:08:09.383 回答