Enterprise Spring Best Practices – Part 4 – Annotation Config
Join the DZone community and get the full member experience.
Join For FreeIn 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
- Annotation Discovery from XML
- Application Component Scanning
- MVC Component Scanning
- Component Scanning Best Practices
- Further Reading
- Social Me
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
- XML based discovery
- JavaConfig
- 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
- Create an
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, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments