How to Inject a Property Value Into a Class Not Managed by Spring?

1. Overview

By design, classes annotated with @Repository, @Service, @Controller,
etc. are managed by Spring and injecting configuration there is easy and
natural. What’s not as simple is passing configuration to classes that
are not directly managed by Spring.

In that case, we can use ClassLoader-based configuration loading or
simply instantiate our classes in another bean and set required params
manually – this is the suggested option because configuration entries
don’t need to be stored in *.properties files exclusively.

In this quick article, we are going to cover the topic of loading
*.properties files with Java ClassLoader as well as injection of
already loaded configuration by Spring
into an unmanaged class.

2. Load Configuration with Class Loader

Simply put, *.properties files are resources files holding some config
info. Instead of using third party implementations that support
automatic application configuration loading, e.g. that implemented in
Spring, we can use Java ClassLoader to do the same.

We’re going to create a container object that will hold Properties
defined in resourceFileName. To fill up the container with
configuration, we will use a ClassLoader.

Let’s define PropertiesLoader class that implements
loadProperties(String resourceFileName) method:

public class PropertiesLoader {

    public static Properties loadProperties(String resourceFileName) throws IOException {
        Properties configuration = new Properties();
        InputStream inputStream = PropertiesLoader.class
          .getClassLoader()
          .getResourceAsStream(resourceFileName);
        configuration.load(inputStream);
        inputStream.close();
        return configuration;
    }
}

Every Class object contains a reference to the ClassLoader that
instantiated it; this is an object that is primarily responsible for
loading classes, but in this tutorial, we’ll use it for loading resource
file instead of plain Java class. The ClassLoader is looking for
resourceFileName on the classpath.

Afterward, we load the resource file as InputStream via the
getResourceAsStream API.

In the above example, we defined a configuration container that can
parse resourceFileName using the load(InputStream) API.

The load method implements parsing of *.properties files with support
of “:” or “=” characters as delimiters. Additionally, both “#” or
“!” characters used at the beginning of the new line are comment
markers and cause that line to be ignored.

Finally, let’s read the exact value of defined configuration entry from
our configuration files:

String property = configuration.getProperty(key);

3. Loading Configuration with Spring

A second solution is to make use of Spring Spring feature to handle some
of the low-level loading and processing of files.

Let’s define an Initializer that will hold the configuration needed to
initialize our custom class. During Bean initialization, the framework
will load all of the fields annotated with @Value from *.properties
config file:

@Component
public class Initializer {

    private String someInitialValue;
    private String anotherManagedValue;

    public Initializer(
      @Value("someInitialValue") String someInitialValue,
      @Value("anotherValue") String anotherManagedValue) {

        this.someInitialValue = someInitialValue;
        this.anotherManagedValue = anotherManagedValue;
    }

    public ClassNotManagedBySpring initClass() {
        return new ClassNotManagedBySpring(
          this.someInitialValue, this.anotherManagedValue);
    }
}

The Initializer can now be responsible for instantiating the
ClassNotManagedBySpring.

Now we’ll simply access our Initializer instance and run the
initClass() method on it to handle the instantiation of our custom
ClassNotManagedBySpring:

ClassNotManagedBySpring classNotManagedBySpring = initializer.initClass();

Once we have the reference to Initializer, we’ll be able to
instantiate our custom ClassNotManagedBySpring.

4. Summary

In this quick tutorial, we focused on reading properties into a
non-Spring Java class.

As always, an example implementation can be found
over
on GitHub
.

Leave a Reply

Your email address will not be published.