2016-02-03 14 views
5

Ho due classi Uploader e UploadTask. Utilizzando Primavera 4.@Async all'interno di una classe Runnerable @Component non consente l'acquisizione automatica

@Service 
public class Uploader{ 
    @Autowired 
    private UploadTask task; 
} 
@Component 
public class UploadTask implements Runnable{ 
    @Async 
    public void soso(){ 
    } 
    public void run(){ 
    } 
} 

all'avvio dell'applicazione ottengo la seguente eccezione:

org.springframework.beans.factory.BeanCreationException: Errore durante la creazione di fagioli con nome 'uploader': Iniezione delle dipendenze autowired fallito ; l'eccezione annidata è org.springframework.beans.factory.BeanCreationException: Impossibile eseguire il campo autowire: private com.xx.uploading.UploadTask com.xx.uploading.Uploader.task; l'eccezione annidata è org.springframework.beans.factory.NoSuchBeanDefinitionException: Nessun bean qualificante di tipo [com.xx.uploading.UploadTask] trovato per dipendenza: atteso almeno 1 bean che si qualifica come candidato autowire per questa dipendenza. annotazioni Dipendenza: {@ org.springframework.beans.factory.annotation.Autowired (richiesto = true), @ org.springframework.beans.factory.annotation.Qualifier (valore = uploadTask)}

Penso che questo possa essere perché UploadTask è un Runnable. Quando ho rimosso l'annotazione @Async, non genera alcuna eccezione. C'è una spiegazione?

Aggiornamento: Quando ho visto i log ho scoperto che il bean di classe UploadTask è stato creato correttamente. Non viene trovato durante l'autowiring.

+1

'@ Async' richiede la creazione di un proxy e, a seconda della configurazione, il proxy è del tipo 'Runnable'. – zeroflagL

+0

Quindi non c'è modo di creare un metodo Async all'interno di un Runnable? – zafar142003

+0

Effettuate prima un'interfaccia 'UploadTask' e lasciate che il componente la implementa o cambi la configurazione del proxy nella vostra configurazione di primavera. Supponendo che questo sia il problema, ovviamente. – zeroflagL

risposta

-1

Avere un setter pubblico per l'attività UploadTask privata; e prova.

+0

Ho menzionato che rimuovere @Async risolve il problema. Quindi non è un problema di un setter pubblico. – zafar142003

0

Utilizzare @EnableAsync a livello di classe.

@Component 
@EnableAsync 
public class UploadTask implements Runnable{ 
    @Async 
    public void soso(){ 
    } 
    public void run(){ 
    } 
} 
+0

@EnableAsync non aiuta. Ad ogni modo avevo già scritto nel file di contesto. Quindi questa annotazione non fa nulla in più. – zafar142003

-1
configure your service classes in the context.xml file. 
like the below codes. 

<bean id="Uploader" class="packageName.Uploader"> 
    <property name="task" ref="task"/> 
</bean> 

<bean id="task" class="packageName.UploadTask "> 
    <property name="xxx" ref="xxx"/> 
</bean> 
change xxx with your datasource name. 
+0

Questo è ridondante. Le annotazioni fanno questo. – zafar142003

1

ho eseguito questo codice con successo. per favore vedi il mio codice qui sotto.

 @Service 
public class Uploader{ 
    @Autowired 
    private UploadTask task; 

    public void display(){ 
     task.run(); 
     task.soso(); 
    } 
} 

@Component 
public class UploadTask implements Runnable{ 
    @Async 
    public void soso(){ 
     System.out.println("Upload task running---"); 
    } 
    public void run(){ 
     System.out.println("Running the class UploadTask---------"); 
    } 
} 

Spring.xml

<mvc:annotation-driven/> 
    <context:component-scan base-package="com.exp" /> 

Qui di seguito è la mia classe di test

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath*:/META-INF/spring/spring.xml"}) 
public class TestScope { 

    @Autowired 
    Uploader uploader = null; 

    @Test 
    public void testScope() 
    { 
     uploader.display(); 

    } 
} 

Qui di seguito è il mio pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>SpringAsync-Exmp</groupId> 
    <artifactId>SpringAsync-Exmp</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.3.2.RELEASE</version> 
    </parent> 

    <properties> 
     <java.version>1.8</java.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.9</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${spring.version}</version> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-databind</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>2.5</version> 
      <scope>provided</scope> 
     </dependency> 

    </dependencies> 


    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

Quando eseguo la classe di test, è stampa con successo il sysout in UploadTask.

UPDATE Ho modificato il codice per l'esecuzione con @EnableAsync. Si prega di vedere sotto il codice modificato.

classe Uploader

@EnableAsync 
@Service 
public class Uploader{ 
    @Autowired 
    private UploadTask uploadTask; 


    public UploadTask getUploadTask() { 
    return uploadTask; 
} 


public void setUploadTask(UploadTask uploadTask) { 
    this.uploadTask = uploadTask; 
} 


public void display(){ 
     uploadTask.run(); 
     uploadTask.soso(); 
    } 
} 

interfaccia UploadTask

@Component 
public interface UploadTask extends Runnable{ 
    @Async 
    public void soso(); 
    public void run(); 
} 

classe UploadTaskImpl

public class UploadTaskImpl implements UploadTask{ 

     public void soso() 
     { 
      System.out.println("Inside the class----"); 
     } 
     public void run() 
     { 
      System.out.println("Inside the class--run--"); 
     } 
} 

Tutti gli altri sono gli stessi. Questa volta ho creato UploaderTask come interfaccia e scrivo una nuova classe per implementarla. Questo risolve il problema.

Penso che @EnableAsync stia convertendo qualsiasi componente usando @Async per il proxy che implementa le stesse interfacce utilizzate da questa classe di componenti, così quando fare autowire con la classe concreta affronterà il conflitto di tipo tra questa classe concreta e il proxy.

+0

Non vedo alcuna aggiunta speciale nella risposta. Cosa dovrei fare per far funzionare il mio caso? Oltre a ciò non hai né @EnableAsync nella tua classe né nel tuo contesto. Il tuo caso non dovrebbe essere in esecuzione senza questo. – zafar142003

+0

Ho modoficato la risposta in base alle vostre esigenze. Si prega di commentare se funziona per voi o no. –

+0

Ci scusiamo, ma anche questo non funziona. – zafar142003