Spring组件之间的信息共享

Spring组件之间的信息共享

问题描述:

我想构建一个应用程序,在其中实现一个相当简单的模式:我有一个websocket服务器,它接收来自多个客户端的流数据。然后存储这些数据,以便通过RESTful API提供。我想拥有某种接口,WS服务器和REST API都可以访问存储和请求最新数据。Spring组件之间的信息共享

为了提供一个简化的情况:

我具有被通过WebSocket连接流消息10点连接的小工具。它们中的每一个都正在流入/接收/ {ID}。然后我有一个REST API在/ latest/{ID}上返回最新消息。

  1. 这是正确的设计模式吗?
  2. 如果是这样,我该如何使用尽可能多的Spring框架来实现它?

我想象,我需要做到以下几点:

我将有一个类的方法main(String args[])。这将自行运行,Spring框架将选择不同的组件 - WebSocket端点,REST端点和DataCache类。

如何将DataCache类的正确实例提供给WebSocket和REST端点?

 @SpringBootApplication 
     @EnableWebSocket 
     @ComponentScan(basePackages={"com.acme.server.wsendpoint","com.acme.server.restendpoint","com.acme.server.datacache"}) 
     public class PredixWebsocketServerApplication{ 
      private static Logger log = LoggerFactory.getLogger(WebsocketServerApplication.class); 

      /** 
      * @param args - 
      */ 
      @SuppressWarnings("nls") 
      public static void main(String[] args) { 
       SpringApplication app = new SpringApplication(WebsocketServerApplication.class); 
      } 
     } 

然后,我会在每个组件类的有以下代码:

public class WSEndpoint { 

     private static Logger logger = LoggerFactory.getLogger(WSEndpoint.class); 
     private DataCache dataCache; 

     public WSEndpoint(DataCache cache) { 
      dataCache = cache; 
//do init stuff 
     } 

    /** 
    * @param ID - machine ID 
    * @param session - session object 
    * @param ec  - 
    */ 
    @OnOpen 
    public void onOpen(@PathParam(value = "mID") String ID, @PathParam(value = "direction") String DirectionID, final Session session, EndpointConfig ec) { 
     logger.info("Server: opened... for Direction: " + DirectionID + " Node Id : " + ID + " : " + session.getId()); 
    } 

    /** 
    * @param ID - 
    * @param message - 
    * @param session - 
    */ 
    @OnMessage 
    public void onMessage(@PathParam(value = "modelID") String modelID, @PathParam(value = "direction") String DirectionID, String message, Session session) { 
     try { 
      for(Session s : session.getOpenSessions()){ 
       if ("ingest".equals(s.getPathParameters().get("direction"))){ 
        DataCache.store(message); 
       } 
      } 
     } catch (Exception e){ 
      logger.error("Error handling websocket message: " + e.getLocalizedMessage()); 
     } 
    } 

    /** 
    * @param session  - session object 
    * @param closeReason - The reason of close of session 
    */ 
    @OnClose 
    public void onClose(Session session, CloseReason closeReason) { 
     logger.info("Server: Session " + session.getId() + " closed because of " + closeReason.toString()); 
    } 

    /** 
    * @param session - current session object 
    * @param t  - Throwable instance containing error info 
    */ 
    @OnError 
    public void onError(Session session, Throwable t) { 
     logger.error("Server: Session " + session.getId() + " closed because of " + t.getMessage()); 
    } 


} 

然后,剩下的端点将是这个样子:

@Controller 
public class RestEndpoint { 

    private DataCache dataCache; 
    private static Logger log = LoggerFactory.getLogger(restEndpoint.class); 

    public void setGreeting(DataCache cache){ 
     dataCache = cache; 
    } 

    @CrossOrigin(origins = "http://localhost:5000") 
    @RequestMapping(value="/latest/{ID}") 
    @ResponseBody 
    public String latest() { 
     log.info("Sending message: " + DataCache.getLatest(ID)); 
     return latest; 
    } 
} 

使用Spring IoC Container将您的DataCache注入到两个Bean中,这就是Spring的确切目的。

尝试

@Autowired 
private DataCache datacache 

在这两个您的终端。

如果启用了Spring autoConfiguration,则使用@Service注释您的DataCache类,以告知Spring创建DataCache Bean。

而且您应该详细了解https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html

+0

非常感谢您,这正是我需要做的。最初,它并不适用于我使用我共享的代码,因为[javax websocket](http://stackoverflow.com/questions/29306854/serverendpoint-and-autowired)中不支持@Autowired注释。 我想通过切换到Spring框架实现来解决它。我仍然需要做其他hacky的事情来让websockets按照我需要的方式工作,但至少现在我可以注入持久性提供者,而不是将其设置为静态字段。 –