1

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 上下文因NoSuchBeanDefinitionExceptionfor失败JobStatusService。我已经确认,如果我设置required=falseMongoJobStatusServicebean 会被正确地组件扫描并安装在上下文中,但 Spring 似乎无法理解该类实现了该参数化的通用接口。

有什么方法可以向 Spring 指定我需要一个实现泛型接口的 bean,该接口具有在包含 bean 级别参数化的类型参数,而不是作为字段级别的文字类型参数嵌入?

4

3 回答 3

2

尝试添加:

 @Autowired 
 @Qualifier("mongoJobStatusService")
 JobStatusService<JS> jobService;

并指定MongoJobStatusServicebean的名称。

于 2014-04-04T08:12:42.137 回答
1

Spring 容器似乎无法解决控制器类上可接受的类型参数,但如果显式提供这些类型参数,它可以解决注入字段。通过使用文字类型对控制器类进行子类化,我能够以次优方式解决该问题:

@Controller
public class MongoJobController<MongoJobStatus> {}

我为此打开了一个 JIRA 问题,并在 GitHub 上有一个最小的示例。

于 2014-04-04T16:38:14.707 回答
1

实际上 Spring 没有找到匹配的 Bean,可能是 JobStatusService 级别太高。

尝试在 MongoJobStatusService 和 JobStatusService 之间放置另一个接口,像这样

public class MongoJobStatusService implements IMongoJobStatusService  {
..}

public interface IMongoJobStatusService  implements  JobStatusService<MongoJobStatus> {
...
}

我有同样的问题(Spring autowire Trouble with generic parameter),我就这样解决了......

于 2017-07-21T12:22:43.177 回答