title: Can I use Spring @Autowired in multiple classes?
body: <p>My question is - <strong>Can I autowire an instance of a class in multiple classes?</strong> </p>
  
  <p>My application uses Spring MVC to communicate between the JSP front end pages and my MongoDB back end. I am using MongoDB for my repository. I have created a service which performs the CRUD methods for MongoDB. This can be seen below with one of the CRUD methods (not all are shown as they are not needed). It uses the Mongo template. </p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Scope;
  import org.springframework.data.mongodb.core.MongoTemplate;
  import org.springframework.stereotype.Repository;
  
  @Repository
  public class SensorReadingService {
  
  @Autowired
  private MongoTemplate mongoTemplate;
  
  /**
   * Create a unique mongo id and insert the document into
   * the collection specified. If collection doesn't exist, 
   * create it.
   * @param sensor
   */ 
  public void addSensorReadingIntoCollection(SensorReading sensor, String collection)  {
      if (!mongoTemplate.collectionExists(SensorReading.class)) {
          mongoTemplate.createCollection(SensorReading.class);
      }
  
      String id = UUID.randomUUID().toString();
  
      String[] ids = id.split("-");
  
      String noHyphens = "";
  
      for(int i = 0; i&lt;ids.length; i++) {
          noHyphens = noHyphens.concat(ids[i]);
      }
  
      sensor.setId(noHyphens);
      mongoTemplate.insert(sensor, collection);
  }
  </code></pre>
  
  <p>As can be seen, the MongoTemplate is autowired. In my Dispatcher-Servlet I have the following code for MongoDB:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"&gt;
  
  &lt;context:component-scan base-package="usm" /&gt;
  
  &lt;!-- Factory bean that creates the Mongo instance --&gt;
  &lt;bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean"&gt;
      &lt;property name="host" value="localhost" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- MongoTemplate for connecting and querying the documents in the database --&gt;
  &lt;bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"&gt;
      &lt;constructor-arg name="mongo" ref="mongo" /&gt;
      &lt;constructor-arg name="databaseName" value="USMdb" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes --&gt;
  &lt;bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /&gt;   
  
  &lt;bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/WEB-INF/jsp/"
        p:suffix=".jsp" /&gt;    
  
  &lt;mvc:resources mapping="/resources/**" location="/resources/" /&gt;
  
  &lt;mvc:annotation-driven /&gt;
  </code></pre>
  
  <p></p>
  
  <p>I now also have a controller which has autowired the service so that requests from the JSP page can be passed to the controller, and the controller then writes these requests to the database via the autowired service. (One example method shown below as the class is massive). This autowired service doesn't have anything in the dispatcher servlet like the MongoDB autowired previously. </p>
  
  <pre><code>import gnu.io.SerialPortEventListener;
  import gnu.io.CommPortIdentifier;
  import gnu.io.SerialPort;
  import gnu.io.SerialPortEvent;
  import gnu.io.SerialPortEventListener;
  
  import java.util.concurrent.Callable;
  import java.util.concurrent.ExecutionException;
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  import java.util.concurrent.Future;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Controller;
  
  @Controller
  public class SensorReadingController implements SerialPortEventListener {
  
  //mongodb service
  @Autowired
  private SensorReadingService sensorReadingService;
  
      /**
   * When a post method is achieved via save, check if reading already
   * exists and update. Else, create new sensor. Redirect back to post race
   * page.
   * @param sensorReading
   * @param model
   * @return post race page
   */
  @RequestMapping(value = "/postRace-save", method = RequestMethod.POST)
  public View createSensorReading(@ModelAttribute SensorReading sensor, ModelMap model,@RequestParam(value="colName", required=true)String name) {
      if (StringUtils.hasText(sensor.getId())) {
          sensorReadingService.updateSensorReading(sensor, name);
      }
      else {
          sensorReadingService.addSensorReading(sensor);
      }
      return new RedirectView("/USM-Analysis-Application/postRace");
  }
  </code></pre>
  
  <p>The sensorReadingService method runs perfectly, performing CRUD methods on the database. <strong>Now my question is, how do I use this sensorReadingService in another class?</strong> When I add</p>
  
  <pre><code>//mongodb service
  @Autowired
  private SensorReadingService sensorReadingService;
  </code></pre>
  
  <p>into another class, the service doesn't work. No errors are flung, the service just does not add anything to the database. Is it because @Autowired only allows the class to be autowired in one class i.e. there can't be multiple instances? Or is it because I haven't specified anything in my dispatcher-servlet like with the MongoDB?</p>
  
  <p>The reason I need to have it work in another class is that in my class, I am listening for Serial events. When there is data available, I create a new thread to deal with this serial event so that the rest of my program can still function. In the thread, I parse the string I received from Serial, create a new SensorReading object, and then I want to write this SensorReading object to the database. However, as I cannot get sensorReadingService to work in any other classes, I can't perform this write to database. </p>
  
  <p>First I used a class that implements Runnable to perform the parsing and saving. Having @Autowired in this class did not work, so I tried passing the sensorReadingService to the thread from the controller (shown in code below). This did not work either. I then changed my thread to implement Callable so I could return the SensorReading and save it to the database in my original controller class that has the working autowired service. However, this defeats the purpose of creating the thread in the first place as it is the writing to the database I wish to perform in the thread, as it slows down the whole program if not. </p>
  
  <pre><code> @Override
  public void serialEvent(SerialPortEvent oEvent) {
      if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {          
          //use a thread in the thread pool
         //tried passing sensorReadingService to thread but did not work
          //threadPool.execute(new RealTimeThread(input, sensorReadingService, getRealTimeIdsAndNames()));
  
          //tried return sensor reading. This works but slows down the program.
          Callable&lt;List&lt;SensorReading&gt;&gt; callable = new RealTimeThread(input, getRealTimeIdsAndNames(), offset, sensitivity);
          Future&lt;List&lt;SensorReading&gt;&gt; future = threadPool.submit(callable);
  </code></pre>
  
  <p>So, I was just wondering if anyone knew what I was doing wrong with @Autowired? <strong>Can I have multiple instances of @Autowired? Do I need to add something in my dispatcher servlet? Or should I just not use @Autowired and try to call my service another way?</strong> </p>
  
  <p>Any suggestions would be much appreciated and if you need me to post anymore code let me know! Thanks in advance! </p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>For my RealTimeThread class I have the following code</p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import usm.service.SensorReadingService;
  
   public class RealTimeThread implements Callable&lt;List&lt;SensorReading&gt;&gt; {
  
  //mongodb service
  @Autowired
  private SensorReadingService sensorReadingService;
  
  //fed by an InputStreamReader to convert bytes to strings
  BufferedReader input;
  
  //variables for getting data from real time
  ArrayList&lt;Byte&gt; values = new ArrayList&lt;Byte&gt;();
  //mappings for sensors
  double[] offset;
  double[] sensitivity;
  
  Map&lt;String, String&gt; realTimeIDs;
  
  public RealTimeThread(BufferedReader input, Map&lt;String, String&gt; rt, double[] offset, double[] sens) {
      this.input = input;
      realTimeIDs = rt;
      this.offset = offset;
      this.sensitivity = sens;
  }
  
  //Split up the line, parse it and add to database
  @Override
  public List&lt;SensorReading&gt; call() throws Exception {
      List&lt;SensorReading&gt; toReturn = new ArrayList&lt;SensorReading&gt;();
  
          String inputLine;
          if((inputLine = input.readLine()) != null) {
  
              //pass to the scanner
              Scanner scan = new Scanner(inputLine); 
  
              //get everything after the starting pattern 
              Pattern pStart = Pattern.compile("\\x02\\x02\\x02\\x02\\x02(.*)"); 
              Matcher mStart = pStart.matcher(inputLine);
              if ( mStart.find() ) {
                 inputLine = mStart.group(1);
  
                 //get everything before ending pattern
                 Pattern pEnd = Pattern.compile("(.*)\\x04\\x04\\x04\\x04\\x04"); 
                 Matcher mEnd = pEnd.matcher(inputLine);
                 if ( mEnd.find() ) {
                     inputLine = mEnd.group(1); // " that is awesome"
  
                     //split up this string
                     scan = new Scanner(inputLine);
  
                     //set the delimiter to unit separator
                     Pattern delim = Pattern.compile("\\x1F"); 
                     scan.useDelimiter(delim); 
  
                     while(scan.hasNext()) {
                         //get the next string
                         String s = scan.next();
  
                         //change it to an integer and make it a byte
                         int val = Integer.parseInt(s);
                         byte b = (byte) val;
  
                         //add to the arraylist
                         values.add(b);
                     } 
  
                     //parse the values
                     toReturn = parser(values);
  
                    // System.out.println("RETURN 0 " + toReturn.get(1).getRawValue());
  
                     //reset the arraylist
                     values = new ArrayList&lt;Byte&gt;();
                  }                  
              }
          }
  
      return toReturn;
  }
  
  //Parser to split up line, create a new sensor reading and add to database
  private List&lt;SensorReading&gt; parser(ArrayList&lt;Byte&gt; data) {
  
      //arraylist for data after transformation
      ArrayList&lt;Short&gt; convertedData = new ArrayList&lt;Short&gt;();
  
      //get all data in big endian 
      for (int i = 0; i&lt;46; i=i+2) {
  
      ...
  ...
          convertedData.add(dataChunk);
      }
  
      //get the time now
      double myTime = System.currentTimeMillis();
  
      ArrayList&lt;SensorReading&gt; toReturn = new ArrayList&lt;SensorReading&gt;();
  
  //add to the database
      for(int i = 0; i&lt;convertedData.size(); i++) {
          //create new sensor reading
          SensorReading sr = new SensorReading();
          sr.setSensorId(keys[i].toString());
          sr.setName(sens.get(keys[i]));
          sr.setRawValue(convertedData.get(i));
          sr.setTime(myTime);
  
          //add to database - this is not working 
          sensorReadingService.addSensorReadingIntoCollection(sr, "realTime");
          System.out.println("added");
  
          toReturn.add(sr);
      }
  
      return toReturn;
  }
  }
  </code></pre>
  
  <p>When trying to create a bean either in my XML or using @Component I get a BeanCreationException saying that there is no default empty constructor. I have a constructor but it has inputs into it. <strong>How do I make Spring use this constructor?</strong></p>
  
  <p>I tried using @Autowired on the constructor I have but I got an error saying that it could not autowire field BufferedInput. Any suggestions? Thanks!</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I have used @Component on my RealTimeThread class and @Autowired on my constructor. Now the errors I am getting are as follows:</p>
  
  <pre><code>[localhost-startStop-1] ERROR org.springframework.web.context.ContextLoader - Context
  initialization failed
  org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'realTimeThread' defined in file [C:\Users\Lauren\Dropbox\MEng Project\1. Off-board Software\Lauren\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\USM-Analysis-Application\WEB-INF\classes\usm\model\RealTimeThread.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.io.BufferedReader]: : No qualifying bean of type [java.io.BufferedReader] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.io.BufferedReader] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
  </code></pre>
  
  <p>So what I gather from this is that my BufferedReader is not handled by Spring? I am passing my BufferedReader in from my Controller class as follows:</p>
  
  <pre><code>@Controller
  public class SensorReadingController implements SerialPortEventListener {
  
  //mongodb service
  @Autowired
  private SensorReadingService sensorReadingService;
  
  private BufferedReader input;
  double[] offset;
  double[] sensitivity;
  
  ...
  
  @Override
  public void serialEvent(SerialPortEvent oEvent) {
      if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {          
          //use a thread in the thread pool
          //threadPool.execute(new RealTimeThread(input, sensorReadingService, getRealTimeIdsAndNames()));
  
          //input.readLine();
  
          Callable&lt;List&lt;SensorReading&gt;&gt; callable = new RealTimeThread(input, getRealTimeIdsAndNames(), offset, sensitivity);
          Future&lt;List&lt;SensorReading&gt;&gt; future = threadPool.submit(callable);
  </code></pre>
  
  <p>I thought that because I was passing these variables from the controller, Spring already dealt with them. But I guess not. <strong>How do I make Spring manage these variables?</strong> Do I just use @Autowired above them like I have done with my service?</p>