Class CommonAnnotationBeanPostProcessor

java.lang.Object
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
All Implemented Interfaces:
Serializable, org.springframework.beans.factory.aot.BeanRegistrationAotProcessor, org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanFactoryAware, org.springframework.beans.factory.config.BeanPostProcessor, org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor, org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor, org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor, org.springframework.core.Ordered, org.springframework.core.PriorityOrdered

public class CommonAnnotationBeanPostProcessor extends org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor implements org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor, org.springframework.beans.factory.BeanFactoryAware, Serializable
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:
  • Constructor Details

    • CommonAnnotationBeanPostProcessor

      public CommonAnnotationBeanPostProcessor()
      Create a new CommonAnnotationBeanPostProcessor, with the init and destroy annotation types set to PostConstruct and PreDestroy, respectively.
  • Method Details

    • ignoreResourceType

      public void ignoreResourceType(String resourceType)
      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.

      See Also:
      • AutowireCapableBeanFactory.resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String)
    • setAlwaysUseJndiLookup

      public void setAlwaysUseJndiLookup(boolean alwaysUseJndiLookup)
      Set whether to always use JNDI lookups equivalent to standard Jakarta EE resource injection, even for name 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 for name attributes and default names.

      See Also:
    • setJndiFactory

      public void setJndiFactory(org.springframework.beans.factory.BeanFactory jndiFactory)
      Specify the factory for objects to be injected into @Resource / @EJB annotated fields and setter methods, for mappedName 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 for name attributes and default names.

      The default is a SimpleJndiBeanFactory for JNDI lookup behavior equivalent to standard Jakarta EE resource injection.

      See Also:
    • setResourceFactory

      public void setResourceFactory(org.springframework.beans.factory.BeanFactory resourceFactory)
      Specify the factory for objects to be injected into @Resource / @EJB annotated fields and setter methods, for name 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 for name attributes and default names. This is the same behavior that the "alwaysUseJndiLookup" flag enables.

      See Also:
    • setBeanFactory

      public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)
      Specified by:
      setBeanFactory in interface org.springframework.beans.factory.BeanFactoryAware
    • postProcessMergedBeanDefinition

      public void postProcessMergedBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
      Specified by:
      postProcessMergedBeanDefinition in interface org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor
      Overrides:
      postProcessMergedBeanDefinition in class org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
    • resetBeanDefinition

      public void resetBeanDefinition(String beanName)
      Specified by:
      resetBeanDefinition in interface org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor
    • postProcessBeforeInstantiation

      public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
      Specified by:
      postProcessBeforeInstantiation in interface org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
    • postProcessAfterInstantiation

      public boolean postProcessAfterInstantiation(Object bean, String beanName)
      Specified by:
      postProcessAfterInstantiation in interface org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
    • postProcessProperties

      public org.springframework.beans.PropertyValues postProcessProperties(org.springframework.beans.PropertyValues pvs, Object bean, String beanName)
      Specified by:
      postProcessProperties in interface org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
    • buildLazyResourceProxy

      protected Object buildLazyResourceProxy(CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName)
      Obtain a lazily resolving resource proxy for the given name and type, delegating to getResource(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/method
      requestingBeanName - 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 org.springframework.beans.factory.NoSuchBeanDefinitionException
      Obtain the resource object for the given name and type.
      Parameters:
      element - the descriptor for the annotated field/method
      requestingBeanName - the name of the requesting bean
      Returns:
      the resource object (never null)
      Throws:
      org.springframework.beans.factory.NoSuchBeanDefinitionException - if no corresponding target resource found
    • autowireResource

      protected Object autowireResource(org.springframework.beans.factory.BeanFactory factory, CommonAnnotationBeanPostProcessor.LookupElement element, @Nullable String requestingBeanName) throws org.springframework.beans.factory.NoSuchBeanDefinitionException
      Obtain a resource object for the given name and type through autowiring based on the given factory.
      Parameters:
      factory - the factory to autowire against
      element - the descriptor for the annotated field/method
      requestingBeanName - the name of the requesting bean
      Returns:
      the resource object (never null)
      Throws:
      org.springframework.beans.factory.NoSuchBeanDefinitionException - if no corresponding target resource found