java - Can I use Spring @Autowired in multiple classes? -


my question - can autowire instance of class in multiple classes?

my application uses spring mvc communicate between jsp front end pages , mongodb end. using mongodb repository. have created service performs crud methods mongodb. can seen below 1 of crud methods (not shown not needed). uses mongo template.

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 unique mongo id , insert document  * 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 = 0; i<ids.length; i++) {         nohyphens = nohyphens.concat(ids[i]);     }      sensor.setid(nohyphens);     mongotemplate.insert(sensor, collection); } 

as can seen, mongotemplate autowired. in dispatcher-servlet have following code mongodb:

<?xml version="1.0" encoding="utf-8"?> <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">  <context:component-scan base-package="usm" />  <!-- factory bean creates mongo instance --> <bean id="mongo" class="org.springframework.data.mongodb.core.mongofactorybean">     <property name="host" value="localhost" /> </bean>  <!-- mongotemplate connecting , querying documents in database --> <bean id="mongotemplate" class="org.springframework.data.mongodb.core.mongotemplate">     <constructor-arg name="mongo" ref="mongo" />     <constructor-arg name="databasename" value="usmdb" /> </bean>  <!-- use post processor translate mongoexceptions thrown in @repository annotated classes --> <bean class="org.springframework.dao.annotation.persistenceexceptiontranslationpostprocessor" />     <bean id="jspviewresolver"       class="org.springframework.web.servlet.view.internalresourceviewresolver"       p:prefix="/web-inf/jsp/"       p:suffix=".jsp" />      <mvc:resources mapping="/resources/**" location="/resources/" />  <mvc:annotation-driven /> 

i have controller has autowired service requests jsp page can passed controller, , controller writes these requests database via autowired service. (one example method shown below class massive). autowired service doesn't have in dispatcher servlet mongodb autowired previously.

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 post method achieved via save, check if reading  * exists , update. else, create new sensor. redirect 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"); } 

the sensorreadingservice method runs perfectly, performing crud methods on database. now question is, how use sensorreadingservice in class? when add

//mongodb service @autowired private sensorreadingservice sensorreadingservice; 

into class, service doesn't work. no errors flung, service not add database. because @autowired allows class autowired in 1 class i.e. there can't multiple instances? or because haven't specified in dispatcher-servlet mongodb?

the reason need have work in class in class, listening serial events. when there data available, create new thread deal serial event rest of program can still function. in thread, parse string received serial, create new sensorreading object, , want write sensorreading object database. however, cannot sensorreadingservice work in other classes, can't perform write database.

first used class implements runnable perform parsing , saving. having @autowired in class did not work, tried passing sensorreadingservice thread controller (shown in code below). did not work either. changed thread implement callable return sensorreading , save database in original controller class has working autowired service. however, defeats purpose of creating thread in first place writing database wish perform in thread, slows down whole program if not.

 @override public void serialevent(serialportevent oevent) {     if (oevent.geteventtype() == serialportevent.data_available) {                   //use thread in thread pool        //tried passing sensorreadingservice thread did not work         //threadpool.execute(new realtimethread(input, sensorreadingservice, getrealtimeidsandnames()));          //tried return sensor reading. works slows down program.         callable<list<sensorreading>> callable = new realtimethread(input, getrealtimeidsandnames(), offset, sensitivity);         future<list<sensorreading>> future = threadpool.submit(callable); 

so, wondering if knew doing wrong @autowired? can have multiple instances of @autowired? need add in dispatcher servlet? or should not use @autowired , try call service way?

any suggestions appreciated , if need me post anymore code let me know! in advance!

edit:

for realtimethread class have following code

import org.springframework.beans.factory.annotation.autowired; import usm.service.sensorreadingservice;   public class realtimethread implements callable<list<sensorreading>> {  //mongodb service @autowired private sensorreadingservice sensorreadingservice;  //fed inputstreamreader convert bytes strings bufferedreader input;  //variables getting data real time arraylist<byte> values = new arraylist<byte>(); //mappings sensors double[] offset; double[] sensitivity;  map<string, string> realtimeids;  public realtimethread(bufferedreader input, map<string, string> rt, double[] offset, double[] sens) {     this.input = input;     realtimeids = rt;     this.offset = offset;     this.sensitivity = sens; }  //split line, parse , add database @override public list<sensorreading> call() throws exception {     list<sensorreading> toreturn = new arraylist<sensorreading>();          string inputline;         if((inputline = input.readline()) != null) {              //pass scanner             scanner scan = new scanner(inputline);               //get after starting pattern              pattern pstart = pattern.compile("\\x02\\x02\\x02\\x02\\x02(.*)");              matcher mstart = pstart.matcher(inputline);             if ( mstart.find() ) {                inputline = mstart.group(1);                 //get before ending pattern                pattern pend = pattern.compile("(.*)\\x04\\x04\\x04\\x04\\x04");                 matcher mend = pend.matcher(inputline);                if ( mend.find() ) {                    inputline = mend.group(1); // " awesome"                     //split string                    scan = new scanner(inputline);                     //set delimiter unit separator                    pattern delim = pattern.compile("\\x1f");                     scan.usedelimiter(delim);                      while(scan.hasnext()) {                        //get next string                        string s = scan.next();                         //change integer , make byte                        int val = integer.parseint(s);                        byte b = (byte) val;                         //add arraylist                        values.add(b);                    }                      //parse values                    toreturn = parser(values);                    // system.out.println("return 0 " + toreturn.get(1).getrawvalue());                     //reset arraylist                    values = new arraylist<byte>();                 }                               }         }      return toreturn; }  //parser split line, create new sensor reading , add database private list<sensorreading> parser(arraylist<byte> data) {      //arraylist data after transformation     arraylist<short> converteddata = new arraylist<short>();      //get data in big endian      (int = 0; i<46; i=i+2) {      ... ...         converteddata.add(datachunk);     }      //get time     double mytime = system.currenttimemillis();      arraylist<sensorreading> toreturn = new arraylist<sensorreading>();  //add database     for(int = 0; i<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 database - not working          sensorreadingservice.addsensorreadingintocollection(sr, "realtime");         system.out.println("added");          toreturn.add(sr);     }      return toreturn; } } 

when trying create bean either in xml or using @component beancreationexception saying there no default empty constructor. have constructor has inputs it. how make spring use constructor?

i tried using @autowired on constructor have got error saying not autowire field bufferedinput. suggestions? thanks!

edit:

i have used @component on realtimethread class , @autowired on constructor. errors getting follows:

[localhost-startstop-1] error org.springframework.web.context.contextloader - context initialization failed org.springframework.beans.factory.unsatisfieddependencyexception: error creating bean 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 index 0 of type [java.io.bufferedreader]: : no qualifying bean of type [java.io.bufferedreader] found dependency: expected @ least 1 bean qualifies autowire candidate dependency. dependency annotations: {}; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [java.io.bufferedreader] found dependency: expected @ least 1 bean qualifies autowire candidate dependency. dependency annotations: {} 

so gather bufferedreader not handled spring? passing bufferedreader in controller class follows:

@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 thread in thread pool         //threadpool.execute(new realtimethread(input, sensorreadingservice, getrealtimeidsandnames()));          //input.readline();          callable<list<sensorreading>> callable = new realtimethread(input, getrealtimeidsandnames(), offset, sensitivity);         future<list<sensorreading>> future = threadpool.submit(callable); 

i thought because passing these variables controller, spring dealt them. guess not. how make spring manage these variables? use @autowired above them have done service?

the problem seems class in sensorreadingservice being autowired into, not class managed spring. autowiring work, class requires wiring needs have it's lifecycle managed spring (meaning need have entry class in spring xml of spring java config)

you refactor code this:

1) add constructor argument realtimethread going of type sensorreadingservice.

2) create class realtimethreadfactory so:

public class realtimethreadfactory {      private final sensorreadingservice sensorreadingservice;      public realtimethreadfactory(sensorreadingservice sensorreadingservice) {         this.sensorreadingservice = sensorreadingservice;     }      public realtimethread getobject(bufferedreader input, map<string, string> rt, double[] offset, double[] sens) {           return new realtimethread(input, rt, offset, sens, sensorreadingservice);     } } 

3) add java config class somewhere under package being included in component scan

@configuration public class realtimethreadconfig {      @autowired     private sensorreadingservice sensorreadingservice;      @bean     public realtimethreadfactory realtimethreadfactory() {         realtimethreadfactory realtimethreadfactory = new realtimethreadfactory(sensorreadingservice);         return realtimethreadfactory;     }  } 

4) class current code creating realtimethread needs spring bean (using way prefer) , injected realtimethreadfactory. in order create realtimethread objects , simple call getobject() method on factory appropriate arguments


Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

javascript - Using Windows Media Player as video fallback for video tag -

c# - Unity IoC Lifetime per HttpRequest for UserStore -