Spring自动装配参数化的泛型类型 [英] Spring autowiring parameterized generic types
问题描述
Spring 4包含了泛型类型解析的主要增强功能,但是当type参数在包含bean类上进行参数化时,我在自动装配泛型类型时遇到麻烦。
我需要跟踪提交给外部服务的作业状态,并且我希望在每个作业启动时创建一个条目,并在收到回发时清除或更新作业。我通常尝试将持久性策略与服务接口分开,所以我有一个接口 JobStatus
和一个Spring Data Mongo类 MongoJobStatus实现了JobStatus code>。由于在外部服务有机会为其分配一个ID(例如HTTP 502)之前,作业可能会失败,所以我需要将
JobStatus
传递回服务以识别更新:
界面JobStatusService< S扩展JobStatus> {
S beginJob(...);
S updateJobStatus(S targetJob,Status newStatus);
void finishJob(S targetJob);
$ b相应地,我的Spring控制器可以处理关闭作业并记录回发的外观喜欢这个;控制器类携带一个类型参数,以便我可以存储新的状态对象并将其传递回服务:
@Controller
public class JobController< JS扩展JobStatus> {
@Autowired JobStatusService< JS> jobService;
...处理方法...
JS status = jobService.createJob(info,go,here);
//通过HTTP提交作业
jobService.updateJobStatus(status,Status.PROCESSING);
...
}
我的MongoDB支持的实现如下所示:
public class MongoJobStatusService实现JobStatusService< MongoJobStatus> {
MongoJobStatus beginJob(...){...}
MongoJobStatus updateJobStatus(MongoJobStatus作业,状态newStatus){...}
}
当我尝试启动时,Spring上下文失败, NoSuchBeanDefinitionException
代替 JobStatusService
。我已经证实,如果我设置了 required = false
,那么 MongoJobStatusService
bean被正确的组件扫描并安装在上下文中,但Spring似乎无法理解该类实现了该参数化的泛型接口。
有什么办法可以指定Spring需要一个bean实现一个类型参数的泛型接口,它在包含bean级别参数化,而不是在字段级别嵌入为字面类型参数?
Spring容器似乎无法解析控制器类上的可接受类型参数,但如果明确提供了这些类型参数,它可以解决注入字段。通过继承控制器类的字面类型,我已经能够非常理想地解决这个问题:
@Controller
公共类MongoJobController< MongoJobStatus> {}
我有为此打开了一个JIRA问题,并且 GitHub上的一个简单示例。
Spring 4 included major enhancements to generic type resolution, but I'm having trouble with autowiring a generic type when the type argument is parameterized on the containing bean class.
I am needing to track the status of jobs submitted to an outside service, and I want to create an entry for each job when it starts and clear or update it when I receive postbacks. I generally try to keep my persistence strategy separated from the service interface, so I have an interface JobStatus
and a Spring Data Mongo class MongoJobStatus implements JobStatus
. Since a job might fail before the outside service gets a chance to assign it an ID (e.g., an HTTP 502), I need to pass the JobStatus
back to the service to identify for updates:
interface JobStatusService<S extends JobStatus> {
S beginJob(...);
S updateJobStatus(S targetJob, Status newStatus);
void finishJob(S targetJob);
}
Accordingly, my Spring controller that handles firing off the jobs and recording the postbacks looks like this; the controller class carries a type parameter so that I can store the new status object and pass it back to the service:
@Controller
public class JobController<JS extends JobStatus> {
@Autowired JobStatusService<JS> jobService;
... handler method ...
JS status = jobService.createJob(info, goes, here);
// submit job via HTTP
jobService.updateJobStatus(status, Status.PROCESSING);
...
}
My MongoDB-backed implementation looks like this:
public class MongoJobStatusService implements JobStatusService<MongoJobStatus> {
MongoJobStatus beginJob(...) {...}
MongoJobStatus updateJobStatus(MongoJobStatus job, Status newStatus) {...}
}
When I try to launch, the Spring context fails with NoSuchBeanDefinitionException
for JobStatusService
. I have confirmed that if I set required=false
, the MongoJobStatusService
bean is properly component-scanned and installed in the context, but Spring doesn't seem to be able to understand that the class implements that parameterized generic interface.
Is there any way to specify to Spring that I need a bean implementing a generic interface with a type argument that is parameterized at the containing bean level instead of embedded as a literal type argument on the field level?
The Spring container does not appear to be able to solve for acceptable type parameters on the controller class, but it can solve for the injected field if those type parameters are supplied explicitly. I have been able to suboptimally work around the problem by subclassing the controller class with a literal type:
@Controller
public class MongoJobController<MongoJobStatus> {}
I have opened a JIRA issue for this and have a minimal example on GitHub.
这篇关于Spring自动装配参数化的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!