Отказ от ответственности: принесите мне достаточно кода для объяснения сценария.
В одном из модулей maven (ядро) у нас есть следующие классы:
abstract class ReportingEvent {
}
abstract class Element {
public <E extends ReportingEvent> Optional<E> getReportEvent() {
return Optional.empty();
}
}
такие сервисы, как:
public interface Reporting<E extends ReportingEvent> {
void report(E event);
}
interface InternalService {
}
public class InternalServiceImpl implements InternalService {
@Inject
Reporting<ReportingEvent> reporting; // 1. Possible to use a generic type? How?
private void reportEvents(BatchRequest batchRequest) {
batchRequest.stream()
// section below is of importance
.map(m -> m.getEntity().getReportEvent()) // the generic method from 'Element'
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(event -> reporting.report(event)); // method from 'Reporting'
}
}
class CoreBindingModule extends AbstractModule {
protected void configure() {
bind(InternalService.class).to(InternalServiceImpl.class).in(Singleton.class);
}
}
Далее, в другом модуле maven (потребителе), который мы развертываем, у нас есть классы, связанные с вышеописанным и реализующие его как:
abstract class BaseReporting extends ReportingEvent {
}
class ColdReporting extends BaseReporting {
}
abstract class Node extends Element {
}
class Cold extends Node {
@Override
public Optional<ColdReporting> getReportEvent() {
return Optional.ofNullable(new ColdReporting()); // some business logic
}
}
class ReportingImpl implements Reporting<ReportingEvent> { // 2. Use 'BaseReporting' here
void report(ReportingEvent event){}
}
class ConsumerBindingModule extends AbstractModule {
protected void configure() {
bind(new TypeLiteral<Reporting<ReportingEvent>>() {}).to(ReportingImpl.class).in(Singleton.class);
}
}
Приведенный выше код работает нормально. Но проблема заключается в использовании типов, которые не совсем относятся к модулям.
A ... Поэтому, если я изменяю привязку в модуле-потребителе на
bind(new TypeLiteral<Reporting<BaseReporting>>() {}).to(ReportingImpl.class).in(Singleton.class);
с
class ReportingImpl implements Reporting<BaseReporting> {
void report(BaseReporting event){}
}
, я получаю ошибку
No implementation for Reporting<ReportEvent> was bound.
while locating Reporting<ReportEvent> for field at InternalServiceImpl.reporting(InternalServiceImpl.java:21)
, что актуально, и я все равно не могу использовать Reporting<BaseReporting>
в основном модуле.
B ... Вкл с другой стороны, если я попытаюсь ввести Reporting
как:
@Inject
Reporting<? extends ReportingEvent> reporting;
, тогда IDEA сообщит
Required type: capture of ?
Provided: ReportingEvent
в строке
...forEach(event -> reporting.report(event))
Есть ли способ обойти эту ситуацию, пытаясь решить для 1 и 2 , как указано в разделах кода?