这是我的 StatusMapper 界面的样子:
public interface StatusMapper<T extends Throwable> {
Status map(final T exception);
}
这是我的 MapBinder:
TypeLiteral<Class<? extends Throwable>> exceptionType = new TypeLiteral<Class<? extends Throwable>>() { };
TypeLiteral<StatusMapper<? extends Throwable>> mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() { };
MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder = MapBinder.newMapBinder(binder(), exceptionType, mapperType);
exceptionBinder.addBinding(IOException.class).to(IOExceptionMapper.class);
exceptionBinder.addBinding(SQLException.class).to(SQLExceptionMapper.class);
...
这就是这些 ExceptionMappers 之一的样子:(简化)
public class IOExceptionMapper implements StatusMapper<IOException> {
@SuppressWarnings("unused")
private static final Logger logger = LoggerFactory.getLogger(IOExceptionMapper.class);
@Override
public Status map(final IOException exception) {
return new Status(100);
}
}
到目前为止这工作正常,但我必须注意 IOException 绑定到 IOExceptionMapper。如果我绑定 exceptionBinder.addBinding(IOException.class).to(SQLExceptionMapper.class);
类型检查器(编译器)不会抱怨,但它会破坏整个应用程序 - 有什么提示吗?
[更新]根据我创建的The111的回答ExceptionBinder
public class ExceptionBinder {
private final MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder;
public ExceptionBinder(final Binder binder) {
final TypeLiteral<Class<? extends Throwable>> exceptionType;
final TypeLiteral<StatusMapper<? extends Throwable>> mapperType;
exceptionType = new TypeLiteral<Class<? extends Throwable>>() {};
mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() {};
exceptionBinder = MapBinder.newMapBinder(binder, exceptionType, mapperType);
}
public <T extends Throwable> void bind(Class<T> exceptionClass, Class<? extends StatusMapper<T>> mapperClass) {
exceptionBinder.addBinding(exceptionClass).to(mapperClass);
}
}
这就是我的 Guice-Module 的样子:
final ExceptionBinder eb = new ExceptionBinder(binder());
eb.bind(IOException.class,IOExceptionMapper.class);
eb.bind(SQLException.class,SQLExceptionMapper.class);