Skip to content

Annotation to validate required bean attributes [SPR-1047] #5754

@spring-projects-issues

Description

@spring-projects-issues

Magnus Heino opened SPR-1047 and commented

Bean definitions are required to provide a value for bean attributes defined as required using jdk1.5 annotation.

This provides a check to validate that values are not "forgotten" when creating new bean definitions. Values that are not properly set in the bean definition and are not be used immediately after bean instantiation will not be found otherwise.

package se.lantmateriet.jollen.bryggan.support;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**

  • JDK 1.5+ method-level annotation that indicates that the value
  • is required to be non-null.
  • @author Magnus Heino
    */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequiredAttribute {
    }

/**
*
*/
package se.lantmateriet.jollen.bryggan.support;

import java.lang.reflect.Field;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;

/**

  • @author maghei

*/
public class RequiredAttributeValidator implements BeanFactoryPostProcessor {

/* (non-Javadoc)
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
 */
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

	for(String beanName: beanFactory.getBeanDefinitionNames()) {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
		
		if(beanDefinition.isAbstract()) {
			continue;
		}
		
		MutablePropertyValues beanProperties = beanDefinition.getPropertyValues();
					
		for(Field field: beanFactory.getType(beanName).getDeclaredFields()) {
			RequiredAttribute requiredAttribute = field.getAnnotation(RequiredAttribute.class);
			if(requiredAttribute != null) {
				Object value = beanProperties.getPropertyValue(field.getName());
				if(value == null) {						
					throw new BeanDefinitionValidationException("Required attribute '" + field.getName() + "' of class '" + beanDefinition.getClass().getName() + "' defined in bean '" + beanName + "' in file '" + beanDefinition.getResourceDescription() + "' is  null.");
				} 
			}
		}		
		
	}
	
}

}


Attachments:

Issue Links:

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions