Spring @ConfigurationProperty a Bean or not?

Semi-recently (“semi” because procrastination kept me from writing, so it’s more like two months ago, but blog posts have to start with “recently” when you try to explain yourself why you are writing what you are writing – but I’m getting sidetracked here, so let’s move on) I was wondering whether Java classes annotated with Spring’s @ConfigurationProperty should be declared as a bean, e.g. with @Component. I didn’t find a definitive answer, but I found three ways on how to do it – typical Spring, I guess.

Here’s a quick setup:

My configuration class.

package com.thecodeslinger.configpropsdemo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; 

@Data 
@ConfigurationProperties(prefix = "demo")
public class Configuration {

    private String elegy;
}

My main application:

package com.thecodeslinger.configpropsdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;

@SpringBootApplication
public class ConfigPropsDemoApplication {

   @Autowired
   private Configuration configuration;

   @PostConstruct
   public void postConstruct() {
      System.out.println(configuration.getElegy());
   }

   public static void main(String[] args) {
      SpringApplication.run(ConfigPropsDemoApplication.class, args);
   }
}

And finally, my properties file:

demo.elegy=R.I.P. Kobe

It’s not an elegant setup, but that’s not the point. It does the job for now.

If you run the application in this state, Spring will greet you with an error message.

APPLICATION FAILED TO START

Description:
Field configuration in com.thecodeslinger.configpropsdemo.ConfigPropsDemoApplication required a bean of type 'com.thecodeslinger.configpropsdemo.Configuration' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.thecodeslinger.configpropsdemo.Configuration' in your configuration.

It obviously cannot find the configuration bean.

Option #1: Slap @Component to it.

package com.thecodeslinger.configpropsdemo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "demo")
public class Configuration {

    private String elegy;
}

Option #2: Use the @EnableConfigurationProperties annotation.

import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties(Configuration.class)
public class ConfigPropsDemoApplication {

Option #3: Use @ConfigurationPropertiesScan to explicitly name the packages to scan for.

import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan({"com.thecodeslinger.configpropsdemo"})
public class ConfigPropsDemoApplication {

All three options achieve what you’re aiming for, a running application.

:: Spring Boot :: (v2.2.4.RELEASE)
2020-02-03 19:57:43.562 INFO 4612 --- [ main] c.t.c.ConfigPropsDemoApplication : Starting ConfigPropsDemoApplication on DESKTOP-C0O3OKC with PID 4612 (D:\OneDrive\Code\Java\config-props-demo\target\classes started by lober in D:\OneDrive\Code\Java\config-props-demo)
2020-02-03 19:57:43.562 INFO 4612 --- [ main] c.t.c.ConfigPropsDemoApplication : No active profile set, falling back to default profiles: default
R.I.P. Kobe
2020-02-03 19:57:43.921 INFO 4612 --- [ main] c.t.c.ConfigPropsDemoApplication : Started ConfigPropsDemoApplication in 0.573 seconds (JVM running for 1.083)

So, is there any benefit of one over the other? The Spring documentation has the following to say:

Sometimes, classes annotated with @ConfigurationProperties might not be suitable for scanning, for example, if you’re developing your own auto-configuration or you want to enable them conditionally. In these cases, specify the list of types to process using the @EnableConfigurationProperties annotation. This can be done on any @Configuration class, as shown in the following example:

I’m not using a @Configuration class in my example, but if you were, you could leverage that to load your configuration classes based on @Profile annotations. Although @Component works too, it’s not mentioned in that part of the Spring documentation (“Type-safe Configuration Properties”).

For myself, I might go with @EnableConfigurationProperties and if it makes sense, even have dedicated @Configuration classes linked to @Profile. For little samples like this one it’s obviously overkill. In a remotely useful application, the additional overhead may be worth it for structural and documentational reasons.

Grails i18n in Regular Classes

The Grails web development framework is a very powerful tool for quickly creating web applications ranging from simple to enterprise ready. For that, it probably provides everything a developer ever needs. And if it’s not delivered by Grails itself there are many useful plugins and tons of existing Java libraries (including the JDK, of course, the underlying SpringSource Framework and the GDK).

However, there is one thing I have stumbled across several times now and a quick search on the internet shows that I’m not alone with this problem: how can I use the internationalization features from a regular Java or Groovy class?Read More »

Java I/O Performance Iterating Directories

A while ago at work we were confronted with the task of creating a directory listing in a Grails application. We’ve tried a couple of approaches, one the Groovy way and one the Java way. Both delivered only a poor performance. A short search brought forth a Stackoverflow thread addressing the issue of slow Java i/o performance with only one real solution: switch from Java 6 to 7. That’s no option at work but out of personal interest I gave it a try at home.Read More »

Project HTPC

Motivation

Not long ago I became quite frustrated with the gaming capabilities of my iMac. It’s not that I didn’t know about the expected performance of the hardware since I bought the cheapest version by design. At that time I did not use the PC I had for what it was built for, which finally led to me selling it. However, recently I felt the urge to play some games other than Diablo 3. For one the iMac just couldn’t deliver the performance to enjoy the visuals of modern games as they were designed to be. Secondly what really frustrated me and this is also the main reason why I never really played anything other than Diablo 3 on the iMac, was the poor cooling management of that machine. I have to crank up the coolers manually (using iStat Menus 3) in order to prevent overheating. Otherwise it’ll just get very hot and reboot eventually. As one can imagine this technique only works reliably on OS X.
Read More »

Controlling a Mac’s fans (AppleSMC)

Since the iMac found its way onto my desk I’ve been bothered with the heat generated when playing Diablo 3 (or possibly any other game) – just as with the MacBook Pro. The only difference: The MacBook’s fans were howling to stop the torment, the iMac just swallows the pain it seems. Don’t get me wrong, the system is not overheating and temperature is well within its limits. In fact, the CPU doesn’t even really heat up. It’s more the graphics chip and the power supply. But for me as a former PC user who built all the PCs himself and always had a good (and mostly quiet) cooling this is just a bit unusual.Read More »