like following in spring
@value("${varname:0}") int varname;
is there way using google guice?
in guice annotate method , make optional. assign default value. if no property there injected, default value.
for example:
public class testmodule3 extends abstractmodule { @override protected void configure() { // properties p = new properties(); // p.setproperty("myvalue", "12"); // names.bindproperties(binder(), p); // binds properties come file bind(manager.class).to(managerimpl.class).in(singleton.class); } public static interface manager { public void talk(); } public static class managerimpl implements manager { @inject(optional = true) @named("myvalue") int test = 0; @override public void talk() { system.out.println(test); } } public static void main(string[] args) { manager instance = guice.createinjector(new testmodule3()).getinstance(manager.class); instance.talk(); } }
this print "0" you, because commented out property binding. if remove comments, bind value 12 string myvalue. inject annotation takes care of rest.
hope helps,
edit:
as @tavianbarnes pointed out, guice 4+ has optionalbinder. tried usecase , not make work out of box.
it appears optionalbinding useful classes (actual instances), not properties. here why:
you have know properties in advance , bind them defaults. easy forget them. example shown op shows not know if has property available (based on name).
default implementation of property bindings don't work in combo optionalbinding.
so way can make work this:
optionalbinder.newoptionalbinder(binder(), key.get(string.class, names.named("myvalue"))).setdefault() .toinstance("777"); properties p = new properties(); p.setproperty("myvalue", "12"); // use enumeration include default properties (enumeration<?> e = p.propertynames(); e.hasmoreelements();) { string propertyname = (string) e.nextelement(); string value = p.getproperty(propertyname); optionalbinder.newoptionalbinder(binder(), key.get(string.class, names.named(propertyname))).setbinding() .toinstance(value); }
i had copy named binding code , change support optional bindings.
in summary:
i prefer use optional=true flag + default value in code properties.
use optionalbinding actual classes can optional.
finally, there 1 more thing - solution in code. have similar requirement (not optional, default values).
i want:
- bind properties
- check if properties variable
- replace variable
- if variable not available set default
apache offers handy library reuse. how properties like:
myproperty=${env_var_name:-600}
this default annotation of how define default value. above property says:
- use evnironment variable "env_var_name".
- if "env_var_name" not set, use value "600"
then bind follows:
inputstream resourceasstream = getclass().getresourceasstream(path); if(resourceasstream == null) { throw new illegalargumentexception("no property file found path: " + path); } try { p.load(resourceasstream); environmentvariablesubstitutor envsubstitutor = new environmentvariablesubstitutor(false); set<object> keys = p.keyset(); for(object k : keys) { string property = p.getproperty(k.tostring()); property = envsubstitutor.replace(property); p.put(k, property); } } catch (ioexception e) { throw new illegalstateexception("could not load properties", e); } { try { resourceasstream.close(); } catch (ioexception e) { log.error("could not close stream resource " + path); } } names.bindproperties(binder(), p);
what code is:
- load properties resource file
- use environmentvariablesubstitutor process values of properties , overwrite result. (see loop)
- finally, bind modified properties names.
these solutions can come @ short notice :) let me know if something's unclear
edit 2:
there info on optionalbindings , properties + how handle default values in google thread well: https://groups.google.com/forum/#!topic/google-guice/7ga79iu_sb0
artur
Comments
Post a Comment