Atmosphere ManagedService中MyDAO始终为null的问题求助
解决Dropwizard + Atmosphere ManagedService中DAO注入为null的问题
这个问题的核心原因是:Atmosphere默认会自己实例化@ManagedService标注的类,不会让Dropwizard的HK2依赖注入容器参与创建过程,所以你的MyDAO无法被自动注入,始终为null。下面是两种可行的解决方案:
方案一:让Dropwizard的DI容器托管ManagedService实例
这种方法是最优解,能让你正常使用构造注入或者字段注入:
确保MyDAO已注册到HK2容器
在你的Dropwizard Application类的run方法中,把MyDAO绑定到HK2容器:@Override public void run(YourConfiguration config, Environment environment) { // 绑定MyDAO为单例 environment.jersey().register(new AbstractBinder() { @Override protected void configure() { bind(MyDAO.class).to(MyDAO.class).in(Singleton.class); } }); // 其他初始化逻辑... }配置Atmosphere使用HK2的实例工厂
在Application的initialize方法中,添加AtmosphereBundle时,指定用HK2的Injector来创建ManagedService实例:@Override public void initialize(Bootstrap<YourConfiguration> bootstrap) { bootstrap.addBundle(new AtmosphereBundle() { @Override public void configureAtmosphere(AtmosphereConfig config) { // 获取Dropwizard的HK2 Injector Injector injector = environment.jersey().getResourceConfig().getApplicationHandler().getInjector(); // 设置Atmosphere使用HK2的实例工厂 config.setClassInstanceFactory(new HK2ClassInstanceFactory(injector)); } }); }在ChatRoom中使用构造注入
修改你的ChatRoom类,添加带@Inject注解的构造方法,注入MyDAO:@Singleton @ManagedService(path = "/chat/{rooms: [a-zA-Z][a-zA-Z_0-9]*}") public class ChatRoom{ private final Logger logger = LoggerFactory.getLogger(ChatRoom.class); // 注意:你原来写的GameService应该是笔误,改成ChatRoom private final ConcurrentHashMap<String, String> users = new ConcurrentHashMap<>(); private final static String CHAR= "/chat/"; private final MyDAO myDAO; // 构造注入MyDAO @Inject public ChatRoom(MyDAO myDAO) { this.myDAO = myDAO; } @Ready(encoders = {InitialMessageEncoder.class}) @DeliverTo(DeliverTo.DELIVER_TO.ALL) public InitialMessage onReady(final AtmosphereResource r) { logger.info("MyDAO instance: {}", myDAO); // 现在myDAO应该不为null了 // 返回你的InitialMessage实例 return new InitialMessage("Ready to chat!"); } }
方案二:手动从ServletContext获取Injector(快速临时方案)
如果不想修改Atmosphere的全局配置,可以在onReady方法中手动获取Dropwizard的Injector,然后实例化MyDAO:
@Ready(encoders = {InitialMessageEncoder.class}) @DeliverTo(DeliverTo.DELIVER_TO.ALL) public InitialMessage onReady(final AtmosphereResource r) { // 从ServletContext获取HK2 Injector ServletContext servletContext = r.getAtmosphereConfig().getServletContext(); Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName()); if (injector != null) { myDAO = injector.getInstance(MyDAO.class); } logger.info("MyDAO instance: {}", myDAO); // 返回InitialMessage return new InitialMessage(...); }
额外注意点
- 确保你的
MyDAO类上添加了@Injectable注解(或者在HK2绑定中明确声明),这样HK2才能识别它。 - 你原来代码中的
LoggerFactory.getLogger(GameService.class)应该是ChatRoom.class的笔误,记得修正,避免日志输出到错误的Logger。
内容的提问来源于stack exchange,提问作者hruday kumar reddy
相关产品推荐
相关产品推荐

