我最近在 Server
类中添加了一个 Throttler
字段,只有在启用限制(这是一个配置条目)时才实例化该类,如果是这样,每秒的最大请求数(另一个配置条目)将传递给其构造函数。
这是没有依赖注入(inject)Throttler
的代码:
public class Server {
private Config config;
private Throttler throttler;
@Inject
public Server(Config config) {
this.config = config;
if (config.isThrottlingEnabled()) {
int maxServerRequestsPerSec = config.getMaxServerRequestsPerSec();
throttler = new Throttler(maxServerRequestsPerSec);
}
}
}
public class Throttler {
private int maxRequestsPerSec;
public Throttler(int maxRequestsPerSec) {
this.maxRequestsPerSec = maxRequestsPerSec
}
}
现在为了注入(inject) Throttler
,我使用了 Provider
,因为它并不总是需要实例化。但现在我被迫将 Config
注入(inject) Throttler
并让它“自行配置”:
public class Server {
private Config config;
private Provider<Throttler> throttlerProvider;
@Inject
public Server(Config config, Provider<Throttler> throttlerProvider) {
this.config = config;
this.throttlerProvider = throttlerProvider;
if (config.isThrottlingEnabled()) {
this.throttler = throttlerProvider.get();
}
}
}
public class Throttler {
private int maxRequestsPerSec;
@Inject
public Throttler(Config config) {
maxRequestsPerSec = config.getMaxServerRequestsPerSec();
}
}
我不喜欢这个解决方案,因为:
- 实用程序类 (
Throttler
) 依赖于Config
。 Throttler
现在绑定(bind)到特定的配置条目,这意味着除了Server
之外,它不能被其他任何东西使用。
我更愿意以某种方式将 maxRequestsPerSec
注入(inject)构造函数。
Guice 可以做到这一点吗?
最佳答案
Guice FAQ建议引入一个工厂接口(interface),该接口(interface)使用其依赖项和客户端传递的附加参数来构建类。
public class Throttler {
...
public static class Factory {
@Inject
public class Factory(... Throttler dependencies ...) {...}
public Throttler create(int maxRequestsPerSec) {
return new Throttler(maxRequestsPerSec /*, injected Throttler dependencies */);
}
}
}
这样,Throttler 的所有直接依赖项仍然封装在 Throttler 类中。
您还可以使用AssistedInject扩展以减少样板代码。
关于java - 使用 Provider 时如何将可配置参数传递给构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29147215/