Spring 2.0 introduced annotation support and annotation-aware configuration options that can be leveraged by Spring users who are developing with Java 5 (or later versions):
@Transactional |
for demarcating and configuring transaction definitions |
@Aspect (AspectJ) |
for defining aspects along with @Pointcut definitions and advice (@Before, @After, @Around) |
@Repository |
for indicating a class that is operating as a repository (a.k.a. Data Access Object or DAO) |
@Required |
for enforcing annotated bean properties are provided a value |
With Spring 2.1, this theme of annotation-driven configuration has been significantly extended and will continue to evolve as we progress toward the RC1 release. In fact, it is now possible to drive Spring's dependency injection via annotations. Furthermore, Spring can discover beans that need to be configured within an application context.
This blog entry will serve as a tutorial-style introduction to the basic features in 10 easy-to-follow steps. I will follow up later in the week with information on some more advanced features and customization options. If you are interested in alternative configuration options, you should also check out the Spring Java Configuration project and this blog.
This tutorial requires at least Java 5, and Java 6 is recommended (otherwise there is a single requirement at the end of step 1).
Step 1:
Grab spring-framework-2.1-m1-with-dependencies.zip. After extracting the archive, you will find the spring.jar and spring-mock.jar in the 'dist' directory. Add them to your CLASSPATH as well as the following (paths shown are relative to the 'lib' directory of the extracted 2.1-m1 archive):
- asm/asm-2.2.3.jar
- asm/asm-commons-2.2.3.jar
- aspectj/aspectjweaver.jar
- hsqldb/hsqldb.jar
- jakarta-commons/commons-logging.jar
- log4j/log4j-1.2.14.jar
(NOTE: If you are not running on Java 6, you will also need to add j2ee/common-annotations.jar)
Step 2:
Provide the interfaces and classes for the example. I have tried to keep it as simple as possible yet capable of demonstrating the main functionality. I am including all of the code and configuration in a single "blog" package. I would encourage following that same guideline so that the examples work as-is; otherwise, be sure to make the necessary modifications. First, the
GreetingService interface:
public interface GreetingService {
String greet(String name);
}
Then, a simple implementation:
public class GreetingServiceImpl implements GreetingService {
private MessageRepository messageRepository;
public void setMessageRepository(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
public String greet(String name) {
Locale locale = Locale.getDefault();
String message = messageRepository.getMessage(locale.getDisplayLanguage());
return message + " " + name;
}
}
Since the service depends upon a MessageRepository, define…