Class CommonAnnotationBeanPostProcessor
- All Implemented Interfaces:
Serializable
,BeanRegistrationAotProcessor
,Aware
,BeanFactoryAware
,BeanPostProcessor
,DestructionAwareBeanPostProcessor
,InstantiationAwareBeanPostProcessor
,MergedBeanDefinitionPostProcessor
,Ordered
,PriorityOrdered
BeanPostProcessor
implementation
that supports common Java annotations out of the box, in particular the common
annotations in the jakarta.annotation
package. These common Java
annotations are supported in many Jakarta EE technologies (e.g. JSF and JAX-RS).
This post-processor includes support for the PostConstruct
and PreDestroy
annotations - as init annotation
and destroy annotation, respectively - through inheriting from
InitDestroyAnnotationBeanPostProcessor
with pre-configured annotation types.
The central element is the Resource
annotation
for annotation-driven injection of named beans, by default from the containing
Spring BeanFactory, with only mappedName
references resolved in JNDI.
The "alwaysUseJndiLookup" flag
enforces JNDI lookups
equivalent to standard Jakarta EE resource injection for name
references
and default names as well. The target beans can be simple POJOs, with no special
requirements other than the type having to match.
Additionally, the original javax.annotation
variants of the annotations
dating back to the JSR-250 specification (Java EE 5-8, also included in JDK 6-8)
are still supported as well. Note that this is primarily for a smooth upgrade path,
not for adoption in new applications.
This post-processor also supports the EJB EJB
annotation,
analogous to Resource
, with the capability to
specify both a local bean name and a global JNDI name for fallback retrieval.
The target beans can be plain POJOs as well as EJB Session Beans in this case.
For default usage, resolving resource names as Spring bean names, simply define the following in your application context:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>For direct JNDI access, resolving resource names as JNDI resource references within the Jakarta EE application's "java:comp/env/" namespace, use the following:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"> <property name="alwaysUseJndiLookup" value="true"/> </bean>
mappedName
references will always be resolved in JNDI,
allowing for global JNDI names (including "java:" prefix) as well. The
"alwaysUseJndiLookup" flag just affects name
references and
default names (inferred from the field name / property name).
NOTE: A default CommonAnnotationBeanPostProcessor 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 CommonAnnotationBeanPostProcessor bean definition!
NOTE: Annotation injection will be performed before XML injection; thus the latter configuration will override the former for properties wired through both approaches.
- Since:
- 2.5
- Author:
- Juergen Hoeller, Sam Brannen
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionprotected static class
Class representing generic injection information about an annotated field or setter method, supporting @Resource and related annotations. -
Field Summary
Fields inherited from class org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
logger
Fields inherited from interface org.springframework.core.Ordered
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE
-
Constructor Summary
ConstructorDescriptionCreate a new CommonAnnotationBeanPostProcessor, with the init and destroy annotation types set toPostConstruct
andPreDestroy
, respectively. -
Method Summary
Modifier and TypeMethodDescriptionprotected Object
autowireResource
(BeanFactory factory, CommonAnnotationBeanPostProcessor.LookupElement element, String requestingBeanName) Obtain a resource object for the given name and type through autowiring based on the given factory.protected Object
buildLazyResourceProxy
(CommonAnnotationBeanPostProcessor.LookupElement element, String requestingBeanName) Obtain a lazily resolving resource proxy for the given name and type, delegating togetResource(org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.LookupElement, java.lang.String)
on demand once a method call comes in.protected Object
getResource
(CommonAnnotationBeanPostProcessor.LookupElement element, String requestingBeanName) Obtain the resource object for the given name and type.void
ignoreResourceType
(String resourceType) Ignore the given resource type when resolving@Resource
annotations.boolean
postProcessAfterInstantiation
(Object bean, String beanName) Perform operations after the bean has been instantiated, via a constructor or factory method, but before Spring property population (from explicit properties or autowiring) occurs.postProcessBeforeInstantiation
(Class<?> beanClass, String beanName) Apply this BeanPostProcessor before the target bean gets instantiated.void
postProcessMergedBeanDefinition
(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) Post-process the given merged bean definition for the specified bean.postProcessProperties
(PropertyValues pvs, Object bean, String beanName) Post-process the given property values before the factory applies them to the given bean.void
resetBeanDefinition
(String beanName) A notification that the bean definition for the specified name has been reset, and that this post-processor should clear any metadata for the affected bean.void
setAlwaysUseJndiLookup
(boolean alwaysUseJndiLookup) Set whether to always use JNDI lookups equivalent to standard Jakarta EE resource injection, even forname
attributes and default names.void
setBeanFactory
(BeanFactory beanFactory) Callback that supplies the owning factory to a bean instance.void
setFallbackToDefaultTypeMatch
(boolean fallbackToDefaultTypeMatch) Set whether to allow a fallback to a type match if no explicit name has been specified.void
setJndiFactory
(BeanFactory jndiFactory) Specify the factory for objects to be injected into@Resource
/@EJB
annotated fields and setter methods, formappedName
attributes that point directly into JNDI.void
setResourceFactory
(BeanFactory resourceFactory) Specify the factory for objects to be injected into@Resource
/@EJB
annotated fields and setter methods, forname
attributes and default names.Methods inherited from class org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
addDestroyAnnotationType, addInitAnnotationType, getOrder, postProcessAfterInitialization, postProcessBeforeDestruction, postProcessBeforeInitialization, processAheadOfTime, requiresDestruction, setDestroyAnnotationType, setInitAnnotationType, setOrder
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.springframework.beans.factory.config.BeanPostProcessor
postProcessAfterInitialization, postProcessBeforeInitialization
Methods inherited from interface org.springframework.beans.factory.aot.BeanRegistrationAotProcessor
isBeanExcludedFromAotProcessing
-
Constructor Details
-
CommonAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor()Create a new CommonAnnotationBeanPostProcessor, with the init and destroy annotation types set toPostConstruct
andPreDestroy
, respectively.
-
-
Method Details
-
ignoreResourceType
Ignore the given resource type when resolving@Resource
annotations.- Parameters:
resourceType
- the resource type to ignore
-
setFallbackToDefaultTypeMatch
public void setFallbackToDefaultTypeMatch(boolean fallbackToDefaultTypeMatch) Set whether to allow a fallback to a type match if no explicit name has been specified. The default name (i.e. the field name or bean property name) will still be checked first; if a bean of that name exists, it will be taken. However, if no bean of that name exists, a by-type resolution of the dependency will be attempted if this flag is "true".Default is "true". Switch this flag to "false" in order to enforce a by-name lookup in all cases, throwing an exception in case of no name match.
-
setAlwaysUseJndiLookup
public void setAlwaysUseJndiLookup(boolean alwaysUseJndiLookup) Set whether to always use JNDI lookups equivalent to standard Jakarta EE resource injection, even forname
attributes and default names.Default is "false": Resource names are used for Spring bean lookups in the containing BeanFactory; only
mappedName
attributes point directly into JNDI. Switch this flag to "true" for enforcing Jakarta EE style JNDI lookups in any case, even forname
attributes and default names. -
setJndiFactory
Specify the factory for objects to be injected into@Resource
/@EJB
annotated fields and setter methods, formappedName
attributes that point directly into JNDI. This factory will also be used if "alwaysUseJndiLookup" is set to "true" in order to enforce JNDI lookups even forname
attributes and default names.The default is a
SimpleJndiBeanFactory
for JNDI lookup behavior equivalent to standard Jakarta EE resource injection. -
setResourceFactory
Specify the factory for objects to be injected into@Resource
/@EJB
annotated fields and setter methods, forname
attributes and default names.The default is the BeanFactory that this post-processor is defined in, if any, looking up resource names as Spring bean names. Specify the resource factory explicitly for programmatic usage of this post-processor.
Specifying Spring's
SimpleJndiBeanFactory
leads to JNDI lookup behavior equivalent to standard Jakarta EE resource injection, even forname
attributes and default names. This is the same behavior that the "alwaysUseJndiLookup" flag enables.- See Also:
-
setBeanFactory
Description copied from interface:BeanFactoryAware
Callback that supplies the owning factory to a bean instance.Invoked after the population of normal bean properties but before an initialization callback such as
InitializingBean.afterPropertiesSet()
or a custom init-method.- Specified by:
setBeanFactory
in interfaceBeanFactoryAware
- Parameters:
beanFactory
- owning BeanFactory (nevernull
). The bean can immediately call methods on the factory.- See Also:
-
postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) Description copied from interface:MergedBeanDefinitionPostProcessor
Post-process the given merged bean definition for the specified bean.- Specified by:
postProcessMergedBeanDefinition
in interfaceMergedBeanDefinitionPostProcessor
- Overrides:
postProcessMergedBeanDefinition
in classInitDestroyAnnotationBeanPostProcessor
- Parameters:
beanDefinition
- the merged bean definition for the beanbeanType
- the actual type of the managed bean instancebeanName
- the name of the bean- See Also:
-
resetBeanDefinition
Description copied from interface:MergedBeanDefinitionPostProcessor
A notification that the bean definition for the specified name has been reset, and that this post-processor should clear any metadata for the affected bean.The default implementation is empty.
- Specified by:
resetBeanDefinition
in interfaceMergedBeanDefinitionPostProcessor
- Parameters:
beanName
- the name of the bean- See Also:
-
postProcessBeforeInstantiation
Description copied from interface:InstantiationAwareBeanPostProcessor
Apply this BeanPostProcessor before the target bean gets instantiated. The returned bean object may be a proxy to use instead of the target bean, effectively suppressing default instantiation of the target bean.If a non-null object is returned by this method, the bean creation process will be short-circuited. The only further processing applied is the
BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)
callback from the configuredBeanPostProcessors
.This callback will be applied to bean definitions with their bean class, as well as to factory-method definitions in which case the returned bean type will be passed in here.
Post-processors may implement the extended
SmartInstantiationAwareBeanPostProcessor
interface in order to predict the type of the bean object that they are going to return here.The default implementation returns
null
.- Specified by:
postProcessBeforeInstantiation
in interfaceInstantiationAwareBeanPostProcessor
- Parameters:
beanClass
- the class of the bean to be instantiatedbeanName
- the name of the bean- Returns:
- the bean object to expose instead of a default instance of the target bean,
or
null
to proceed with default instantiation - See Also:
-
postProcessAfterInstantiation
Description copied from interface:InstantiationAwareBeanPostProcessor
Perform operations after the bean has been instantiated, via a constructor or factory method, but before Spring property population (from explicit properties or autowiring) occurs.This is the ideal callback for performing custom field injection on the given bean instance, right before Spring's autowiring kicks in.
The default implementation returns
true
.- Specified by:
postProcessAfterInstantiation
in interfaceInstantiationAwareBeanPostProcessor
- Parameters:
bean
- the bean instance created, with properties not having been set yetbeanName
- the name of the bean- Returns:
true
if properties should be set on the bean;false
if property population should be skipped. Normal implementations should returntrue
. Returningfalse
will also prevent any subsequent InstantiationAwareBeanPostProcessor instances being invoked on this bean instance.- See Also:
-
postProcessProperties
Description copied from interface:InstantiationAwareBeanPostProcessor
Post-process the given property values before the factory applies them to the given bean.The default implementation returns the given
pvs
as-is.- Specified by:
postProcessProperties
in interfaceInstantiationAwareBeanPostProcessor
- Parameters:
pvs
- the property values that the factory is about to apply (nevernull
)bean
- the bean instance created, but whose properties have not yet been setbeanName
- the name of the bean- Returns:
- the actual property values to apply to the given bean (can be the passed-in
PropertyValues instance), or
null
to skip property population
-
buildLazyResourceProxy
protected Object buildLazyResourceProxy(CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName) Obtain a lazily resolving resource proxy for the given name and type, delegating togetResource(org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.LookupElement, java.lang.String)
on demand once a method call comes in.- Parameters:
element
- the descriptor for the annotated field/methodrequestingBeanName
- the name of the requesting bean- Returns:
- the resource object (never
null
) - Since:
- 4.2
- See Also:
-
getResource
protected Object getResource(CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException Obtain the resource object for the given name and type.- Parameters:
element
- the descriptor for the annotated field/methodrequestingBeanName
- the name of the requesting bean- Returns:
- the resource object (never
null
) - Throws:
NoSuchBeanDefinitionException
- if no corresponding target resource found
-
autowireResource
protected Object autowireResource(BeanFactory factory, CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException Obtain a resource object for the given name and type through autowiring based on the given factory.- Parameters:
factory
- the factory to autowire againstelement
- the descriptor for the annotated field/methodrequestingBeanName
- the name of the requesting bean- Returns:
- the resource object (never
null
) - Throws:
NoSuchBeanDefinitionException
- if no corresponding target resource found
-