1

我正在构建一个 TCP 套接字服务器,它使用 Spring Framework (3.2.3.RELEASE) 将事物联系在一起。

一切都使用带有注释的 Java Config 进行配置。在 Java Config 中,我有一个@ComponentScan注释来扫描我的类路径中的组件。

当 TCP Socket Server 接收到消息时,我偶尔想调度一些事件。为此,我使用 Google Guice EventBus。我不希望 TCP 套接字服务器知道事件接收器,反之亦然,以保持松散耦合。

我已经EventBusRegisterBeanPostProcessor从 Patrick Meade @ http://pmeade.blogspot.no/2013/02/using-guava-eventbus-with-spring-part-2.html提供的代码中注册了一个

这将扫描任何 bean 并将其注册到 EventBus。

要监听事件(订阅),我只需要创建一个如下所示的 POJO:

@Component
public class PingMessageReceivedHandler {

    static Logger logger = Logger.getLogger(PingMessageReceivedHandler.class);

    @Subscribe
    public void handleMessageReceivedEvent(MessageReceivedEvent messageReceivedEvent) {
        logger.info(messageReceivedEvent.getMessage());
        messageReceivedEvent.getChannel().writeAndFlush(new BaseMessage(false, "Pong", null, ""));
    }

}

现在,问题来了:除非我在不同的服务或组件或其他地方的某个地方依赖于PingMessageReceivedHandler(例如使用@Autowired),否则EventBusRegisterBeanPostProcessor将不会意识到PingMessageReceivedHandler并且因此不会向它发送消息。

我知道 Spring 知道PingMessageReceivedHandler日志状态的存在,所以:

2013-11-04 17:35:05,391  INFO [main] (DefaultListableBeanFactory.java:596) - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9695ed7: defining beans [[...],pingMessageReceivedHandler,[...],eventBusRegisterBeanPostProcessor]; root of factory hierarchy

关于导致这种情况的任何想法,更重要的是,我如何解决它?

编辑: 上下文配置:

@ComponentScan(value = "com.company.product")
@Configuration
public class DeviceManagerServerConfig {

    @Bean
    public static EventBusRegisterBeanPostProcessor eventBusRegisterBeanPostProcessor() {
        return new EventBusRegisterBeanPostProcessor();
    }

    @Bean
    public EventBus eventBus() {
        return new EventBus("standard");
    }
}

它使用以下方式初始化:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DeviceManagerServerConfig.class);
context.refresh();
4

2 回答 2

0

问题是我试图初始化一个具有阻塞操作的 bean(TCP 套接字服务器)。

这阻止了 Spring 进一步的 bean 初始化,并导致了原始帖子中的问题。

IE:

@Component
@Profile("default")
public class SocketServerImpl implements SocketServer {
    /**
    * Instantiates a new socket server.
    */
    public SocketServerImpl() {
        /* Standard stuff */
    }


    @PostConstruct
    @Override
    public void start() {
        /* This would block any further progressing */
    }
}

我的修复非常简单,我@PostConstruct从上面的代码中删除了public static void main,在我调用之后context.refresh(),我调用了context.getBean(SocketServer.class).start().

于 2013-11-04T23:03:12.763 回答
-1

尝试添加

@Lazy(false)

到您的处理程序 bean。

我认为它默认以某种方式声明为惰性,因此在没有依赖关系的情况下不会在启动时加载。

于 2013-11-04T17:01:46.643 回答