2

我目前正在编写一个库,我希望我的库的用户实现一个接口。在我的库中,我调用了这个实现。

我正在使用 ServiceLoader 来实例化集成器提供的实现,它工作得很好。集成器在我的库中调用 start() 方法,最后他得到了一些回报。该实现用于为我提供一些我需要的东西,以便获得最终结果。(我故意不使用 CDI 或任何其他 DI 容器,因为我想创建一个可以在任何地方使用的库。在桌面应用程序、spring 应用程序和使用 guice 的应用程序中......)

现在我面临一个问题。我正在创建一个使用我自己的库的展示。这是我使用 jsf 和 CDI 的 web 应用程序。当我从我的库中实例化所述 webapp 中提供的实现时,我正在处理一个非容器托管对象。但是由于这个实现需要使用容器管理的对象,所以我有点搞砸了,因为这永远都行不通。

示例:库中的接口:

public interface Example{
   public abstract String getInfo();
}

战争中的实施:

public class ExampleImpl implements Example{

   @Inject
   private ManagedBean bean;
   public String getInfo(){
      return bean.getSomethingThatReturnsString();
   }
}

正如您所看到的,这是我的库构建方式中的一个大问题,因为 bean 将始终为空......这意味着使用 DI 容器的任何人都无法使用我的库。我知道我可以通过 FacesContext 查找来获取 managedbean 并获取 managedbean,但更重要的是,如果您考虑一下,我的库设计得不是很好。

所以结束我的问题:有什么方法可以让服务加载器使用 DI 容器来实例化类?

谁知道解决我问题的更好方法?

谁知道更好的方法来获得我需要的东西而不让集成器实现接口但我可以从集成器获取信息?

我知道这是一个非常抽象的问题,但我有点坚持这个问题。

提前致谢

4

1 回答 1

0

由于示例的实现不在 CDI 容器内执行,因此不会发生注入。您可以做的是使用 BeanManager 手动查找 bean。根据文档, BeanManager 绑定到 jndi 名称java:comp/BeanManager。使用以下代码,您可以在实现类中获取 BeanManager 并手动查找依赖项:

InitialContext context = new InitialContext();
BeanManager beanManager = (BeanManager) context.lookup("java:comp/BeanManager");
Set<Bean<?>> beans = beanManager.getBeans(YourBean.class, new AnnotationLiteral<Default>() {});
Bean<YourBean> provider = (Bean<YourBean>) beans.iterator().next();
CreationalContext<YourBean> cc = beanManager.createCreationalContext(provider);
YourBean yourBean = (YourBean) beanManager.getReference(provider, YourBean.class, cc);

其中YourBean是您要查找的依赖项。

于 2013-08-23T11:02:42.823 回答