java - @Value at runtime -


how access @value machinery dynamically @ run-time?

i thought environment might looking for, it

@component public class springconfiguration implements configurationi {     @autowired     private provider<environment> env;      @override     public string get(string key) {         try {             return env.get().getrequiredproperty(key);         } catch (illegalstateexception e) {             return null;         }     } } 

unfortunately, not access values exposed our propertyplaceholderconfigurer bean.

edit: explain use case: part of making library lot of spring specific pieces (that pile of older spring applications depend on) usable newer guice applications switching spring specific annotations jsr 330 (javax.inject) ones. hoping avoid rewriting propertyplaceholderconfigurer stuff across our spring applications, providing nice entrypoint this. if there better way (maybe @named?) ears.

edit2: (cleaned up) example of kind of propertyplaceholderconfigurer exists in apps calling library.

@bean public propertyplaceholderconfigurer placeholderconfigurer() {     return new propertyplaceholderconfigurer() {         @override         protected string resolveplaceholder(string placeholder, properties props) {             // code parse , cleanup key here             string result = getpropertyfromlocalappspecificconfig(key);             if (result == null) {                 result = super.resolveplaceholder(placeholder, props);             }             // more random app specific logic missing defaults             return result;         }     }; } 

propertyplaceholder , friends not put properties in environment (mainly because of backward compatibility reasons). instead use environment , own internal properties object gathered property files classpath resolve @value properties. properties loaded propertyplaceholder can not fetched dynamically (ie no getproperty(string..)). people create custom propertyplaceholder store properties publicly (through getter or whatever) think defeats spring's new unified environment configuration handling.

what want @propertysource still pretty crappy since not dynamic (since annotation can't change files loaded from) load properties environment. have been meaning file issues spring source confusion of this.

anyway can @ solution here: manually add @propertysource: configuring environment before context refreshed

basically need hold of configurableenvironment , load properties creating propertysources. api powerful not intuitive. can use applicationcontextinitializers environment has own annoying issues (see link) or can below.

public class configresourcesenvironment implements      resourceloaderaware, environmentaware, beandefinitionregistrypostprocessor, environmentpropertiesmapsupplier {      private environment environment;     private map<string, string> environmentpropertiesmap;      @override     public void postprocessbeandefinitionregistry(beandefinitionregistry registry) throws beansexception {         if (environment instanceof configurableenvironment) {             configurableenvironment env = ((configurableenvironment) this.environment);             list<propertysource> propertysources;             try {                 propertysources = loadpropertysources(); //your custom method propertysources             } catch (ioexception e) {                 throw new runtimeexception(e);             }             //spring prefers primacy ordering reverse order of sources... may not need this.             reverse(propertysources);             (propertysource rp : propertysources) {                 env.getpropertysources().addlast(rp);             }             environmentpropertiesmap = immutablemap.copyof(environmentpropertiestomap(env));         }         else {             environmentpropertiesmap = immutablemap.of();         }     }       public static map<string,string> environmentpropertiestomap(configurableenvironment e) {         map<string, string> properties = newlinkedhashmap();         (string n : propertynames(e.getpropertysources())) {             string v = e.getproperty(n);             if (v != null)                 properties.put(n, v);         }         return properties;     }      public static iterable<string> propertynames(propertysources propertysources) {         linkedhashset<string> propertynames = new linkedhashset<string>();         (propertysource<?> p : propertysources) {             if (p instanceof enumerablepropertysource) {                 enumerablepropertysource<?> e = (enumerablepropertysource<?>) p;                 propertynames.addall(aslist(e.getpropertynames()));             }         }         return propertynames;     }      @override     public void postprocessbeanfactory(configurablelistablebeanfactory beanfactory) throws beansexception {         //noop     }      @override     public void setenvironment(environment environment) {         this.environment = environment;     }       public map<string, string> getenvironmentpropertiesmap() {         return environmentpropertiesmap;     }  } 

once have configurableenvironment loaded can use environmentaware interface things need environment or create own interface.

here custom interface can use things need dynamic properties (the above class implements it):

public interface environmentpropertiesmapsupplier {     public map<string, string> getenvironmentpropertiesmap();  } 

Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -