Part 1: Spring Annotations

This tutorial is part 1 of 5-part tutorial on JEE annotations. We recommend that you read Prerequisite section first, review the abstract and Example Application to understand the context. You can also jump to other parts by clicking on the links below.

Spring Annotations: Contents:

AnnotationPackage Detail/Import statement
@Serviceimport org.springframework.stereotype.Service;
@Repositoryimport org.springframework.stereotype.Repository;
@Componentimport org.springframework.stereotype.Component;
@Autowiredimport org.springframework.beans.factory.annotation.Autowired;
@Transactionalimport org.springframework.transaction.annotation.Transactional;
@Scopeimport org.springframework.context.annotation.Scope;
Spring MVC Annotations
@Controllerimport org.springframework.stereotype.Controller;
@RequestMappingimport org.springframework.web.bind.annotation.RequestMapping;
@PathVariableimport org.springframework.web.bind.annotation.PathVariable;
@RequestParamimport org.springframework.web.bind.annotation.RequestParam;
@ModelAttributeimport org.springframework.web.bind.annotation.ModelAttribute;
@SessionAttributesimport org.springframework.web.bind.annotation.SessionAttributes;
Spring Security Annotations
@PreAuthorizeimport org.springframework.security.access.prepost.PreAuthorize;


For spring to process annotations, add the following lines in your application-context.xml file.
	<context:annotation-config />
	<context:component-scan base-package="...specify your package name..." />
Spring Annotation Tip Spring supports both Annotation based and XML based configurations. You can even mix them together. Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches.

@Service

Annotate all your service classes with @Service. All your business logic should be in Service classes.
@Service
public class CompanyServiceImpl implements CompanyService {
...
}

@Repository

Annotate all your DAO classes with @Repository. All your database access logic should be in DAO classes.
@Repository
public class CompanyDAOImpl implements CompanyDAO {
...
}

@Component

Annotate your other components (for example REST resource classes) with @Component.
@Component
public class ContactResource {
...
}
@Component is a generic stereotype for any Spring-managed component. @Repository, @Service, and @Controller are specializations of @Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively.

Spring Component Annotations

@Autowired

Let Spring auto-wire other beans into your classes using @Autowired annotation.

@Service
public class CompanyServiceImpl implements CompanyService {

  @Autowired
  private CompanyDAO companyDAO;
  
  ...
}
Spring Annotation Tip Spring beans can be wired by name or by type.
  • @Autowire by default is a type driven injection. @Qualifier spring annotation can be used to further fine-tune autowiring.
  • @Resource (javax.annotation.Resource) annotation can be used for wiring by name.
Beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection or map bean by unique name.

@Transactional

Configure your transactions with @Transactional spring annotation.
@Service
public class CompanyServiceImpl implements CompanyService {

  @Autowired
  private CompanyDAO companyDAO;

  @Transactional
  public Company findByName(String name) {

    Company company = companyDAO.findByName(name);
    return company;
  }
  ...
}
Spring Annotation Tip To activate processing of Spring's @Transactional annotation, use the <tx:annotation-driven/> element in your spring's configuration file.

The default @Transactional settings are as follows:
  • Propagation setting is PROPAGATION_REQUIRED.
  • Isolation level is ISOLATION_DEFAULT.
  • Transaction is read/write.
  • Transaction timeout defaults to the default timeout of the underlying transaction system, or to none if timeouts are not supported.
  • Any RuntimeException triggers rollback, and any checked Exception does not.
These default settings can be changed using various properties of the @Transactional spring annotation.

Spring Annotation Tip Specifying the @Transactional annotation on the bean class means that it applies to all applicable business methods of the class. Specifying the annotation on a method applies it to that method only. If the annotation is applied at both the class and the method level, the method value overrides if the two disagree.

@Scope

As with Spring-managed components in general, the default and most common scope for autodetected components is singleton. To change this default behavior, use @Scope spring annotation.
@Component
@Scope("request")
public class ContactResource {
...
}
Similarly, you can annotate your component with @Scope("prototype") for beans with prototype scopes.
Spring Annotation Tip Please note that the dependencies are resolved at instantiation time. For prototype scope, it does NOT create a new instance at runtime more than once. It is only during instantiation that each bean is injected with a separate instance of prototype bean.

Spring MVC Annotations

@Controller

Annotate your controller classes with @Controller.
@Controller
public class CompanyController {
...
}

@RequestMapping

You use the @RequestMapping spring annotation to map URLs onto an entire class or a particular handler method. Typically the class-level annotation maps a specific request path (or path pattern) onto a form controller, with additional method-level annotations narrowing the primary mapping.
@Controller
@RequestMapping("/company")
public class CompanyController {

  @Autowired
  private CompanyService companyService;
...
}

@PathVariable

You can use the @PathVariable spring annotation on a method argument to bind it to the value of a URI template variable. In our example below, a request path of /company/techferry will bind companyName variable with 'techferry' value.
@Controller
@RequestMapping("/company")
public class CompanyController {

  @Autowired
  private CompanyService companyService;

  @RequestMapping("{companyName}")
  public String getCompany(Map<String, Object> map, @PathVariable String companyName) {
    Company company = companyService.findByName(companyName);
    map.put("company", company);
    return "company";
  }
...
}

@RequestParam

You can bind request parameters to method variables using spring annotation @RequestParam.
@Controller
@RequestMapping("/company")
public class CompanyController {

  @Autowired
  private CompanyService companyService;

  @RequestMapping("/companyList")
  public String listCompanies(Map<String, Object> map, @RequestParam int pageNum) {
    map.put("pageNum", pageNum);
    map.put("companyList", companyService.listCompanies(pageNum));
    return "companyList";
  }
...
}
Similarly, you can use spring annotation @RequestHeader to bind request headers.

@ModelAttribute

An @ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument's fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.
@Controller
@RequestMapping("/company")
public class CompanyController {

  @Autowired
  private CompanyService companyService;

  @RequestMapping("/add")
  public String saveNewCompany(@ModelAttribute Company company) {
    companyService.add(company);
    return "redirect:" + company.getName();
  }
...
}

@SessionAttributes

@SessionAttributes spring annotation declares session attributes. This will typically list the names of model attributes which should be transparently stored in the session, serving as form-backing beans between subsequent requests.
@Controller
@RequestMapping("/company")
@SessionAttributes("company")
public class CompanyController {

  @Autowired
  private CompanyService companyService;
...
}
@SessionAttribute works as follows:
  • @SessionAttribute is initialized when you put the corresponding attribute into model (either explicitly or using @ModelAttribute-annotated method).
  • @SessionAttribute is updated by the data from HTTP parameters when controller method with the corresponding model attribute in its signature is invoked.
  • @SessionAttributes are cleared when you call setComplete() on SessionStatus object passed into controller method as an argument.
The following listing illustrate these concepts. It is also an example for pre-populating Model objects.
@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {

	@ModelAttribute("types")
	
	public Collection<PetType> populatePetTypes() {
		return this.clinic.getPetTypes();
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, 
			SessionStatus status) {
		new PetValidator().validate(pet, result);
		if (result.hasErrors()) {
			return "petForm";
		}else {
			this.clinic.storePet(pet);
			status.setComplete();
			return "redirect:owner.do?ownerId=" + pet.getOwner().getId();
		}
	}
}

Spring Security Annotations

@PreAuthorize

Using Spring Security @PreAuthorize annotation, you can authorize or deny a functionality. In our example below, only a user with Admin role has the access to delete a contact.
  @Transactional
  @PreAuthorize("hasRole('ROLE_ADMIN')")
  public void removeContact(Integer id) {
    contactDAO.removeContact(id);
  }

References:

  1. Spring Annotations: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/beans.html#beans-annotation-config
  2. Spring Framework Reference: http://static.springsource.org/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf