How to make a property injection via @Value annotation mandatory?

2k views Asked by At

I have the following Test.java POJO class being populated from a property file using the @ConfigurationProperties annotation. I have seen the usage of @Required annotation to make it a mandatory.

Rather than defining annotations at the setter method level, are there any annotations or options within the @Value annotation that I can use for defining conditions like Mandatory, NotNull, etc?

@Component
@ConfigurationProperties(prefix = "com.test")
public class Test {
  private String name;

  @Required
  public void setName(String name) {
    name = name;
  }

  public String getName(String name) {
    name = name;
  }
}

Is this the right and only way for making a particular attribute mandatory? What are the other such annotations I could use for such conditions or validations purpose?

2

There are 2 answers

2
geoand On

You can use validation for the properties, just not in the way you envisaged. What you can do is use standard validation annotations (like @NotNull etc.) on the fields (or setters) themselves.

For example

@NotNull
@Size(min=2, max=10)
private String name;

Check out this part of the documentation

What the documentation essentially says, is that you simply have to have a compatible JSR303 validator implementation on the classpath, and use the relevant annotations. Spring Boot will take care of the rest

0
Andrew Spencer On

According to the Spring docs (currently 4.1.6.RELEASE), the Value annotation only has a single property, value, containing the value of the property. You can put a Spring EL expression in this, but that won't let you explicitly express notions like non-nullity.

Further, in your code snippet you're using @ConfigurationProperties which is an alternative approach to configuring property values, compared to the @Value annotation.

The way you're doing it, your Java getter/setter names need to map to the property names, i.e. prefix "com.test" + getName() / setName() matches property com.test.name=... So, you don't need the @Value annotation to tell Spring what property to use.

With the @Value approach, your getters/setters don't have to match the property names, but you do have to annotate each property e.g. @Value("${com.test.name}") and on the class, a @PropertySource annotation pointing to the properties file that contains com.test.name=...

I found a couple of blog posts with code examples that use the 2 different ways to inject the same properties: http://blog.codeleak.pl/2014/09/using-configurationproperties-in-spring.html and http://blog.codeleak.pl/2014/09/testing-mail-code-in-spring-boot.html