0

In my Spring Integration webapp configuration I've added a property placeholder:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:ctx="http://www.springframework.org/schema/context"
    ...
    xsi:schemaLocation="http://www.springframework.org/schema/context
            ...
            ">

    <ctx:component-scan ... />
    <ctx:annotation-config />
    <mvc:annotation-driven />

    <ctx:property-placeholder location="classpath:config.properties" trim-values="true" />

This is that file content:

apiPath=/requests

I'm sure this configuration works because I've tried using that value in a http inbound-channel-adapter:

<int-http:inbound-channel-adapter id="/api${apiPath}"
        channel="httpRequestsChannel"
        path="${apiPath}"
        ...>
</int-http:inbound-channel-adapter>

and if I change the property value the frontend application cannot reach the endpoint.

However, further in the context I have an endpoint so configured:

<int:header-value-router input-channel="httpRequestsChannel" ... >
    <int:mapping value="POST" channel="httpRequestsPostChannel" />
    ...
</int:header-value-router>

<int:channel id="httpRequestsPostChannel" />

<int:chain input-channel="httpRequestsPostChannel">

    <int:transformer method="transform">
        <bean class="transformers.RequestToMessageFile" />
    </int:transformer>

    ...

where I want to read the property value:

public class RequestToMessageFile {

    @Autowired
    private Environment env;

    // ...

    public Message<?> transform(LinkedMultiValueMap<String, Object> multipartRequest) {
        System.out.println("Value: " + env.getProperty("apiPath"));

But on the console I see:

Value: null

I supposed once declared the property source in the XML that would be part of the whole web app environment, what am I missing? Should I declare the source in another place?

I noticed that if I add the following annotations:

@Configuration
@PropertySource("classpath:config.properties")
public class RequestToMessageFile {

the property is correctly found so I guess this is just a configuration problem.

In case it matters, here's the web.xml portion that configures integration:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/META-INF/spring.integration/context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

UPDATE

Partly following this answer I removed <ctx:property-placeholder> from the XML file and I added the following bean:

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:config.properties")
public class WebappConfig {

}

And now both beans and the XML file can see the properties.

watery
  • 5,026
  • 9
  • 52
  • 92
  • No it isn't a configuration issue that is how it is supposed to work. The `` doesn't add properties to the environment. Where as the `@PropertySource` does. – M. Deinum May 18 '18 at 12:56
  • @M.Deinum Then how can I declare the property source in only one place, for both the XML and all the beans? Or otherwise, what's the XML equivalent of `@PropertySource`? – watery May 18 '18 at 13:08
  • There isn't. Just declare it in Java everything is part of the same application context. – M. Deinum May 18 '18 at 13:22
  • You need to use `@PropertySource` and also declare a `PropertySourcesPlaceholderConfigurer` as a `static` `@Bean` in your `@Configuration`. And that everything instead of ``. – Artem Bilan May 18 '18 at 13:24

1 Answers1

1

Quoting Martin Deinum:

No it isn't a configuration issue that is how it is supposed to work. The doesn't add properties to the environment. Where as the @PropertySource does.

Therefore you should remove <ctx:property-placeholder> from your XML configuration. Continue to use @PropertySource("classpath:config.properties") and also add this bean definition:

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

Pay attention how it has to be static do not load eagerly all other beans in the same @Configuration.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • I removed the XML file entry and added a new bean (please see my _update_ above) and it works now; I'm new to Spring, can you elaborate on why I need that additional `PropertySourcesPlaceholderConfigurer` bean? – watery Jun 08 '18 at 08:05
  • Because that’s how it has to be configured with Java and Annotations configuration. See its JavaDocs for more info – Artem Bilan Jun 08 '18 at 11:57