我是Guice的新手,这是一个天真的问题。我了解到我们可以通过以下方式将String绑定到特定值:
bind(String.class)
.annotatedWith(Names.named("JDBC URL"))
.toInstance("jdbc:mysql://localhost/pizza");
但是如果我想将String绑定到任何可能的字符呢?
或者我认为可以这样描述:
如何用Guice替换“new SomeClass(String strParameter)”?
答案 0 :(得分:41)
首先需要为SomeClass
:
class SomeClass {
@Inject
SomeClass(@Named("JDBC URL") String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
}
我更喜欢使用自定义注释,如下所示:
class SomeClass {
@Inject
SomeClass(@JdbcUrl String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface JdbcUrl {}
}
然后你需要在你的模块中提供一个绑定:
public class SomeModule extends AbstractModule {
private final String jdbcUrl; // set in constructor
protected void configure() {
bindConstant().annotatedWith(SomeClass.JdbcUrl.class).to(jdbcUrl);
}
}
然后一个时间Guice创建SomeClass,它将注入参数。例如,如果SomeOtherClass依赖于SomeClass:
class SomeOtherClass {
@Inject
SomeOtherClass(SomeClass someClass) {
this.someClass = someClass;
}
通常,当您认为要注入String时,您希望注入一个对象。例如,如果String是一个URL,我经常注入带有绑定注释的URI。
这都假设您可以在模块创建时为String定义一些常量值。如果在创建模块时该值不可用,则可以使用AssistedInject。
答案 1 :(得分:20)
这可能是偏离主题的,但Guice使配置比为所需的每个String编写显式绑定更容易。您可以为它们配置一个配置文件:
Properties configProps = Properties.load(getClass().getClassLoader().getResourceAsStream("myconfig.properties");
Names.bindProperties(binder(), configProps);
并且您的所有配置都已准备就绪:
@Provides // use this to have nice creation methods in modules
public Connection getDBConnection(@Named("dbConnection") String connectionStr,
@Named("dbUser") String user,
@Named("dbPw") String pw,) {
return DriverManager.getConnection(connectionStr, user, pw);
}
现在,只需使用
在类路径的根目录下创建Java properties filemyconfig.properties
即可
dbConnection = jdbc:mysql://localhost/test
dbUser = username
dbPw = password
或将来自其他来源的授权信息合并到属性中并进行设置。
答案 2 :(得分:0)
我在Guice的常见问题解答中找到了解决方案:
http://code.google.com/docreader/#p=google-guice&s=google-guice&t=FrequentlyAskedQuestions
除了在MyModule中定义注释和String属性外,我还需要在下面写一行来获取SomeClass的实例:
SomeClass instance = Guice.createInjector(new MyModule("any string i like to use")).getInstance(SomeClass.class);
但是我记得除了root对象之外不应该使用Injector.getInstance(),那么还有更好的方法吗?
答案 3 :(得分:0)
我能够通过Named
注释插入一个字符串。
@Provides
@Named("stage")
String stage() {
return domain;
}
class SomeClass {
@Inject
@Named("stage")
String stageName;
}