我有一个Utility / constants类,其中包含一个Map<String, Authorizer>
,其中Authorizer
是具有一些不同实现的接口。我使用跨不同流的映射来接收包含某个String
(授权方法的名称)的对象,该对象随后映射到特定的Authorizer
,从而完成一些授权。
我正在使用Guice连接Authorizer
类,但是这种方法使我无法使实用程序类(包含Map
)成为具有空私有构造函数的真正的实用程序类。我有一个时髦的解决方法,可以让Guice和Checkstyle都满意,但是我想知道是否有更好的方法。
我的实用程序类:
public final class Constants {
@Inject
private Constants() {}
public static final String AUTH_METHOD_ONE = "Auth1";
public static final String AUTH_METHOD_TWO = "Auth2";
@Singleton
@Inject
@Getter // For Checkstyle, as AUTH_METHODS isn't a true static final constant
private static Map<String, Authorizer> authMethods;
}
我的常数模块:
public class ConstantsModule extends AbstractModule {
@Override
public void configure() {
requestStaticInjection(Constants.class);
final MapBinder<String, Authorizer> mapBinder = MapBinder.newMapBinder(binder(), String.class, Authenticator.class);
mapBinder.addBinding(AUTH_METHOD_ONE).to(MethodOneAuthorizer.class);
mapBinder.addBinding(AUTH_METHOD_TWO).to(MethodTwoAuthorizer.class);
}
}
以及示例用法:
public class AuthorizationOrchestrator {
private static Authorizer getAuthorizer(final AuthorizationState state) {
return state.getMethods().stream()
.map(AuthorizationApproach::getAuthorizationApproachName)
.filter(Constants.getAuthMethods().keySet()::contains)
.findFirst()
.map(Constants.getAuthMethods()::get)
.orElse(null);
}
}
这种方法还需要在单元测试中使用一些PowerMock。是否有更好的方法来:
将授权方法的名称映射到
Authorizer
类,同时将映射保留在一个地方?将
Constants
类用作public static final Map<String, Authorizer> AUTH_METHODS
的真实实用工具类,同时仍然可以将授权者注入Map
吗? 最佳答案
注入原本应该是常量的东西真的没有任何意义。
通过使用静态Constants
类,您正在将非注入式依赖项引入使用Constants
类的代码中,这与DI的观点背道而驰-更不用说静态依赖项在您的模拟中更加困难测试。
还有其他几种方法可能对您有用。原则上,它们都是相同的解决方案(将Authorizer
注入到非静态的东西中),但是它们有一些细微的差别。
使用组合避免使用实用程序类。制作由多个Authorizer
组成的Authorizer
实现。复合Authorizer
可以在内部委派给正确的“真实”实现。然后,您只需在需要的任何地方注入一个Authorizer
。取决于Authorizer
合同的定义方式,可能无法启用。
保持逻辑在实用程序类中没有任何状态。将静态方法的签名更改为getAuthorizer(AuthorizationState state, Map<String, Authorizer> availableAuthorizersByName)
。然后,将AUTH_METHODS
映射直接注入到将要调用静态getAuthorizer
方法的类中,并将该映射作为方法的参数之一传递给该方法。
使getAuthorizer()
不是静态的。并将地图直接注入到AuthorizationOrchestrator
的实例中。
关于java - 将依赖项注入(inject)实用程序类映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56941442/