Spring 4包含对泛型类型解析的主要增强,但是当在包含bean类上参数化类型参数时,我在自动装配泛型类型方面遇到了麻烦。
我需要跟踪提交到外部服务的作业的状态,我想在每个作业启动时创建一个条目,并在收到回发时清除或更新它。我通常会尝试将持久性策略与服务接口分开,因此我有一个接口JobStatus
和一个Spring Data Mongo类MongoJobStatus implements JobStatus
。由于作业可能在外部服务有机会为其分配ID(例如,HTTP 502)之前失败,因此我需要将JobStatus
传递回服务以识别更新:
interface JobStatusService<S extends JobStatus> {
S beginJob(...);
S updateJobStatus(S targetJob, Status newStatus);
void finishJob(S targetJob);
}
因此,我的Spring控制器可以处理作业并记录回发,就像这样;控制器类带有一个类型参数,以便我可以存储新的状态对象并将其传递回服务:
@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);
...
}
我的MongoDB支持的实现如下所示:
public class MongoJobStatusService implements JobStatusService<MongoJobStatus> {
MongoJobStatus beginJob(...) {...}
MongoJobStatus updateJobStatus(MongoJobStatus job, Status newStatus) {...}
}
当我尝试启动时,Spring上下文失败,NoSuchBeanDefinitionException
为JobStatusService
。我已经确认,如果我设置required=false
,MongoJobStatusService
bean正确地进行组件扫描并安装在上下文中,但Spring似乎无法理解该类实现了参数化通用接口。
有没有办法向Spring指定我需要一个bean实现一个泛型接口,该接口的类型参数在包含bean级别进行参数化,而不是作为字段级别的文字类型参数嵌入?
答案 0 :(得分:2)
尝试添加:
@Autowired
@Qualifier("mongoJobStatusService")
JobStatusService<JS> jobService;
并指定MongoJobStatusService
bean的名称。
答案 1 :(得分:1)
Spring容器似乎无法解决控制器类上可接受的类型参数,但如果显式提供了这些类型参数,它可以解决注入的字段。通过使用文字类型对控制器类进行子类化,我能够通过次优解决问题:
@Controller
public class MongoJobController<MongoJobStatus> {}
答案 2 :(得分:1)
事实上Spring并没有找到匹配Bean,可能导致JobStatusService处于高水平。
尝试在MongoJobStatusService和JobStatusService之间添加其他接口,如下所示
public class MongoJobStatusService implements IMongoJobStatusService {
..}
public interface IMongoJobStatusService implements JobStatusService<MongoJobStatus> {
...
}
我有同样的问题(Spring autowire trouble with generic parameter),我就这样解决了......