RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Stereotype Annotations Cut Down XML Configuration in Spring : Page 2

Spring stereotype annotations can greatly reduce the amount of XML configuration required to build and maintain a Spring application.


Using Stereotype Annotations: Setup and Configuration

To use the Spring stereotype annotations, you need a Spring 2.5 or later environment. That is, the Spring 2.5 or later JAR file (spring.jar) must be available on the classpath of your project. The first Spring stereotype, @Repository, was released with Spring 2.0. Therefore, if @Repository were the only annotation you used, a Spring 2.0 environment would suffice.

Spring MVC provides many additional annotations that support and augment the @Controller annotation in web applications, which means you also need the Spring MVC library JAR (spring-webmvc.jar) to use many of the controller-related annotations.

Again, the purpose of the stereotype annotation (or any annotation for that matter) is to reduce the amount of XML configuration. Therefore, annotated beans serving in a stereotype role do not need to be configured in the Spring XML configuration file. Instead, Spring provides a mechanism to automatically detect (something the Spring Framework documentation calls "autodect") stereotype components.

To have the Spring Framework autodect the stereotype beans, include a component-scan element in the Spring XML configuration file (as shown below). Note the context schema that is required to use the component-scan element.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"

  <context:component-scan base-package="org.intertech"/>

The scan element forces the Spring container to search the package specified in the base-package attribute for all stereotype components. The base-package attribute specifies the parent package to look for stereotype components, but the Spring container scans all sub-packages as well. Use a comma-separated list of package names when you need to search multiple packages:

 base-package="com.intertech.mvc, com.intertech.dao"/>

By default, all components marked with the @Repository, @Service, @Controller, and @Component annotations are detected in the scan. However, you can configure the component-scan element with filters to include or exclude classes in the scan. In the example below, a regular expression include filter allows all classes that end in "Dao" to be included in the scan. Conversely, any component marked with a "@Service" annotation is excluded from the scan.

<context:component-scan base-package="com.intertech">
 <context:include-filter type="regex" expression=".*Dao" />
 <context:exclude-filter type="annotation"
 expression="org.springframework.stereotype.Service" />

Five different types of filters are available for including or excluding classes in a scan. Table 2 describes each of them.

Table 2. Five Types of Filter for Including/Excluding Classes from a Stereotype Component Scan
Filter Type Description Expression Example
annotation Include or exclude those classes with a stereotype annotation org.springframework. stereotype.Repository
aspectj Use an AspectJ expression to specify classes to include or exclude (requires AspectJ libraries) com.intertech..*Controller
assignable Include or exclude classes that extend or implement this class or interface org.intertech.mvc.BaseController
custom A custom implementation of the org.springframework.core.type.TypeFilter interface com.intertech.IntertechTypeFilterImpl
regex Use a regular expression to specify classes to include or exclude .*Controller

In essence, default annotation include filters scan the @Repository, @Service, @Controller, and @Component annotations, but you can disable this behavior. To turn off the automatic inclusion of components with the stereotype annotations, add the use-default-filters="false" attribute to the component-scan element. The example component-scan configuration below turns off this default behavior (to include all components with a stereotype annotation) and includes only those assignable from com.intertech.mvc.IntertechBaseController.

<context:component-scan base-package="com.intertech" 
 <context:include-filter type="assignable"
  expression="com.intertech.mvc.IntertechBaseController" />

Annotating Components

To create a stereotype component, apply the @Repository, @Service, @Controller, or @Component annotation on the class definition. Consider the typical service-to-DAO component relationship as set up in a standard Spring XML configuration file:

<bean id="orderService" class="com.intertech.OrderServiceImpl">
 <property name="orderDao" ref="orderDao"/>
<bean id="orderDao" class="com.intertech.OrderDaoImpl"/>

Figure 1. Relationship of Components in a Configuration to One Another: These are typical components that must be configured by XML in a Spring application.

Figure 1 depicts the relationship of the components in this configuration to one another. Using a stereotype annotation, you can simply mark the OrderDao bean as a DAO component using @Repository.

public class OrderDaoImpl implements OrderDao {

When Spring automatically detects the stereotype components, BeanNameGenerator assigns a default name to each one. BeanNameGenerator is an interface (org.springframework.beans.factory.support.BeanNameGenerator) that Spring provides by default. It works with the component scanner to provide bean names. By default, the Spring BeanNameGenerator gives each stereotype component a lower CamelCase of the class name as its name. So, in the example above, the repository's name would be "orderDaoImpl." If you don't like the default name, you can implement your own generator and register it with the component scanner:

<context:component-scan base-package="com.intertech" 
 name-generator="com.intertech.utils.IntertechNameGenerator" />

Also, you can give an explicit name to any stereotype component by providing a component name with the annotation:

public class OrderDaoImpl implements OrderDao{

Given the stereotype annotation, the Spring XML configuration file no longer has to carry the DAO bean. Here is the reduced XML Spring configuration, given the repository annotation and repository's default name:

<bean id="orderService" class="com.intertech.OrderServiceImpl">
 <property name="orderDao" ref="orderDaoImpl"/>

In this scenario, you probably would make the OrderService a stereotype component (with an @Service annotation) also. Furthermore, because you are using annotations, you would likely use the @Autowired annotation with regard to the DAO:

public class OrderService {
 private OrderDao orderDao;

Because Spring automatically includes some additional BeanPostProcessors when you use the component-scan element (<context:component-scan>), it automatically provides annotated autowiring with the component-scan as well. So now, with stereotype and @Autowired annotations in these two classes, absolutely no XML configuration is required for either the OrderService or OrderDao!

As with all Spring beans, stereotype components are singletons by default. However, you can set their scope explicitly with a @Scope annotation (org.springframework.context.annotation.Scope):

public class OrderDaoImpl implements OrderDao{

Author's Note: Spring did not introduce the @Scope annotation until version 2.5. So even though repository components (@Repository) are available in Spring 2.0, prototype repositories are not.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date