How to do simple property validation when using Spring @Value

How can I check if is ${}

not an empty string, and if so, throw some readable exception? This should happen when the Bean is created.

public class Service {

  private String property;


I'm looking for the easiest way (least written code). It would be great if annotations were used.

My current solution is to do "handwritten" validation inside the setter for the property, but there is very little code for that.

Hint: I was looking for a way to use SpEL since I am using it already internally @Value

, but as far as I found out it would not be that easy / clean. But I could have missed something.

Clarification: The expected behavior is that the application will not start. The goal is to ensure that all properties are set, and especially that the row properties are not empty . The error should clearly state what is missing. I do not want to set default values! The user has to install everything.


source to share

2 answers

What you have there will work. If you have not included the property in your properties file, you will get an exception org.springframework.beans.factory.BeanCreationException

when starting the server.

Apr 22, 2015 9:47:37 AM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'service': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'service': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder '' in string value "${}"
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(


An alternative would be to use initProperty

to handle or set the value, here you can throw some kind of readable exception.

public class Service {

    private String property;

    public void initProperty(@Value("${}") String property) {
        if(property == null) {
            // Error handling here


It really depends on whether you want to run the application regardless of whether the property is set, and if not, throw a readable exception to the log or console and then set it with a default value, or if you want the error to be thrown when starting the server and creating the bean.

I think the third option would be to just set the value if none were set using the default installer.

public class Service {

    @Value("${'This is my default setter string'}")
    private String property;




Here's my solution, just put this class in your code (just fix the "my.package" line):

 * Validates the environment-dependent properties during application start. Finds all spring beans, which classes are in
 * defined package, validates them and in case of error tries to log the property name (not class field name), taken
 * from {@link Value} annotation.
 * @author Tomasz
public class ConfigurationChecker implements ApplicationListener<ContextRefreshedEvent> {
    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationChecker.class);

    // this is a property, that is set in XML, so we bind it here to be found by checker. For properties wired directly in Beans using @Value just add validation constraints
    private String ldapUrl;

    private static final String FAIL_FAST_PROPERTY = "hibernate.validator.fail_fast";
    private Validator validator = Validation.byDefaultProvider().configure().addProperty(FAIL_FAST_PROPERTY, "false")

     * Performs the validation and writes all errors to the log.
    public void onApplicationEvent(ContextRefreshedEvent event) {"Validating properties");

        Set<ConstraintViolation<Object>> allViolations = new HashSet<>();

        // Find all spring managed beans (including ConfigurationChecker)...
        for (String beanName : event.getApplicationContext().getBeanDefinitionNames()) {
            Object bean = event.getApplicationContext().getBean(beanName);

            // ...but validate only ours.
            if (bean.getClass().getCanonicalName().startsWith("my.package")) {
                Set<ConstraintViolation<Object>> viol = this.validator.validate(bean);
      "Bean '" + beanName + "': " + (viol.isEmpty() ? " OK" : viol.size() + " errors found"));
            } else {


        // if any error found...
        if (allViolations.size() > 0) {

            for (ConstraintViolation<Object> violation : allViolations) {
                // ...extract "" from field annotation like @Value("${}")
                String propertyName = violation.getLeafBean().getClass()
                propertyName = StringUtils.substring(propertyName, 2, -1);

                // .. log it ..
                LOG.error(propertyName + " " + violation.getMessage());

            // ... and do not let the app start up.
            throw new IllegalArgumentException("Invalid configuration detected. Please check the log for details.");


And here's a test for it:

public class ConfigurationCheckerTest extends EasyMockSupport {

    private ConfigurationChecker checker = new ConfigurationChecker();

    private ContextRefreshedEvent event;
    private ApplicationContext applicationContext;

    @Test(expected = IllegalArgumentException.class)
    public void test() {

        expect(this.applicationContext.getBeanDefinitionNames()).andReturn(new String[] { "configurationChecker" });







All Articles