我有两个类Uploader和UploadTask。使用Spring 4.
@Service
public class Uploader{
@Autowired
private UploadTask task;
}
@Component
public class UploadTask implements Runnable{
@Async
public void soso(){
}
public void run(){
}
}
在应用程序启动时,我得到以下异常:
org.springframework.beans.factory.BeanCreationException:创建名为'uploader'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.xx.uploading.UploadTask com.xx.uploading.Uploader.task;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[com.xx.uploading.UploadTask]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true),@ org.springframework.beans.factory.annotation.Qualifier(value = uploadTask)}
我认为这可能是因为UploadTask是一个Runnable。当我删除@Async注释时,它不会抛出任何异常。有解释吗?
更新: 当我看到日志时,我发现正在创建UploadTask类bean。在自动装配期间没有找到它。
答案 0 :(得分:1)
我已成功运行此代码。请参阅下面的代码。
@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" />
以下是我的测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:/META-INF/spring/spring.xml"})
public class TestScope {
@Autowired
Uploader uploader = null;
@Test
public void testScope()
{
uploader.display();
}
}
下面是我的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>
当我运行测试类时,它成功在UploadTask中打印sysout。
<强>更新强> 我已修改编码以使用@EnableAsync运行。请在下面看到修改后的代码。
上传者课程
@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();
}
}
UploadTask接口
@Component
public interface UploadTask extends Runnable{
@Async
public void soso();
public void run();
}
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--");
}
}
所有其他人都一样。这次我创建了UploaderTask作为接口并编写了一个新类来实现它。这解决了这个问题。
我认为@EnableAsync正在使用@Async将任何组件转换为代理实现此组件类使用的相同接口,因此当使用具体类进行autowire时,将面临此具体类与代理之间的类型冲突。
答案 1 :(得分:0)
在班级使用@EnableAsync。
@Component
@EnableAsync
public class UploadTask implements Runnable{
@Async
public void soso(){
}
public void run(){
}
}
答案 2 :(得分:-1)
拥有私有UploadTask任务的公共setter;并测试。
答案 3 :(得分:-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.