Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Dynamic property configurations reload during runtime utilising Java 7 WatchService API, Google Guava and Spring 3.2.5

License

Notifications You must be signed in to change notification settings

jamesmorgan/ReloadablePropertiesAnnotation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reloadable Properties Annotation

A simple utilty which allows object fields to be set from properties files via a @ReloadableProperty annotation. These properties also auto reload if the given properties file changes during runtime.

Example Annotation Usage

	@ReloadableProperty("dynamicProperty.longValue")
	private long primitiveWithDefaultValue = 55;
	
	@ReloadableProperty("dynamicProperty.substitutionValue")
	private String stringProperty;
	
	@ReloadableProperty("dynamicProperty.compoiteStringValue")
	private String compsiteStringProperty;

Example Properties File

	dynamicProperty.longValue=12345
	dynamicProperty.substitutionProperty=${dynamicProperty.substitutionValue}
	dynamicProperty.compoiteStringValue=Hello, ${dynamicProperty.baseStringValue}!

Example Spring XML Configuration

How it Works

When Spring starts an Application Context an implementation of Springs PropertySourcesPlaceholderConfigurer is instantiated to perform additional logic when loading and setting values from a given set of properties files. (see: ReadablePropertySourcesPlaceholderConfigurer)

During the instantiation phasae of an Application Context a new instance of InstantiationAwareBeanPostProcessorAdapter is also created which allows post bean processing to occur.

Google Guava is used to implement a simple Publish & Subscribe (Pub-Sub) Pattern so that beans can be updated once created, i.e. a bean can subscribe to property change events. (see: EventBus) EventBus was chosen as it is a very easy and simplistic way to implement loosely couple object structure. (see: blog)

When each properties file resource is loaded a PropertiesWatcher is started and attached to the given resource set, reporting on any java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY events from the host operating system

When an ENTRY_MODIFY event is fired firstly the resource changed is checked for property value changes then any bean subscribing to changes to the modified property has the specified field value updated with the new property. Once the filed value is updated no other operations are performed on the object.

Each resource specified starts a new thread per parent directory i.e. two properties files in the same directory requires only one ResourceWatcher thread, three properties files in three different directories will start three threads.

Tests

A set of integration and unit tests can be found in src/test/java (tests) & src/test/resources (test resources)

TODO (Unfinished)

  • Update test method names
  • Creation of any test utilities or helper classes

Why?

  • Useful for web applications which often need configuration changes but you don't always want to restart the application before new properties are used.
  • Can be used to define several layers of properties which can aid in defining multiple application configurations e.g sandbox/development/testing/production.
  • A pet project of mine I have been intending to implement for a while
  • A test of the new Java 7 WatchService API
  • Another dive in Spring & general investigation of Google Guava's EventBus
  • The project is aimed to be open to modification if required
  • Sample testing tools (CountDownLatch, Hamcrest-1.3, JMock-2.6.0-RC2)

Future Changes

  • Ability to use Spring Expression language to map properties files
  • Support for Java 7 Date and Time classes
  • Include the ability to define a database driven properties source not just properties files
  • Implement error recovery inside PropertiesWatcher.class, including better thread recovery
  • Ability to perform additional re-bind logic when a property is changed, i.e. if a class has an open DB connection which needs to be re-established using newly set properties.
  • Replace callback Properties EventHandler with Guava EventBus
  • Ability to configure usage via spring's @Configuration

Contributions

  • Thank you normanatashbar for adding composite string replacement
  • Thank you shiva2991 for adding java.util.Date type conversion.

Supported Property Type Conversions Available

  • LocalDate.class

  • LocalTime.class

  • LocalDateTime.class

  • Period.class

  • Spring Supported (3.1.2-RELEASE)

  • String.class

  • Date.class

  • boolean.class, Boolean.class

  • byte.class, Byte.class

  • char.class, Character.class

  • short.class, Short.class

  • int.class, Integer.class

    • long.class,Long.class
  • float.class, Float.class

  • double.class, Double.class

Dependencies

Core

  • Java 7 SDK
  • Spring (3.2.5-RELEASE)
  • Google Guava (14.0.1)
  • Joda Time Library (2.1) - link

Logging

  • logback (1.0.13)
  • slf4j (1.7.5)

Testing

  • juint (4.11)
  • jmock (2.6.0)
  • hamcrest-all (1.3)
  • spring-test (3.2.5-RELEASE)

Bitdeli Badge

About

Dynamic property configurations reload during runtime utilising Java 7 WatchService API, Google Guava and Spring 3.2.5

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages