在 JBoss AS7 上运行,我有这个:
import javax.inject.Singleton;
@Singleton
public class Connections {
private final List<AtmosphereResource> connections = new ArrayList<AtmosphereResource>();
public void add(AtmosphereResource event) {
connections.add(event);
}
}
和这个:
import javax.inject.Inject;
public class PubSubAtmosphereHandler extends AbstractReflectorAtmosphereHandler {
@Inject
private Connections connections;
@Override
public void onRequest(AtmosphereResource event) throws IOException {
[...]
connections.add(event); // <---
}
指定线路上的 NPE。看了无数页和例子,这是重复了几十次的方法之一,但它不起作用。我有空的 beans.xml,放在我的 WEB-INF 中。我在这里错过了什么?
最佳答案
经过一些研究,事实证明 Atmosphere 为这种功能提供了(目前已损坏的)钩子(Hook)。这意味着 IS 可以简单地使用您的普通注释并使其与 Atmosphere 一起使用,尽管是“外部”实例化。
如果你知道你的代码将被部署在哪里,你可以简单地覆盖 Atmosphere 中的默认 noop InjectorProvider 类,方法是在同一个包中使用一个同名的类并让它提供正确的 Injector。
我在这个答案的末尾添加了 JBoss AS7 的代码,以及指向应该在 Google Guice 和 Spring 上运行的代码的链接,我自己没有测试过。
如果您需要您的代码在多个平台上工作,您可能需要弄清楚如何检测您正在运行的内容,然后返回适当的 Injector。由于我对 Guice 和 Spring 不是很熟悉,我将把这个练习留给读者。
JBoss AS7 的脏“初稿”代码(请记住,这必须进入声明的包以覆盖默认的 noop 提供程序):
package org.atmosphere.di;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class InjectorProvider {
private InjectorProvider() {}
public static Injector getInjector() {
return LazyProvider.INJECTOR;
}
private static final class LazyProvider {
private static final Injector INJECTOR;
static {
Injector injector = new Injector() {
@Override public void inject(final Object o) {
try {
final BeanManager bm = (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
final CreationalContext cc = bm.createCreationalContext(null);
final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(o.getClass()));
it.inject(o, cc);
cc.release();
} catch (final NamingException e) {
e.printStackTrace();
}
}
};
try {
injector = ServiceLoader.load(Injector.class).iterator().next();
} catch (final NoSuchElementException e) {}
INJECTOR = injector;
}
}
}
请注意,包装代码取自 Atmosphere 代码库,这是在 Java 中执行单例的一种非常糟糕的方式。您可能不想在生产中“按原样”使用它。
Guice 注入(inject)器,未经测试:https://github.com/Atmosphere/atmosphere/blob/atmosphere-1.0.x/extras/guice/src/main/java/org/atmosphere/guice/GuiceInjector.java
Spring 注入(inject)器,未经测试:https://github.com/Atmosphere/atmosphere/blob/atmosphere-1.0.x/extras/spring/src/main/java/org/atmosphere/spring/SpringInjector.java
关于java - 无法让@Singleton 做任何事情,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13827293/