Dependency injection 如何在GoogleGuice中注入具有名称模式或正则表达式的属性列表?
使用Google Guice,我们可以从属性文件中注入如下内容:Dependency injection 如何在GoogleGuice中注入具有名称模式或正则表达式的属性列表?,dependency-injection,binding,guice,Dependency Injection,Binding,Guice,使用Google Guice,我们可以从属性文件中注入如下内容: @Inject(optional = true) @Named("api.server.ip") private final String ip = "localhost"; api.server.ip.1=10.11.12.13 api.server.port.1=3000 api.server.path.1=/maps api.server.ip.2=10.11.12.14 api.server.port.2=3001 ap
@Inject(optional = true)
@Named("api.server.ip")
private final String ip = "localhost";
api.server.ip.1=10.11.12.13
api.server.port.1=3000
api.server.path.1=/maps
api.server.ip.2=10.11.12.14
api.server.port.2=3001
api.server.path.2=/phones
那么,如果我有这样一个属性文件:
@Inject(optional = true)
@Named("api.server.ip")
private final String ip = "localhost";
api.server.ip.1=10.11.12.13
api.server.port.1=3000
api.server.path.1=/maps
api.server.ip.2=10.11.12.14
api.server.port.2=3001
api.server.path.2=/phones
任务是应用程序需要访问多个服务器来调用请求,那么是否有任何方法可以使用GoogleGuice中的模式注入属性,或者有任何建议来解决此问题?谢谢你 Google Guice没有现成的解决方案,但您可以使用api做一些事情 下面是一段代码,它将注入由自定义属性注释注释的字段-
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matchers;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class PropertiesInjection {
static class PropertiesModule extends AbstractModule {
@Override
protected void configure() {
bindListener(Matchers.any(), new PropertiesTypeListener());
}
}
static class PropertiesTypeListener implements TypeListener {
public <T> void hear(TypeLiteral<T> typeLiteral, TypeEncounter<T> typeEncounter) {
Class<?> clazz = typeLiteral.getRawType();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
if (field.getType() == String.class && field.isAnnotationPresent(Property.class)) {
Property annotation = field.getAnnotation(Property.class);
typeEncounter.register(new PropertyInjector<T>(field, annotation.value()));
}
}
clazz = clazz.getSuperclass();
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Property {
String value();
}
static class PropertyInjector<T> implements MembersInjector<T> {
private final Field field;
private final String key;
PropertyInjector(Field field, String key) {
this.field = field;
this.key = key;
}
@Override
public void injectMembers(T instance) {
try {
field.set(instance, PropertiesFileDataProvider.getValue(key));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
static class PropertiesFileDataProvider {
private static final Map<String, String> PROPERTIES = new HashMap<>();
static {
PROPERTIES.put("api.server.ip", "localhost"); //load it from properties file. I am putting dummy values just for an example.
}
static String getValue(String key) {
return PROPERTIES.getOrDefault(key, key);
}
}
static class TestData {
@Property("api.server.ip")
private String property;
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new PropertiesModule());
TestData instance = injector.getInstance(TestData.class);
System.out.println(instance.property); //prints localhost
}
}