title: Share information between Spring components
body: <p>I am trying to build an app where I implement a rather simple pattern: I have a websocket server that receives streaming data from a number of clients. This data is then stored so that it can be served through a RESTful API. I want to have some sort of interface that both the WS server and the REST API can access to both store and request the latest data.</p>
  
  <p>To present a simplified case:</p>
  
  <p>I have 10 connected gadgets that are streaming messages over a websocket connection. Each one of them is streaming to /ingest/{ID}. I then have a REST API that returns latest message on the /latest/{ID}.</p>
  
  <ol>
  <li>Is this the correct design pattern to go for?</li>
  <li>If so, how do I implement it using as much of the Spring framework as possible?</li>
  </ol>
  
  <p>I am imagining that I need to do the following:</p>
  
  <p>I will have one class with the <code>main(String args[])</code> method. This will then run itself and the Spring framework will pick up the different components- the WebSocket endpoint, the REST endpoint, and the DataCache class.</p>
  
  <p>How do I give the correct instance of my DataCache class to the WebSocket and the REST endpoint?</p>
  
  <pre><code>        @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);
              }
          }
  </code></pre>
  
  <p>Then, I would have the following code in each of the component classes:</p>
  
  <pre><code>    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());
      }
  
  
  }
  </code></pre>
  
  <p>Then, the rest endpoint will look something like this:</p>
  
  <pre><code>@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;
      }
  }
  </code></pre>