Gordon Dickens is an instructor, mentor & consultant. Gordon is currently architecting and teaching several official SpringSource courses and actively tweets about open source technology at http://twitter.com/gdickens. Gordon is active within the Spring Framework community focussed on: Spring training, Spring Roo, Spring Integration, Spring Batch and Eclipse Virgo OSGi projects. Gordon is a DZone MVB and is not an employee of DZone and has posted 39 posts at DZone. You can read more from them at their website. View Full User Profile

Enterprise Spring Best Practices – Part 4 – Annotation Config

11.24.2012
| 4536 views |
  • submit to reddit

 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

Published at DZone with permission of Gordon Dickens, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)