Enterprise Spring Best Practices – Part 4 – Annotation Config

Enterprise Spring Best Practices Series

In part 4, Spring Annotation Configuration.

In this edition of Enterprise Spring Best Practices, let’s look at annotations. Several of the annotations became available in Spring 2.5. Spring 3.0 added convenient annotation discovery mechanisms which we’ll see here.

Annotations are available for Dependency Injection, Bean discovery and instantiation, post processing (required fields, initialization method, etc).

Annotations may or may NOT be discovered in java interfaces, refer to the documentation or JavaDoc for details on whether the annotation discovery mechanism will traverse upward in the class hierarchy.


Sections




Annotation Style Decision



Annotations help simplify configuration. All annotations in Java 5 and above, require some discovery mechanism.

Within Spring, we have 3 strategies for bean discovery and dependency injection

  1. XML based discovery
  2. JavaConfig
  3. Hybrid Configuration

Hybrid configuration is simply mixing standard XML <bean/> declarations with annotation methods discussed below. In the next blog, I will discuss JavaConfig, so for now lets focus on XML based discovery of Annotations.



Annotation Discovery from XML



All annotations REQUIRE a discovery directive. We MUST know which XML directives discover particular annotations, or the beans will not be processed.
For Spring annotation discovery detail, see Annotation Reference for Spring Projects

Option 1 – Register individual bean post processors

There are several individual Bean Post Processors that can be registered to discover specific annotation categories

  • RequiredAnnotationBeanPostProcessor – (@Required)
  • CommonAnnotationBeanPostProcessor – (@PostConstruct, @PreDestroy, @Resource, etc.)
  • AutowiredAnnotationBeanPostProcessor – (@Autowired, @Value, @Inject, etc.)
  • PersistenceAnnotationBeanPostProcessor – (@PersistenceUnit, @PersistenceContext, etc.)

Option 2 – Use the annotation-config directive

Automatically registers the Bean Post Processors above.

  <context:annotation-config/>

Option 3 – Use the component-scan directive

Automatically registers the Bean Post Processors above AND scans for component annotations @Component, @Repository, @Service, @Controller, and more…

  <context:context:component-scan 
      base-package="com.gordondickens.enterprisespring"/>



Application Component Scanning



Exclude configuration elements that are not part of the underlying application. Controllers are part of the application that deals with the user interface but are not pertinent to Web Services.
Within applicationContext-bootstrap.xml

<context:component-scan 
  base-package="com.gordondickens.enterprisespring">
    
  <context:exclude-filter
    expression="org.springframework.stereotype.Controller"
    type="annotation"/>
</context:component-scan>



MVC Component Scanning



Exclude components are not part of the entire application. If our application serves UI clients and web service clients, only the base components should be discovered in the main application configuration. We will discuss MVC configuration in a future blog.

Within applicationContext-webmvc.xml

<context:component-scan 
  base-package="com.gordondickens.enterprisespring"
  use-default-filters="false"/>

    <context:include-filter 
      expression="org.springframework.stereotype.Controller" 
      type="annotation"/>
</context:component-scan>



Component Scanning Best Practices



When Spring creates the application context, it aggregates all of the configuration into a single context, no matter how many configuration files or annotations are used.

  • Component scanning should ONLY be configured in the bootstrap config file, not in every XML config file
  • Do NOT also include the <context:annotation-config/> directive, it is automatically included by component scan
  • Do NOT start scanning from “com” and/or “org”, as this will scan ALL sub packages in all of the project and jars for candidates!
  • Be as specific as possible with the packages
  • Do NOT cross application boundaries with component-scan
    • Create an applicationContext-services.xml for scanning services
    • Create an applicationContext-persistence.xml for persistence and entity beans
    • Create an applicationContext-webmvc.xml for persistence and entity beans
    • Create an applicationContext-webservice.xml for web service beans
    • Import these references into the applicationContext-bootstrap.xml to these elements

Why separate the discovery files into layer specific configuration?

  • Unit testing is easier as discovery of beans is more specific
  • Allows the project to be separated into multiple Jar/Wars
  • Lowers risk of widely scoped discovery issues, overscanning and beans being replaced by multiple scanners

For Spring annotation discovery detail, see Annotation Reference for Spring Projects



Further Reading




Social Me



Twitter – twitter.com/gdickens
LinkedIn – linkedin.com/in/gordondickens
GitHub: github.com/gordonad
gordon@gordondickens.com


About Gordon

Technology enthusiast primarily focused on Java and Open Source projects. Spring Certified Professional and Trainer. http://twitter.com/gdickens http://linkedin.com/in/gordondickens http://github.com/gordonad
This entry was posted in Spring and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>