How to programmatically resolve property placeholder in Spring

后端 未结 6 1456
借酒劲吻你
借酒劲吻你 2020-12-04 19:17

I currently work on a web application based on Spring 3.1.0.M1, annotations based, and I have a problem with resolving property placeholders in one specific place of my appl

相关标签:
6条回答
  • 2020-12-04 19:50

    Since Spring 3.0.3 there is EmbeddedValueResolverAware which will work same way as mentioned by another post which uses appContext.getBeanFactory().resolveEmbeddedValue("${prop}") call.

    To solve the problem:

    1. Make your class to implement EmbeddedValueResolverAware interface and you will get resolver injected for you

    2. Then where you will be able to retrieve properties as demonstrated in a code snippet:

      String propertyValue = resolver.resolveStringValue("${your.property.name}");
      

    Then your bean does not need to depend on ApplicationContext to retrieve properties you need.

    0 讨论(0)
  • 2020-12-04 19:57

    There is one more possible solution: make tag classes @Configurable via AspectJ and enable either compile-time or load-time weaving. Then, I could use usual Spring @Value annotations in my custom tags. But, really, I don't want to set up weaving infrastructure just because of a couple of classes. Still searching for a way to resolve placeholder via ApplicationContext.

    0 讨论(0)
  • 2020-12-04 19:59

    I think rather than focusing on inner working of context place holder, you can simply define a new util:properties like this:

    <util:properties id="appProperties" location="classpath:app.properties" />
    

    and in your code, use it like this:

    Properties props = appContext.getBean("appProperties", Properties.class);
    

    OR like this wherever you can do DI:

    @Value("#{appProperties['app.resources.path']}")
    
    0 讨论(0)
  • 2020-12-04 20:00

    One option is to add a PropertySource (here MapPropertySource to exemplify an in-memory configuration) to a ConfigurableEnvironment and ask it to resolve properties for you.

    public class Foo {
    
        @Autowired
        private ConfigurableEnvironment env;
    
        @PostConstruct
        public void setup() {
            env.getPropertySources()
               .addFirst(new MapPropertySource("my-propertysource", 
                   ImmutableMap.<String, Object>of("your.property.name", "the value")));
            env.resolvePlaceholders("your.property.name");
        }
    }
    

    Optionally annotate the Foo class with @Configuration to enjoy the power of programmatic configuration in favor of XML.

    0 讨论(0)
  • 2020-12-04 20:05

    Since version 3.0, Spring keeps a list of String resolver in the beanFactory. You can use it like this:

    String value = appContext.getBeanFactory().resolveEmbeddedValue("${prop}");
    

    The javadoc states this method as for resolving embedded values such as annotation attributes so maybe we are circumventing its usage, but it works.

    0 讨论(0)
  • 2020-12-04 20:15

    Just to add a complete answer, I'm adding this.

    You can do it with a custom class like this.

    import org.springframework.context.EmbeddedValueResolverAware;
    import org.springframework.util.StringValueResolver;
    import org.springframework.lang.Nullable;
    
    public class MyValueResolver implements EmbeddedValueResolverAware {
        @Nullable
        private StringValueResolver embeddedValueResolver;
    
        @Override
        public void setEmbeddedValueResolver(StringValueResolver resolver) {
            this.embeddedValueResolver = resolver;
        }
    
        public String readMyProperty(String propertyString){
            return embeddedValueResolver.resolveStringValue(propertyString);
        }
    }
    

    This propertyString should be passed as "${my.property}".

    Given that in .properties file it is presented as

    my.property=myPropertyValue
    
    0 讨论(0)
提交回复
热议问题