public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware
BeanPostProcessor
implementation
that enforces required JavaBean properties to have been configured.
Required bean properties are detected through a Java 5 annotation:
by default, Spring's Required
annotation.
The motivation for the existence of this BeanPostProcessor is to allow developers to annotate the setter properties of their own classes with an arbitrary JDK 1.5 annotation to indicate that the container must check for the configuration of a dependency injected value. This neatly pushes responsibility for such checking onto the container (where it arguably belongs), and obviates the need (in part) for a developer to code a method that simply checks that all required properties have actually been set.
Please note that an 'init' method may still need to implemented (and may
still be desirable), because all that this class does is enforce that a
'required' property has actually been configured with a value. It does
not check anything else... In particular, it does not check that a
configured value is not null
.
Note: A default RequiredAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags. Remove or turn off the default annotation configuration there if you intend to specify a custom RequiredAnnotationBeanPostProcessor bean definition.
setRequiredAnnotationType(java.lang.Class<? extends java.lang.annotation.Annotation>)
,
Required
Modifier and Type | Field and Description |
---|---|
private ConfigurableListableBeanFactory |
beanFactory |
private int |
order |
private java.lang.Class<? extends java.lang.annotation.Annotation> |
requiredAnnotationType |
static java.lang.String |
SKIP_REQUIRED_CHECK_ATTRIBUTE
Bean definition attribute that may indicate whether a given bean is supposed
to be skipped when performing this post-processor's required property check.
|
private java.util.Set<java.lang.String> |
validatedBeanNames
Cache for validated bean names, skipping re-validation for the same bean
|
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE
Constructor and Description |
---|
RequiredAnnotationBeanPostProcessor() |
Modifier and Type | Method and Description |
---|---|
private java.lang.String |
buildExceptionMessage(java.util.List<java.lang.String> invalidProperties,
java.lang.String beanName)
Build an exception message for the given list of invalid properties.
|
int |
getOrder()
Get the order value of this object.
|
protected java.lang.Class<? extends java.lang.annotation.Annotation> |
getRequiredAnnotationType()
Return the 'required' annotation type.
|
protected boolean |
isRequiredProperty(java.beans.PropertyDescriptor propertyDescriptor)
Is the supplied property required to have a value (that is, to be dependency-injected)?
|
void |
postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
java.lang.Class<?> beanType,
java.lang.String beanName)
Post-process the given merged bean definition for the specified bean.
|
PropertyValues |
postProcessPropertyValues(PropertyValues pvs,
java.beans.PropertyDescriptor[] pds,
java.lang.Object bean,
java.lang.String beanName)
Post-process the given property values before the factory applies them
to the given bean.
|
void |
setBeanFactory(BeanFactory beanFactory)
Callback that supplies the owning factory to a bean instance.
|
void |
setOrder(int order) |
void |
setRequiredAnnotationType(java.lang.Class<? extends java.lang.annotation.Annotation> requiredAnnotationType)
Set the 'required' annotation type, to be used on bean property
setter methods.
|
protected boolean |
shouldSkip(ConfigurableListableBeanFactory beanFactory,
java.lang.String beanName)
Check whether the given bean definition is not subject to the annotation-based
required property check as performed by this post-processor.
|
determineCandidateConstructors, getEarlyBeanReference, postProcessAfterInitialization, postProcessAfterInstantiation, postProcessBeforeInitialization, postProcessBeforeInstantiation, predictBeanType
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
postProcessAfterInitialization, postProcessBeforeInitialization
public static final java.lang.String SKIP_REQUIRED_CHECK_ATTRIBUTE
private java.lang.Class<? extends java.lang.annotation.Annotation> requiredAnnotationType
private int order
private ConfigurableListableBeanFactory beanFactory
private final java.util.Set<java.lang.String> validatedBeanNames
public void setRequiredAnnotationType(java.lang.Class<? extends java.lang.annotation.Annotation> requiredAnnotationType)
The default required annotation type is the Spring-provided
Required
annotation.
This setter property exists so that developers can provide their own (non-Spring-specific) annotation type to indicate that a property value is required.
protected java.lang.Class<? extends java.lang.annotation.Annotation> getRequiredAnnotationType()
public void setBeanFactory(BeanFactory beanFactory)
BeanFactoryAware
Invoked after the population of normal bean properties
but before an initialization callback such as
InitializingBean.afterPropertiesSet()
or a custom init-method.
setBeanFactory
in interface BeanFactoryAware
beanFactory
- owning BeanFactory (never null
).
The bean can immediately call methods on the factory.BeanInitializationException
public void setOrder(int order)
public int getOrder()
Ordered
Higher values are interpreted as lower priority. As a consequence,
the object with the lowest value has the highest priority (somewhat
analogous to Servlet load-on-startup
values).
Same order values will result in arbitrary sort positions for the affected objects.
getOrder
in interface Ordered
Ordered.HIGHEST_PRECEDENCE
,
Ordered.LOWEST_PRECEDENCE
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, java.lang.Class<?> beanType, java.lang.String beanName)
MergedBeanDefinitionPostProcessor
postProcessMergedBeanDefinition
in interface MergedBeanDefinitionPostProcessor
beanDefinition
- the merged bean definition for the beanbeanType
- the actual type of the managed bean instancebeanName
- the name of the beanpublic PropertyValues postProcessPropertyValues(PropertyValues pvs, java.beans.PropertyDescriptor[] pds, java.lang.Object bean, java.lang.String beanName) throws BeansException
InstantiationAwareBeanPostProcessor
Also allows for replacing the property values to apply, typically through creating a new MutablePropertyValues instance based on the original PropertyValues, adding or removing specific values.
The default implementation returns the given pvs
as-is.
postProcessPropertyValues
in interface InstantiationAwareBeanPostProcessor
postProcessPropertyValues
in class InstantiationAwareBeanPostProcessorAdapter
pvs
- the property values that the factory is about to apply (never null
)pds
- the relevant property descriptors for the target bean (with ignored
dependency types - which the factory handles specifically - already filtered out)bean
- the bean instance created, but whose properties have not yet been setbeanName
- the name of the beannull
to skip property populationBeansException
- in case of errorsMutablePropertyValues
protected boolean shouldSkip(ConfigurableListableBeanFactory beanFactory, java.lang.String beanName)
The default implementations check for the presence of the
SKIP_REQUIRED_CHECK_ATTRIBUTE
attribute in the bean definition, if any.
It also suggests skipping in case of a bean definition with a "factory-bean"
reference set, assuming that instance-based factories pre-populate the bean.
beanFactory
- the BeanFactory to check againstbeanName
- the name of the bean to check againsttrue
to skip the bean; false
to process itprotected boolean isRequiredProperty(java.beans.PropertyDescriptor propertyDescriptor)
This implementation looks for the existence of a
"required" annotation
on the supplied property
.
propertyDescriptor
- the target PropertyDescriptor (never null
)true
if the supplied property has been marked as being required;
false
if not, or if the supplied property does not have a setter methodprivate java.lang.String buildExceptionMessage(java.util.List<java.lang.String> invalidProperties, java.lang.String beanName)
invalidProperties
- the list of names of invalid propertiesbeanName
- the name of the bean