Is it possible to name a Spring configuration class by passing a name to the @Configuration annotation?

140 Views Asked by At

I am building a Kafka streaming app (Java/Spring) and have a configuration class that uses @Value to assign values to the properties there as usual. In the configuration class is a method that sets other values based on these values which is a new practice to me. There is no @Bean annotation. It looks something like this:

@Configuration
public class SomeConfig {

    @Value("${some.value.we.use}")
    private String aConfigValue;

    @Value("${some.value.we.need}")
    private String anotherConfigValue;

    @PostConstruct
    public void configureIt() {
        if (aConfigValue != null) {
            System.setProperty("java.domain.this.thing", aConfigValue);
        }
        if (anotherConfigValue != null) {
            System.setProperty("java.domain.that.thing", anotherConfigValue);
        }
    }
}

Elsewhere, this class is used in an @DependsOn annotation on another class like this: @DependsOn("someConfig").

I believe @DependsOn("someConfig") is fine and that it will refer to the correct class, but I would like to add some reassurance (to my confidence - by improving my knowledge or by adding something to the code).

This would make me feel better, but I don't know if it is possible, a good idea, or if it would even work. And, I'm not in a position to try it out first right now, so I'm asking folks who might know better than me. I know I can name Beans via the @Bean annotation, like this: @Bean("someConfig"), but I'm not declaring a Bean in that way. I am also familiar with @Qualifier, but I would like to not use it if I can just name the class in this way I am suggesting.

@Configuration("someConfig")
public class SomeConfig {

    @Value("${some.value.we.use}")
    private String aConfigValue;

    @Value("${some.value.we.need}")
    private String anotherConfigValue;

    @PostConstruct
    public void configureIt() {
        if (aConfigValue != null) {
            System.setProperty("java.domain.this.thing", aConfigValue);
        }
        if (anotherConfigValue != null) {
            System.setProperty("java.domain.that.thing", anotherConfigValue);
        }
    }
}

So:

  1. Is it possible to name a Spring configuration class by passing a name to the @Configuration annotation in this way? If so, do you think I should? If not, why not?
  2. Does it look to you like I'm missing something that should be obvious to me if I'm doing this for a living? (I will go study)

I have not tried anything just yet. There is other code with no additional annotation or qualification. This makes me think that Spring will read the class as "someConfig" when its name is SomeConfig. The actual name is common enough that I don't want to risk a name collision somewhere and have Spring picking something that isn't this class.

Also, since this pattern is new to me and I'm not used to seeing it done this way I'm feeling uneasy and looking for a way to reassure myself. However, since I have lots of repositories where this or something mostly the same as this are working in production, I can just copy what's there and not think about it anymore. I don't like working that way, though.

2

There are 2 best solutions below

1
derkoe On

As these classes are no Spring config classes you can use @Component to define the beans:

@Component("someConfig")
public class SomeConfig {

    @Value("${some.value.we.use}")
    private String aConfigValue;

    @Value("${some.value.we.need}")
    private String anotherConfigValue;

    @PostConstruct
    public void configureIt() {
        if (aConfigValue != null) {
            System.setProperty("java.domain.this.thing", aConfigValue);
        }
        if (anotherConfigValue != null) {
            System.setProperty("java.domain.that.thing", anotherConfigValue);
        }
    }
}

Additionally, it may not be a good pattern to set the Java system properties here and then depend on this bean. A better way would be to directly pass the config values to the bean depening on SomeConfig.

0
BIBOO nation On

Based on the Spring documentation, @Configuration supports the value element:

Explicitly specify the name of the Spring bean definition associated with this Configuration class. If left unspecified (the common case), a bean name will be automatically generated. The custom name applies only if the Configuration class is picked up via component scanning or supplied directly to a AnnotationConfigApplicationContext. If the Configuration class is registered as a traditional XML bean definition, the name/id of the bean element will take precedence.

So, what you are trying to do is achievable. Take note of the minor gotcha about XML bean definitions.