自动装配任务发送到 Spring TaskExecutor
Posted
技术标签:
【中文标题】自动装配任务发送到 Spring TaskExecutor【英文标题】:Autowiring Tasks sent to Spring TaskExecutor 【发布时间】:2013-04-18 22:56:59 【问题描述】:你怎么会有一个实现Runnable并自动提交给springs TaskExecutor的类?
例如,我有一个任务:
public class MyTask implements Runnable
@Autowired private MyRepository myRepository;
@Override
public void run()
myRepository.doSomething();
还有一个向spring TaskExecutor 发送任务的服务:
@Service
public class MyService
@Autowired private TaskExecutor taskExecutor;
public void someMethod()
MyTask myTask = new MyTask();
taskExecutor.execute(myTask);
我知道这些字段没有被自动连接,因为 MyTask 正在使用 new MyTask() 进行实例化。但是,我该如何解决这个问题?我应该访问 Spring 的 ApplicationContext 并通过它创建 bean 吗?您将如何在 Web 应用程序环境中执行此操作?
谢谢!
【问题讨论】:
【参考方案1】:试试
public class MyTask implements Runnable
private MyRepository myRepository;
public MyTask(MyRepository myRepository)
this.myRepository = myRepository;
@Override
public void run()
myRepository.doSomething();
@Service
public class MyService
@Autowired private TaskExecutor taskExecutor;
@Autowired private MyRepository myRepository;
public void someMethod()
MyTask myTask = new MyTask(myRepository);
taskExecutor.execute(myTask);
或者您可以声明 MyTask 的 scope = "prototype" 并将 MyService 更改为
@Service
public class MyService
@Autowired private ApplicationContext ctx;
public void someMethod()
MyTask myTask = ctx.getBean(MyTask.class);
taskExecutor.execute(myTask);
【讨论】:
是的,这行得通。我希望让自动装配在任务中工作,因为我有很多依赖项并且不想全部传递它们 - 但是,看起来可能没有办法解决它。 @EvgeniyDorofeev 如何将 MyTask 定义为原型? 如果你使用 Spring xml 配置然后添加 scope="prototype" attr 到 MyTask bean 定义【参考方案2】:至少有两种使用 Spring 的好方法。首先,@Configurable 注释。使用这意味着对 AspectJ 的依赖,但它将允许您注入不受 Spring 管理的 bean(即您正在使用 new 运算符)。这将涉及使用 @Configurable 注释 MyTask,并在您的 Spring 配置中添加几行,如链接中所述。
@Configurable
public class MyTask implements Runnable ...
@Service
public class MyService
@Autowired private TaskExecutor taskExecutor;
public void someMethod()
// AspectJ would jump in here and inject MyTask transparently
MyTask myTask = new MyTask();
taskExecutor.execute(myTask);
第二种方法涉及使用 Spring 的 ServiceLocatorFactoryBean 特性来创建原型 bean。这在JavaDoc 中得到了最好的解释,但在这种情况下,您将像任何其他 bean 一样将 TaskFactory 注入到您的 @Service 注释类中,然后执行以下操作:
@Service
public class MyService
@Autowired private TaskExecutor taskExecutor;
@Autowired private MyRepository myRepository;
@Autowired private TaskFactory taskFactory;
public void someMethod()
MyTask myTask = taskFactory.getTask("myTask")
taskExecutor.execute(myTask);
MyTask 已经被注入到您的存储库中,因为您可以在 XML 映射中配置它。我每天都使用这两种方法,但我倾向于使用第二种方法,因为它更易于阅读,并通过确保开发人员不做不易测试的事情来帮助他们保持诚实,坦率地说,它更多对不经意的观察者来说很清楚。
【讨论】:
以上是关于自动装配任务发送到 Spring TaskExecutor的主要内容,如果未能解决你的问题,请参考以下文章
从 Spring 3 升级到 Spring 5 - 现在自动装配错误