Java Spring:如何实例化接受运行时参数的Springbean?
我有一个单例Springbean,它在运行时创建两个任务(Java Spring:如何实例化接受运行时参数的Springbean?,java,spring,parameters,prototype,Java,Spring,Parameters,Prototype,我有一个单例Springbean,它在运行时创建两个任务(java.util.concurrent.Callable),以并行地完成它的工作。现在,Callable被定义为singleton bean中的内部类,singleton bean通过使用new Task(in)实例化它们来创建它们,其中in是一个只有在运行时才知道的参数 现在,我想将内部任务类提取到一个常规的顶级类,因为我想使任务的call()方法具有事务性,所以我需要它是一个Springbean 我想我需要给我的单例提供某种工厂的T
java.util.concurrent.Callable
),以并行地完成它的工作。现在,Callable
被定义为singleton bean中的内部类,singleton bean通过使用new Task(in)
实例化它们来创建它们,其中in
是一个只有在运行时才知道的参数
现在,我想将内部任务类提取到一个常规的顶级类,因为我想使任务的call()
方法具有事务性,所以我需要它是一个Springbean
我想我需要给我的单例提供某种工厂的
Task
s,但是这些任务必须是原型Springbean,以运行时值作为构造函数参数。我怎样才能做到这一点呢?Spring的bean factory和new是相互排斥的。您不能调用new并期望该对象在Spring的控制下
我的建议是将这些任务注入Singleton。也要做春豆
您应该认识到任务本身不是事务,但它的依赖关系可以是事务。将这些注入到任务中,让Spring管理事务。您的单例bean可以从包含Spring的工厂实现BeanFactoryAware和lookup bean
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
public class MyBeanFactory implements BeanFactoryAware {
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory)
throws BeansException {
this.beanFactory = beanFactory;
}
public Task createTask(Task in) {
return beanFactory.getBean("task",in);
}
}
///////////////
import java.util.concurrent.Callable;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Scope;
import org.springframework.transaction.annotation.Transactional;
@Configurable // unless using xml based config
@Scope(value="prototype") // tell bean factory to create new instance each time
public class Task implements Callable<Object> {
private Object in;
public Task(Object in) {
super();
this.in = in;
}
@Transactional
public Object call() throws Exception {
//do real work
return in;
}
}
///
import org.springframework.beans.BeansException;
导入org.springframework.beans.factory.BeanFactory;
导入org.springframework.beans.factory.BeanFactoryAware;
公共类MyBeanFactory实现BeanFactoryAware{
私人豆厂豆厂;
公共工厂(BeanFactory BeanFactory)
抛出BeansException{
this.beanFactory=beanFactory;
}
公共任务createTask(中的任务){
返回beanFactory.getBean(“任务”,in);
}
}
///////////////
导入java.util.concurrent.Callable;
导入org.springframework.beans.factory.annotation.Configurable;
导入org.springframework.context.annotation.Scope;
导入org.springframework.transaction.annotation.Transactional;
@可配置//除非使用基于xml的配置
@Scope(value=“prototype”)//每次告诉bean工厂创建新实例
公共类任务实现了可调用{
私人物品;
公共任务(中的对象){
超级();
this.in=in;
}
@交易的
公共对象调用()引发异常{
//干实事
返回;
}
}
///
另一种方法可能是使用Spring的@可配置的
注释和加载时编织,这样您就可以使用new
(而不是bean工厂)在运行时创建有线可调用的:
@Configurable
public class WiredTask implements Callable<Result> {
@Autowired
private TaskExecutor executor;
public WiredTask(String in) {
this.in = in;
}
public Result call() {
return executor.run(in);
}
}
@Bean @Scope("prototype")
public class TaskExecutor() {
@Transactional
public Result run(String in) {
...
}
}
// Example of how you might then use it in your singleton...
ExecutorService pool = Executors.newFixedThreadPool(3);
WiredTask task = new WiredTask("payload");
Future<Result> result = pool.submit(task);
@可配置
公共类WiredTask实现了可调用{
@自动连线
私人任务执行者;
公共WiredTask(字符串输入){
this.in=in;
}
公共结果调用(){
返回执行器。运行(in);
}
}
@Bean@Scope(“原型”)
公共类任务执行器(){
@交易的
公共结果运行(字符串输入){
...
}
}
//然后你可以在你的单身生活中使用它的例子。。。
ExecutorService池=Executors.newFixedThreadPool(3);
WiredTask任务=新的WiredTask(“有效负载”);
未来结果=池。提交(任务);
有关更多信息,请参阅。注意,您不能使用,因此需要两个类。因此,如果您有许多不同的Callable实现,这可能不是理想的解决方案(因为每个实现需要两个类)。@BorisTreukhov:这不是关于测试多线程应用程序的问题,而是关于Spring的问题。事实上,我将从我的问题中删除reason#2,因为它会分散对真实问题的注意力。请看:@Bossie ok我删除了我的评论,顺便说一句,我认为最简单的方法是创建单独的服务bean,将它们的方法装饰为事务性的,将它们注入到您的单例中,并将“In”参数传递给服务方法。+1表示KISS。没有理由让事情变得更加困难,只需创建事务性服务并将其注入到任务中。“Spring的bean factory和new是相互排斥的。”这对大多数人来说似乎是显而易见的,但对于一个Spring新手来说,这对我来说非常重要。它帮助我理解了spring的实际功能,但是如果我不知道任务的数量呢?也就是说,有人提交了一份带有数字的作业,比如说10,而我实例化了10个任务?您能告诉我在这种情况下如何将任务注入Singleton吗?您应该创建一个执行者池,让他们处理您的任务。忘掉单身汉,学习春天。