Friday, August 22, 2014

Injecting and Updating Configuration

At the last Hackergarten in Zurich, I discussed some configuration aspects with Andres Almiray (Twitter: @aalmiray). He showed my some very interesting aspects in the Griffon framework concerning injecting and updating String based configuration (preferences plugin). Image the following bean:

@Singleton
public class MyConfiguredBean{

  @Configured
  private String myConfigValue;

  ...
}

Basically this is simple and realizable just using today's existing CDI mechanisms, where @ConfiguredProperty is simply injecting the corresponding configuration value with the key "myConfigValue" (the field name). Of course, if the field name is not, what you want, you can explicitly define the configuration key to be used.

@Singleton
public class MyConfiguredBean{

  @Configured(key="a.b.configValue")
  private String myConfigValue;

  ...
}

Given that declaration the configuration system will just inject the correct configuration value once, when the bean is initialized. Now interesting could be how we can define an easy mechanism, to make the bean aware of configuration changes on the given property. With CDI, we could simply add a ConfigChangeEvent, which will be provided for each Configuration Change:

@Singleton
public class MyConfiguredBean{

  @Configured(key="a.b.configValue")
  private String myConfigValue;

  public void configChanged(@Observes ConfgChangeEvent evt){
    ...
  }

  
}

This would be easy. Furthermore we can add en injection mechanism, where the changes can directly be applied to the current bean:

public void configChanged(@Observes ConfigChangeEvent evt){
    evt.applyChanges(this);
}

This would implicitly update all the configuration injected, including Strings.

If we look at the example above, we basically can make things even easier (and that is what Griffon has already built-in): we simply add another top level annotation on the bean, telling the configuration system, that it should automatically reinject configuration values, when they change:

@AutoConfigured
@Singleton
public class MyConfiguredBean{

  @ConfiguredProperty(key="a.b.configValue")
  private String myConfigValue;

  ...
}

So whenever I access myConfigValue, I will see the current accurate result. I think this is an easy and intuitive way for managing String based configuration. Nevertheless this mechanism must not be constraint to Strings, it can be used for any configured resource.



2 comments: