Followers

Friday, 30 March 2012

Spring Intergration to Eclipse IDE


Now that we have downloaded Spring Framework, we will see how to integrate it with Eclipse IDE.
Eclipse IDE by default is just a platform for development, which doesn’t carry all the JEE features required. It doesn’t ship with support for Spring Framework as you would know by now. So we will see how to integrate Spring Framework with Eclipse IDE using a standard plugin available called SpringIDE. Eclipse IDE is available in different releases, and these steps are almost similar to all of them. This post demonstrates using Eclipse Galileo (Eclipse version 3.5.0 release). If you have any doubts related to Eclipse IDE releases or its download / installation / configuration, refer to Eclipse IDE Installation & Configuration post.

What is Spring IDE
SpringIDE provides a user interface for Spring configuration files, built as a set of plugins on the Eclipse platform. It is a set of free plugins for the Eclipse platform that helps in developing Spring Application. The IDE provides a wizard for creating Spring projects, and using the Graphical Editing Framework, displays graphs of all beans (objects) and relationships either within a single configuration file or within a set of configuration files. The files, or sets, are also validated as they are added / modified. There’s also support for Spring AOP, so pointcut expressions are validated in your Spring configuration. 
Spring IDE (http://www.springsource.com/products/springide) is a product from Spring Source (http://www.springsource.com/). Refer to Spring Primer for details. Latest SpringIDE version avaiable is 2.0.3.

Follow the steps below: 
  • Once Eclipse is up and running, use the Eclipse Software Update wizard either by navigating to Help->Install New Software (Eclipse 3.5 onwards) or Help->Software Updates (prior to Eclispe 3.5 version) as shown below: 

 or


 
or 
 

  •  For Eclipse versions 3.5 and above, click on Add button shown and then you will get the Add Site wizard. Enter the name as Spring IDE or likewise for your reference later and click ok as shown below:

  • Select all the Spring IDE features and click Next or Install for Eclipse 3.5 version onwards and Eclipse prior to this version respectively as shown below:

 or 

  • In case you don’t get any error by now, you will be presented with a License Agreement wizard. Select ‘I Accept the terms of the license agreement’ and click ‘Finish’. By doing this, Spring IDE plugin should be installed and integrated in your Eclipse IDE successfully as shown below:


  •   Restart Eclipse IDE as prompted and you should be ready to use Spring IDE:

  
  • After Eclipse restarts, we need to verify whether the plugin got installed successfully. We will do this by first choosing the Windows menu and the Preferences option of Eclipse.
 

  • We can then see Spring option in the left hand side item nodes in the preferences dialog. Choose the Spring option and it will expand to show three sub items.
     - AOP Support
    -  Beans Support
     - Web Flow Support
  • This confirms that our Spring IDE plugin has been installed successfully in Eclipse.
  
  
  
  
Troubleshooting Installation & Integration:
If you have any problems while installing as per above steps and get any error message in Eclipse IDE, read through the error message and don’t hesitate to uncheck that perticular plugin in the list where you have a problem (provided its optional). You can always install the plugin manually anytime again.
For example:
When you click on Next / Install after chosing the plugins you want to install, you might get an error message saying:
Cannot complete the install because one or more required items could not be found.  Software being installed: Spring IDE AJDT Integration (optional) 2.2.8.200911091054-RELEASE
In this case, as AJDT (AspectJ Development Tools) integration plugin is an optional update and if you have trouble installing it while updating the entire Spring Framework plugin, you can uncheck this plugin from the displayed list and continue to install other updates.  You can always install the plugin manually anytime again.


After doing so, and clicking on ‘Next’, you should do away with the error message and be presented with the License Agreement wizard upon selecting which your installation should be complete.

Wednesday, 28 March 2012

Annotation based configuration in Spring

It is now possible to configure Spring's dependency injection with annotations. This means that annotations can be used in Spring to mark fields, methods and classes that need dependency injection. Spring also supports auto-wiring of the bean dependencies, that is, resolving the collaborating beans by inspecting the contents of the BeanFactory. Now there are annotations that can be used to indicate fields that are to be auto-wired. Furthermore, auto-detection of annotated components in the classpath is also supported now. When these capabilities are combined, the amount of configuration and dependency mapping in the Spring configuration files is reduced drastically.
According to the Spring development team, the core theme of Spring 2.5 that was released in October 2007 is to provide comprehensive support for configuration annotations in application components. Annotation support was first announced in Spring 2.0, and has been significantly enhanced in Spring 2.5. It introduces support for a complete set of configuration annotations.
I'll briefly discuss the annotation-driven configuration and auto-detection support in Spring 2.5 with the help of a simple tutorial.
What you need before you start
You need the following software to try out the tutorial.
You also need the following jars in your classpath. These are available with the Spring distribution.
  • spring.jar
  • asm-2.2.3.jar
  • asm-commons-2.2.3.jar
  • aspectjweaver.jar
  • aspectjrt.jar
  • hsqldb.jar
  • commons-logging.jar
  • log4j-1.2.14.jar
  • junit-4.4.jar
  • spring-test.jar
  • common-annotations.jar(This is not required if Java 6.0 or later is used)
Adding the classes and interfaces for the example
The example is just a simple service that returns a different message when an employee is hired or fired.
Let me start with the EmployeeService interface.
package emptest;

public interface EmployeeService {
 String hire(String name);

 String fire(String name);
}

Here is a simple class that implements this interface.
@Service
public class EmployeeServiceImpl implements EmployeeService {
 @Autowired
 private EmployeeDao employeeDao;

 public String hire(String name) {
  String message = employeeDao.getMessage("Hire");
  return name + ", " + message;
 }

 public String fire(String name) {
  String message = employeeDao.getMessage("Fire");
  return name + ", " + message;
 }

 public void setEmployeeDao(EmployeeDao employeeDao) {
  this.employeeDao = employeeDao;
 }
}
Stereotype Annotations
Classes marked with stereotype annotations are candidates for auto-detection by Spring when using annotation-based configuration and classpath scanning. The @Component annotation is the main stereotype that indicates that an annotated class is a "component".
The @Service stereotype annotation used to decorate the EmployeeServiceImpl class is a specialized form of the @Component annotation. It is appropriate to annotate the service-layer classes with @Service to facilitate processing by tools or anticipating any future service-specific capabilities that may be added to this annotation.
The @Repository annotation is yet another stereotype that was introduced in Spring 2.0 itself. This annotation is used to indicate that a class functions as a repository (the EmployeeDAOImpl below demonstrates the use) and needs to have exception translation applied transparently on it. The benefit of exception translation is that the service layer only has to deal with exceptions from Spring's DataAccessException hierarchy, even when using plain JPA in the DAO classes.
@autowired
Another annotation used in EmployeeServiceImpl is @autowired . This is used to autowire the dependency of the EmployeeServiceImpl on the EmployeeDao . Here is the EmployeeDao interface.
public interface EmployeeDao {
    String getMessage(String messageKey);
}
The implementing class EmployeeDaoImpl uses the @Repository annotation.
@Repository
public class EmployeeDaoImpl implements EmployeeDao {

 private SimpleJdbcTemplate jdbcTemplate;

 public String getMessage(String messageKey) {
  return jdbcTemplate.queryForObject(
    "select message from messages where messagekey = ?",
    String.class, messageKey);
 }

 @Autowired
 public void createTemplate(DataSource dataSource) {
  this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
 }
}

Here again, the DataSource implementation is autowired to the argument taken by the method that creates the SimpleJdbcTemplate object.
Simplified Configuration
The components discovered by classpath scanning are turned into Spring bean definitions, not requiring explicit configuration for each such bean. So the Spring configuration xml file is very simple.
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 <context:annotation-config />
 <context:component-scan base-package="emptest" />
 <aop:aspectj-autoproxy />

 <context:property-placeholder location="classpath:jdbc.properties" />

 <bean id="dmdataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${jdbc.driver}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
 </bean>
  
</beans>

Now let me explain the new configurations in the above Spring context file. The <context:annotation-config /> element is used to automatically register all of Spring's standard post-processors for annotation-based configuration. The <context:component-scan annotation> element is used to enable autodetection of the stereotyped classes in the package emptest . Since the AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor are both included implicitly when using the component-scan element, the <context:annotation-config/> element can be omitted.
The properties for the data source are taken from the jdbc.properties file in the classpath. The property placeholders are configured with the <context:property-placeholder> element.
The <aop:aspectj-autoproxy/> element is used to enable @AspectJ support in Spring.
@Aspect
The @Aspect annotation on a class marks it as an aspect along with @Pointcut definitions and advice (@Before, @After, @Around) as demonstrated in the TraceLogger class defintion below. The PointCut is applied for all methods in the EmployeeServiceImpl class. The @Before annotation indicates that the log() method in the TraceLogger is to be invoked by Spring AOP prior to calling any method in EmployeeServiceImpl.
@Component
@Aspect
public class TraceLogger {
 private static final Logger LOG = Logger.getLogger(TraceLogger.class);

 @Pointcut("execution(* emptest.EmployeeServiceImpl.*(..))")
 public void empTrace() {
 }

 @Before("empTrace()")
 public void log(JoinPoint joinPoint) {
  LOG.info("Before calling " + joinPoint.getSignature().getName()
    + " with argument " + joinPoint.getArgs()[0]);
 }

}
Since there is no definition provided for TraceLogger in the Spring context file, it is marked for auto-detection from the classpath using the @Component annotation.
@Qualifier and @Resource
Suppose there is one more DataSource configuration in the spring context file as follows.
<bean id="jndidataSource"
 class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/test" />
</bean>
Since auto-detection is enabled, auto-wiring will fail since both data source beans are equally eligible candidates for wiring. It is possible to achieve by-name auto-wiring by providing a bean name within the @Qualifier annotation as follows. The below method injects the DataSource implementation by specifying the name “dmdataSource”.
@Autowired
public void createTemplate(@Qualifier("dmdataSource") DataSource dataSource) {
  this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
JSR-250 Annotations
Spring also provides support for Java EE 5 Common Annotations (JSR-250). The supported annotations are @Resource, @PostConstruct and @PreDestroy. The @Resource annotation is also supported by Spring for autowiring as shown in the below code, the bean name to be autowired is passed.
@Resource(name = "dmdataSource")
public void createTemplate(DataSource dataSource) {
this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
The JSR-250 lifecycle annotations @PostConstruct and @PreDestroy can be used to specify initialization callbacks and destruction callbacks respectively. To demonstrate the use of these, I’m adding the following code to the EmployeeDaoImpl class.
@PostConstruct
public void initialize() {
 jdbcTemplate.update("create table messages (messagekey varchar(20), message 

varchar(100))");
 jdbcTemplate.update("insert into messages (messagekey, message) values ('Hire', Congrats! 

You are hired')");
 jdbcTemplate.update("insert into messages (messagekey, message) values ('Fire', 'Sorry! 

You are fired')");
}

@PreDestroy
public void remove() {
 jdbcTemplate.update("drop table messages");
}

Unit Testing
Before testing the service implementation, I provided the database configuration details in the jdbc.properties file as follows.
jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:mem:blog
jdbc.username=sa
jdbc.password=
Here is the class I wrote for unit testing.
public class EmployeeServiceImplTests extends
  AbstractDependencyInjectionSpringContextTests {
 @Autowired
 private EmployeeService employeeService;

 @Override
 protected String[] getConfigLocations() {
  return new String[] { "context.xml" };
 }

 public void testHire() {
  String name = "Tom";
  String message = employeeService.hire(name);
  assertEquals(name + ", " + "Congrats! You are hired", message);
 }

 public void testGermanWelcome() {
  String name = "Jim";
  String message = employeeService.fire(name);
  assertEquals(name + ", " + "Sorry! You are fired", message);
 }

 public void setEmployeeService(EmployeeService employeeService) {
  this.employeeService = employeeService;
 }
}

Tuesday, 27 March 2012

The @transactional Annotation In Spring

The other day, on my current project, I had a situation where I needed to change some transaction parameters on a DAO to start a new transaction whenever methods on that DAO were invoked.

The application architecture is based on a generic DAO interface with standard CRUD operations implemented by a GenericDao. All DAOs have defined their own interface extending the generic DAO and likewise the implementation is extending the GenericDao:

The goal was to have all methods, defined on either the GenericDao or the (in this example) UserDaoImpl , to start a new transaction when invoked.

The GenericDao is annotated with Springs @Transactional annotation with default parameters (Propagation.REQUIRED) which will be inherited to all extending DAOs.

My first attempt to achieve my goal was to annotate the UserDaoImpl with @Transactional(propagation=Propagation.REQUIRED_NEW). Well, this did not have the effect I had hoped for. Now all methods declared on the UserDaoImpl will start a new transaction, but methods on the GenericDao will not and if I removed the annotation on the GenericDao and defined it on all DAOs then invoked methods on the GenericDao will not be transactional at all.

This forced me to investigate how Spring handles the @Transactional annotation and it all comes down to how the method getTransactionAttribute(Method method, Class targetClass) on the class AbstractFallbackTransactionAttributeSource works.

I'll try to explain:
- the method will be invoked where parameter method is Dao#update and targetClass is UserDaoImpl.
  1. The method is from the Dao interface so firstly the actual implementation will be found = GenericDao#update.
  2. This will be the first place to look for the annotation - on the method on the declaring class. Not the case here.
  3. If not on the method then look if the declaring class has defined the annotation. Yep - in this case the GenericDao has defined the annotation for default behavior for all extending DAOs, which means that a new transaction will not be started for invoked methods defined on GenericDao. If I override the method in UserDaoImpl and simply call super I would get the expected behavior, but I do not find this as a convenient solution.
  4. If the target class is a interface and the annotation is not yet present then the interface method and class is searched.
This seems like a good strategy to search for the annotation, but maybe you could argue that if the annotation is present directly on the targetClass (UserDaoImpl) then it should be used in advance of the annotation defined on the actual declaring class of the method in action. You could see this as a way to overwrite the annotaton on the super class.

In the above list this could be number 2.5 just after searching on the method then look at the targetClass before the declaring class... (if they differ at all...) What do you think? Is this a reasonable suggestion?

Well, back to my problem. My solution was of course keep the @Transactional on the GenericDao and remove it from UserDaoImpl and then create a new service in the service layer annotated with @Transactional(propagation=Propagation.REQUIRES_NEW) and actually I am more happy with this solution as it keeps the Dao operations simple and atomic.