如何自动装配Spring TaskExecutor创建的线程?

时间:2012-08-02 23:34:00

标签: java multithreading spring autowired

根据Spring's documentation,使用TaskExecutor的方法如下:

import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {

  private class MessagePrinterTask implements Runnable {

    private String message;

    public MessagePrinterTask(String message) {
      this.message = message;
    }

    public void run() {
      System.out.println(message);
    }

  }

  private TaskExecutor taskExecutor;

  public TaskExecutorExample(TaskExecutor taskExecutor) {
    this.taskExecutor = taskExecutor;
  }

  public void printMessages() {
    for(int i = 0; i < 25; i++) {
      taskExecutor.execute(new MessagePrinterTask("Message" + i));
    }
  }
}

但是,如果MessagePrinterTask具有自动连接的依赖关系,它们将不会被Spring配置,因为我们在Spring的上下文之外实例化我们的bean(至少我是如何理解它),即使Spring将提供实际的线程创建。 如果MessagePrinterTask具有自动连接的依赖关系,我们如何让Spring识别它们?我尝试了以下修改示例无效(是的,正确启用了自动装配):

import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {

  @Component
  private class MessagePrinterTask implements Runnable {

    @Autowired
    private autoWiredDependency;

    public void run() {
      autoWiredDependency.doNotThrowNullPointerExceptionPlease();
    }

  }

  private TaskExecutor taskExecutor;

  public TaskExecutorExample(TaskExecutor taskExecutor) {
    this.taskExecutor = taskExecutor;
  }

  public void printMessages() {
    for(int i = 0; i < 25; i++) {
      taskExecutor.execute(new MessagePrinterTask());
    }
  }
}

3 个答案:

答案 0 :(得分:16)

我认为有两种方法可以解决这个问题:

一个。提供任务的依赖关系 - 这样:

class MessagePrinterTask implements Runnable {
    public MessagePrinterTask(ADependency aDependency){
        this.aDependency = aDependency;
    }


    private ADependency aDependency;

    public void run() {
        aDependency.doNotThrowNullPointerExceptionPlease();
    }
}

在你的TaskExectorExample中可以是单身人士:

import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {

  @Autowired  private ADependency aDependency;

  @Autowired
  public TaskExecutorExample(TaskExecutor taskExecutor) {
    this.taskExecutor = taskExecutor;
  }

  public void printMessages() {
    for(int i = 0; i < 25; i++) {
      taskExecutor.execute(new MessagePrinterTask(this.aDependency));
    }
  }
}

湾在MesasgePrinterTask上使用@Configurable注释,这会将依赖注入到MessagePrinterTask中,即使它是在Spring容器之外实例化的 - 尽管使用@Configurable(需要AspectJ)仍有一些问题:

@Configurable
class MessagePrinterTask implements Runnable {

答案 1 :(得分:3)

您也可以使用@Async注释。

public class TaskExecutorExample {

    @Autowired
    private MessagePrinterTask task;

    public void printMessages() {
        for(int i = 0; i < 25; i++) {
            task.printMessage();
        }
    }
}

@Component
public class MessagePrinterTask implements Runnable {

    @Autowired
    private String message;

    @Async
    public void printMessage() {
      System.out.println(message);
    }

}

对printMessage()的任何调用都将使用默认执行程序异步执行,您可以使用Spring xml配置中的以下内容进行配置。

<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5" />

答案 2 :(得分:0)

尝试此方法。

@Service
@Scope("prototype")
public invokeClass {

    @Autowired
    private ApplicationContext applicationContext;



    public void methodName(TestRequest input){
        TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();

        taskExecutor.execute(new Runnable() {
            public void run() {

                applicationContext.getBean("testService", TestService.class).execute(input);
            }
        });
    }
}