【发布时间】:2015-10-27 18:06:50
【问题描述】:
我有两个接口。一个接口包含信息,第二个接口应该使用第一个接口。第二个接口有一个泛型必须是第一个接口的实现。
我想根据收到的第一个接口的实现自动使用第二个接口的实现。
让我展示一下接口。 (我更改了域并对其进行了简化,但您了解基本概念。)
//This contains information needed to publish some information
//elsewhere, on a specific channel (MQ, Facebook, and so on)
public interface PubInfo {
String getUserName();
String getPassword();
String getUrl();
Map<String, String> getPublishingSettings();
}
//Implementation of this interface should be for one implementation
//PubInfo
public interface Publisher<T extends PubInfo> {
void publish(T pubInfo, String message);
}
假设我会有这些 PubInfo...
的实现public class FacebookPubInfo implements PubInfo {
// ...
}
.
public class TwitterPubInfo implements PubInfo {
// ...
}
...以及Publisher
的这些@Component
public class FacebookPublisher implements Publisher<FacebookPubInfo> {
@Override
public void publish(FacebookPubInfo pubInfo, String message) {
// ... do something
}
}
.
@Component
public class TwitterPublisher implements Publisher<TwitterPubInfo> {
// ...
}
你明白了基本的想法,两个接口,每个接口都有两个实现。
最后是问题
现在我将谈到棘手的部分,那就是我希望能够在我的服务获得 TwitterPubInfo 时自动使用 TwitterPublisher。
正如您在下面的示例中看到的那样,我可以通过手动映射来做到这一点,但我不禁想到它会存在一种更自动地执行此操作的方法,而不是依赖于手动映射。我使用spring,我认为在那里的某个地方会存在一个工具来帮助我解决这个问题,或者可能是其他一些实用程序类,但我找不到任何东西。
@Service
public class PublishingService {
private Map<Class, Publisher> publishers = new HashMap<Class, Publisher>();
public PublishingService() {
// I want to avoid manual mapping like this
// This map would probably be injected, but
// it would still be manually mapped. Injection
// would just move the problem of keeping a
// map up to date.
publishers.put(FacebookPubInfo.class, new FacebookPublisher());
publishers.put(TwitterPubInfo.class, new TwitterPublisher());
}
public void publish(PubInfo info, String message) {
// I want to be able to automatically get the correct
// implementation of Publisher
Publisher p = publishers.get(info.getClass());
p.publish(info, message);
}
}
我至少可以用反射填充publishers 中的PublishingService,对吧?
我需要自己做吗,或者在其他地方有什么帮助吗?
或者,也许你认为这种方法是错误的,并且存在一种更聪明的方法来完成我需要在这里做的事情,请随意说出来并告诉我你做事的优越方式:p(真的,我很感激它)。
编辑 1 个开始
在春季编写自定义事件处理程序时,它会找到正确的实现,这就是我对这个问题的启发。
这是来自那个页面:
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
// ...
public void onApplicationEvent(BlackListEvent event) {
// as you can see spring solves this, somehow,
// and I would like to be able to something similar
}
}
我能以某种方式获得相同的功能吗?
结束编辑 1
【问题讨论】:
-
你的意思是
FacebookPublisher implements Publisher<FacebookPubInfo>? -
您对这个解决方案的第一大问题是什么?您必须手动枚举所有映射?
-
"...遇到问题时...我知道,我会使用 DI...现在他们有两个问题" :D
-
@PaulBoddington 是的,我会改变的
-
您可以在接口
PubInfo中放置一个方法Publisher<? extends PubInfo> publisher();,而不是使用Map。
标签: java spring generics reflection