Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Saturday, November 21, 2009

From Spring applicationContext.xml to Spring Annotations

Moving from Spring applicationContext.xml or any other Spring xml file to Spring annotations is done in a few steps.

First, make sure your Spring’s jar file is at least version 2.5 or download the Spring jar from SpringSource downloads.

Second, your definitions of dataSource bean, sessionFactory bean etc. are still needed, so you still need to have an XML file, though all the POJO bean definitions are replaced by Spring annotations.

So what are the available annotations?

The annotations that I’m going to use in this article are as follows:

- @Repository - org.springframework.stereotype.Repository
Repository is a class level annotation that is used for DAO objects.

- @Service - org.springframework.stereotype.Service
Service is a class level annotation that is used for Business Logic and general Façade POJOs (spring beans).

- @Autowired - org.springframework.beans.factory.annotation.Autowired
Autowired is a method/field level annotation. It handles the automatic detection of relations between classes. It is defined on a setter or a field and indicates that Spring should ‘inject’/initialize the filed with the relevant spring bean.

- @Transactional – org.springframework.transaction.annotation.Transactional
defines the transactional type of the transactions (for example propagation REQUIRED, NEW etc.)
It can be used at the class or method level.

Other useful Spring annotations:

- @Component - org.springframework.stereotype.Component
Component is a class level annotation. Indicates a Spring managed bean.
Repository and Service are both sub-annotations of Component.

- @Controller - org.springframework.stereotype.Controller
Controller is a class level annotation. It is used for Controller/Web controller POJOs. It is a Component as well.


Here you can view the annotations documentation in Spring 2.5 API.

Example of how to replace the applicationContext.xml with Spring annotations:

Before using the annotations:

I have 2 Spring beans (POJOs), one is a façade (MyFacade) and the other is a DAO (MyDao):


---------------------------------------

package com.myStuff.impl;


import java.io.Serializable;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class MyDaoImpl extends HibernateDaoSupport implements MyDao {

public Serializable createORM(MyOrm orm) {
return getHibernateTemplate().save(orm);
}

}

----------------------------------------

package com.myStuff.impl;

public class MyFacadeImpl implements MyFacade {

private MyDao myDao;

public void setMyDao(MyDao myDao) {
this.myDao = myDao;
}

@Override
public void someMethod() {

...

}

}

----------------------------------------

applicationContext.xml is defined with the following bean properties:

<bean id="MyDao" class="com.myStuff.impl.MyDaoImpl"
parent="daoTmpl" />

<bean id="MyFacade" class="com.myStuff.impl.MyFacadeImpl"/>

<bean id="daoTmpl" abstract="true" lazy-init="default"autowire="default"
dependency-check="default">
<property name="sessionFactory">
<
ref bean="sessionFactory" />
property>
bean>

----------------------------------------

In order to replace the Spring beans with annotations let’s make the following modifications in the applicationContext.xml file - We need to make sure that the “beans” tag in the applicationContext.xml imports the correct xsd files and that we enable the annotations configuration:

----------------------------------------

xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="com.myStuff" />
<context:annotation-config />

<bean id="MyDao" class="com.myStuff.impl.MyDaoImpl"
parent="daoTmpl" />

<bean id="MyFacade" class="com.myStuff.impl.MyFacadeImpl"/>

...

beans>

----------------------------------------

Once we’ve updated the “beans” definitions and added the <context:component-scan base-package="com.myStuff" /> and <context:annotation-config /> tags to the xml file, we can remove MyDao and MyFacade Spring beans from the applicationContext.xml and add the annotations.

So, what you’ll finally get is:


After we replaced the beans definitions with annotations
:

The POJO classes:

----------------------------------------

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

@Repository(value = "MyDao")
@Transactional
public class MyDaoImpl extends HibernateDaoSupport implements MyDao {

/* I had to add constructor in order to initialize
HibernateDaoSupport’s sessionFacade object.
*/
@Autowired
public MyDaoImpl(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}

@Override
public Serializable createORM(MyOrm orm) {
return getHibernateTemplate().save(orm);
}

}

----------------------------------------

@Service("MyFacade")
@Transactional(propagation = Propagation.REQUIRED)
public class MyFacadeImpl implements {

private MyDao myDao;

@Autowired
public void setMyDao(MyDao myDao) {
this.myDao = myDao;
}

@Override
public void someMethod() {

...

}

}

----------------------------------------

And the applicationContext.xml would be:

----------------------------------------

xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="com.myStuff" /> <context:annotation-config />

...

beans>

----------------------------------------

And that’s all. No more defining your custom Spring beans in XMLs.

Tuesday, October 27, 2009

How to start H2 database as a stand alone java process

In order to start H2 database server from a Java application, in a process other than the main process of your application (i.e. stand alone), you should use the java runtime API.

A code sample to do that:
-------------------------

Runtime rt = Runtime.getRuntime();
Process p = rt.exec("java -cp h2*.jar org.h2.tools.Server");


For the Spring users -
If you are using a Spring application with H2, you can configure spring to start your H2 server as described in the H2 documentation. Note that this will start the H2 server in the same process as you java application.
You can use java Runtime API in Spring as well. If you want the database to start before Spring/Hibernate are started you can use ServletContextListener to start the H2 server.


Saturday, June 6, 2009

Cannot Start Tomcat 6.0 - "SEVERE: Error getConfigured"

I was working on building my Java web application, based on Spring and Hibernate, and tried to load it in tomcat 6.0.18. I got the following uninformative error:

INFO: ExtensionValidator[/myApp]: Failure to find 3 required extension(s).
Jun 6, 2009 8:59:53 PM org.apache.catalina.core.StandardContext start
SEVERE: Error getConfigured
Jun 6, 2009 8:59:53 PM org.apache.catalina.core.StandardContext start


I searched the logs and couldn't find more information...not a very helpful error message.

So how to fix it? I found this link helpful - http://forum.springsource.org/showthread.php?t=28233
They suggested to remove some of the commons libs and this solved the problem for me.