2013-08-21 40 views
2

我正在编写一个库,我希望我的库的用户实现一个接口。从我的库中我调用这个实现。如何使serviceloader创建类处理容器管理对象

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

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

例: 接口在lib目录下:

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

实现战争:

public class ExampleImpl implements Example{ 

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

正如你可以看到这是在路上一个巨大的问题,我的图书馆是建立以来,豆总会be null ...这意味着没有人使用DI容器可以使用我的库。我知道我可以通过执行FacesContext查找来获得managedbean,并获得managedbean,但更重要的是,如果您仔细考虑,我的库的设计不是很好。

因此,要结束我的问题: 有什么办法可以让serviceloader使用DI容器来实例化类吗?

任何人知道更好的方法来解决我的问题?

任何人都知道更好的方式来获得我所需要的东西,而无需使集成商实现一个接口,但我可以从集成商处获得信息?

我知道这是一个相当抽象的问题,但我有点卡在这一个。

预先感谢

回答

0

如实施例的实施是不CDI容器注射不会发生内进行。你可以做的是使用BeanManager手动查找bean。根据docs,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是你正在寻找的依赖。