你怎么能有一个实现Runnable并提交给弹簧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正在使用新的MyTask()进行实例化。但是,我该如何解决这个问题呢?我是否应该访问Spring的ApplicationContext并通过它创建bean?您将如何在Web应用程序环境中执行此操作?
谢谢!
答案 0 :(得分:11)
试
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);
}
}
答案 1 :(得分:4)
使用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中得到了最好的解释,但在这种情况下,你会将一个TaskFactory注入到@Service注释类中,就像任何其他bean一样,然后执行类似的操作:
@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映射中对其进行配置。我每天都使用这两种方法,但我更倾向于使用这两种方法,因为它更容易阅读,并通过确保他们不做不容易测试的事情来帮助保持开发人员的诚实,坦白说,更多对于不经意的观察者来说很清楚。