Changing Properties values in Spring MVC - spring

I am trying to load dynamic values from properties file into a Bean Class (Spring MVC project).
I had used following tags to load values.
<context:property-placeholder
location="file:/home/java/examresults/departments.properties"
ignore-unresolvable="true" order="2"/>`
But changing the value in properties file after starting the application, it does not reflected at the form.
I am injecting these values into a class using following declaration.
<bean id="beanmessage" class="examresults.bean.MessageClass" scope="prototype">
<property name="imagelocation" value="/home/java/examresults/"/>
<property name="boards" value="${boardvalue}"/>
<property name="departments" value="${deptvalue}"/>
</bean>
Hence, I am not able to fully utilizing the properties file in my Spring MVC Application.

If you modify the properties file, the webserver needs to be reloaded to make the changes reflected.
When a webserver start, it will instantiate all the registered bean with the configured properties. So if you made changes to the configuration after the webserver started, the bean doesn't know about the changed configuration, because it's already instantiated in the application context / IoC container.
To make the changes in properties files reflected is done by restarting / reloading the webserver (either tomcat or jetty).

Related

Can a Spring Bean be re-assign a new value and how

I have a Spring bean which gets new files from the file system when the file changes. Is it possible to assign the new file when the file contents change. What Spring class can I use to refresh the Spring beans value. Here is a simple configuraton, The file.xml allows new entries to be added to it. I then use a FileWatcher to be alerted of changes to the file. I want to attach the new file to the bean so that I can read those changes:
<bean id="config" class="org.my.test.ResourceHandler">
<property name="location" value="file:/path/to/file.xml"/>
</bean>
When file.xml changes I detect the changes and want to refresh the ResourceHandler with the current contents. Is this possible with the Spring framework?

Getting a non Spring Boot program such as ActiveMQ to work with Spring Cloud Config

I have modified my original question slightly to better reflect my question. I have a non-Spring Boot application that I would like to have working with the Spring Cloud Config Server. I have searched around online and tried many things but it seems like the crux of my issue is that the server only works within a Spring Boot context. Although ActiveMQ is a Spring application already, it seems non-trivial to convert it to be a Spring Boot one.
I would like to have an ActiveMQ Broker that is configured from the Spring Cloud Config. My local settings within the application.properties should be replaced by those that come from the server. This works in other servers I work on, now I need it to work for my Broker Filter plugins.
I added the following to activemq.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>file:${activemq.conf}/credentials.properties</value>
</list>
</property>
</bean>
NOTE: Several base packages omitted here but are similar to:
<context:component-scan base-package="org.springframework.cloud.bootstrap"/>
<!-- enables annotation based configuration -->
<context:annotation-config />
After doing so I was able to get various #Value annotations to work with settings coming from my application.properties but the whole Spring Cloud Config Server thing seems to not replace my local application.properties file settings. Other Spring Boot application I work on do so I know the server is fine.
I have added the following jars to the apache-activemq-5.12.0\lib\extra directory:
spring-aop-4.1.8.RELEASE.jar
spring-beans-4.1.8.RELEASE.jar
spring-boot-1.2.7.RELEASE.jar
spring-boot-actuator-1.2.7.RELEASE.jar
spring-boot-autoconfigure-1.2.7.RELEASE.jar
spring-boot-starter-1.2.7.RELEASE.jar
spring-boot-starter-actuator-1.2.7.RELEASE.jar
spring-boot-starter-data-mongodb-1.2.7.RELEASE.jar
spring-boot-starter-logging-1.2.7.RELEASE.jar
spring-cloud-commons-1.0.1.RELEASE.jar
spring-cloud-config-client-1.0.1.RELEASE.jar
spring-cloud-context-1.0.1.RELEASE.jar
spring-cloud-starter-1.0.1.RELEASE.jar
spring-cloud-starter-config-1.0.1.RELEASE.jar
spring-context-4.1.8.RELEASE.jar
spring-context-support-4.1.8.RELEASE.jar
spring-core-4.1.8.RELEASE.jar
spring-data-commons-1.11.0.RELEASE.jar
spring-data-mongodb-1.8.0.RELEASE.jar
spring-expression-4.1.8.RELEASE.jar
spring-jms-4.1.8.RELEASE.jar
spring-security-crypto-3.2.8.RELEASE.jar
spring-test-4.1.8.RELEASE.jar
spring-tx-4.1.8.RELEASE.jar
spring-web-4.1.8.RELEASE.jar
refreshendpoint is not necessarily initialized when the constructor is called. You need to add a method annotation with #PostConstruct (or implement InitializingBean and implement afterPropertiesSet method) in which you'll perform refreshendpoint.refresh(); , e.g:
#PostConstruct
void init() {
refreshendpoint.refresh();
}

Alternative to spring profiles

Using spring 3 I can determine which bean to use at runtime. But using Spring 2.5 what is the alternative?
Here is the config within my context file :
<jee:jndi-lookup id="myDataSource" jndi-name="jdbc/mydb"
resource-ref="true" expected-type="javax.sql.DataSource" />
I can use a profile to determine whether or not to use this datasource, what is the alternative when using an earlier version of spring (earlier than Spring 3)
Update :
"myDataSource" will be injected when I run my app locally, on a prod environment the "jndi" lookup, will be used. To inject "myDataSource" using Spring 3 I can use "profiles" but what alternative can I use if not using Spring 3 ?
You could define all your environment depend beans into several files, such as :
beans-dev.xml
beans-prod.xml
Your XML config would be :
<beans>
<import resource="beans-${myapp.env}.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
In this case, myapp.env property is a JVM system property, i.e. configured with -Dmyapp.env=dev or -Dmyapp.env=prod. myapp.env cannot be setted from a property placeholder since Spring <import> are resolved before property placeholders.
You need to build out this kind of thing yourself. Typically by maintaining a number of different files for each profile that get composed together and a convention for picking the correct file at runtime. A -D System Property can help you pick which one. For example, we could have applicationContext-dev.xml and applicationContext-prod.xml, our applicationContext.xml would import applicationContext-${activeProfile}.xml, and you can set and load -DactiveProfile=dev; you can infer some of the other conventions like a context-param in the web.xml, etc. from how Spring3 profiles are designed.

Maven resource filtering - Spring application

I'm just wondering, at what point does the Maven resource filtering mechanism inject values from a profile into a target file? I'm asking because my application is using Spring, and depending on a JVM property, it will call one of my apps environment files which is in turn used to supply configuration information to spring beans as they get created.
I would like to move passwords and db type info from the environment file into the Maven Settings.xml file however I'm wondering will Spring overwrite or conflict with the way Maven resource filtering is working?
The goal is for Spring to decide what environment the application is running in and choose an environment file which will have already had the necessary values injected by Maven.
Thanks
Maven replaces placeholders within the process-resources phase. See http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
So when spring starts creating its context the values are there.
You can use the PropertyPlaceholderConfigurer to read a properties file and make them available in the spring context:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file://${config.dir}/external-config.properties</value>
</list>
</property>
</bean>
"config.dir" is in the system properties: java -Dconfig.dir=/dir/ or i think it can be a context parameter as well.
within the spring context ${key} from the properties file can be used to configure beans. Depending on the version of spring also annotations are available. Or there is a namespace for the PropertyResolver too.
So maven filtering and spring work nicely together.

How can I define a custom message source for a spring web flow?

The spring webflow documentation mentions that their way of adding messages to a flow is to define all messages regarding that flow in a file messages.properties inside the flow:
Internationalized messages are defined in message bundles accessed by a Spring MessageSource. To create a flow-specific message bundle, simply define messages.properties file(s) in your flow's directory. Create a default messages.properties file and a .properties file for each additional Locale you need to support.
In our webapp we use a mix of Spring Webflow and proprietary frameworks. We have all our internationalized messages in a single file and we'd like to have Spring Webflow access this one instead of littering our project with dozens of properties files. Is there a way to configure the message source for a spring webflow or are we stuck to messages.properties?
Put something like this in your application context XML file:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"><value>classpath:yourSharedResourceBundle</value></property>
</bean>
As long as the file is located on the classpath it should be used.

Resources