Groovy

Spring Dynamic Language Support with Groovy

Groovy is a dynamic and object-oriented programming language running on JVM. It uses a syntax like Java, can be embedded in Java and is compiled to byte-code. Java code can be called from Groovy, and vice versa. Some of Groovy features are Meta and Functional programming, Dynamic typing (with the def keyword), Closures, GroovyBeans, Groovlets, integration with Bean Scripting Framework(BSF), Generics, Anotation and Collection Support.
 
 
 
 
 
 
This article explains fundamental Spring Dynamic Language Support for Groovy via the following ways :

  1. By using Java syntax and Spring Stereotype,
  2. By using Groovy syntax and Spring Stereotype,
  3. By using inline-script feature,
  4. By using Spring Groovy language support(lang:groovy).

Used Technologies :

  • JDK 1.7.0_09
  • Spring 3.2.0
  • Groovy 2.0.4
  • Maven 3.0.4

STEP 1 : CREATE MAVEN PROJECT

A maven project is created as below. (It can be created by using Maven or IDE Plug-in).

STEP 2 : LIBRARIES

Firstly, dependencies are added to Maven’ s pom.xml.

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>3.2.0.RELEASE</spring.version>
	</properties>	

	<!-- Spring 3 dependencies -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.version}</version>
	</dependency>

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>

	<dependency>
		<groupId>org.codehaus.groovy</groupId>
		<artifactId>groovy-all</artifactId>
		<version>2.0.4</version>
	</dependency>

maven-compiler-plugin(Maven Plugin) is used to compile the project with JDK 1.7

	<plugin>
		<artifactId>maven-compiler-plugin</artifactId>
		<version>2.3.2</version>
		<configuration>
			<compilerId>groovy-eclipse-compiler</compilerId>
			<verbose>true</verbose>
			<source>1.7</source>
			<target>1.7</target>
			<encoding>${project.build.sourceEncoding}</encoding>
		</configuration>
		<dependencies>
			<dependency>
				<groupId>org.codehaus.groovy</groupId>
				<artifactId>groovy-eclipse-compiler</artifactId>
				<version>2.6.0-01</version>
			</dependency>
		</dependencies>
	</plugin>

maven-shade-plugin(Maven Plugin) can be used to create runnable-jar

	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-shade-plugin</artifactId>
		<version>2.0</version>

		<executions>
			<execution>
				<phase>package</phase>
				<goals>
					<goal>shade</goal>
				</goals>
				<configuration>
					<createDependencyReducedPom>false</createDependencyReducedPom>
					<configuration>
						<source>1.7</source>
						<target>1.7</target>
					</configuration>
					<transformers>
						<transformer
							implementation='org.apache.maven.plugins.shade.resource.ManifestResourceTransformer'>
							<mainClass>com.onlinetechvision.exe.Application</mainClass>
						</transformer>
						<transformer
							implementation='org.apache.maven.plugins.shade.resource.AppendingTransformer'>
							<resource>META-INF/spring.handlers</resource>
						</transformer>
						<transformer
							implementation='org.apache.maven.plugins.shade.resource.AppendingTransformer'>
							<resource>META-INF/spring.schemas</resource>
						</transformer>
					</transformers>
				</configuration>
			</execution>
		</executions>
	</plugin>

STEP 3 : CREATE Employee CLASS

Employee Bean is created.

package com.onlinetechvision.employee;

/**
 * Employee Bean
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
public class Employee {

	private String id;
	private String name;
	private String surname;

	public Employee(String id, String name, String surname) {
		this.id = id;
		this.name = name;
		this.surname = surname;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}	

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((surname == null) ? 0 : surname.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Employee other = (Employee) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (surname == null) {
			if (other.surname != null)
				return false;
		} else if (!surname.equals(other.surname))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return 'Employee [id=' + id
				            + ', name=' + name
							+ ', surname=' + surname + ']';
	}	

}

METHOD 1 : USING JAVA SYNTAX

STEP 4 : CREATE IGroovyEmployeeCacheService INTERFACE

IGroovyEmployeeCacheService Interface is created to expose Groovy Cache functionality.

package com.onlinetechvision.groovy.srv

import com.onlinetechvision.employee.Employee

/**
 * IGroovyEmployeeCacheService Interface exposes cache functionality.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
interface IGroovyEmployeeCacheService {

	/**
	 * Adds employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	void addToEmployeeCache(Employee employee);

	/**
	 * Gets employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	Employee getFromEmployeeCache(String id);

	/**
	 * Removes employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	void removeFromEmployeeCache(Employee employee);

}

STEP 5 : CREATE GroovyEmployeeCacheService IMPL

GroovyEmployeeCacheService Class is created by implementing IGroovyEmployeeCacheService Interface.

package com.onlinetechvision.groovy.srv

import com.onlinetechvision.employee.Employee;
import org.springframework.stereotype.Service;

/**
 * GroovyEmployeeCacheService Class is implementation of IGroovyEmployeeCacheService Interface.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
@Service
class GroovyEmployeeCacheService implements IGroovyEmployeeCacheService  {

	private Map<String, Employee> cache = new HashMap();

	/**
	 * Adds employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	public void addToEmployeeCache(Employee employee) {
		getCache().put(employee.getId(), employee);
		println print(employee, 'added to cache...');
	}

	/**
	 * Gets employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	public Employee getFromEmployeeCache(String id) {
		Employee employee = getCache().get(id);
		println print(employee, 'gotten from cache...');
		return employee;
	}

	/**
	 * Removes employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	public void removeFromEmployeeCache(Employee employee) {
		getCache().remove(employee.getId());
		println print(employee, 'removed from cache...');
		println 'Groovy Cache Entries :' + getCache();
	}

	public Map<String, Employee> getCache() {
		return cache;
	}

	public void setCache(Map<String, Employee> map) {
		cache = map;
	}

	/**
	 * Prints operation information
	 *
	 * @param Employee employee
	 * @param String description
	 *
	 */
	private String print(Employee employee, String desc) {
		StringBuilder strBldr = new StringBuilder();
		strBldr.append(employee)
		strBldr.append(' ');
		strBldr.append(desc);

		return strBldr.toString();
	}
}

STEP 6 : CREATE IEmployeeService INTERFACE

IUserService Interface is created for Spring service layer and shows how to integrate Spring and Groovy Service layers.

package com.onlinetechvision.spring.srv;

import com.onlinetechvision.employee.Employee;

/**
 * IEmployeeService Interface is created to represent Spring Service layer.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
public interface IEmployeeService {

	/**
	 * Adds Employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	void addToGroovyEmployeeCache(Employee employee);

	/**
	 * Gets Employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	Employee getFromGroovyEmployeeCache(String id);

	/**
	 * Removes Employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	void removeFromGroovyEmployeeCache(Employee employee);	

}

STEP 7 : CREATE EmployeeService IMPL

EmployeeService Class is created by implementing IUserService Interface.

package com.onlinetechvision.spring.srv;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.onlinetechvision.employee.Employee;
import com.onlinetechvision.groovy.srv.IGroovyEmployeeCacheService;

/**
 * EmployeeService Class is implementation of IEmployeeService interface.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
@Service
public class EmployeeService implements IEmployeeService {

	@Autowired
	private IGroovyEmployeeCacheService groovyEmployeeCacheService ;

	/**
	 * Adds Employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	public void addToGroovyEmployeeCache(Employee employee) {
		getGroovyEmployeeCacheService().addToEmployeeCache(employee);
	}

	/**
	 * Gets Employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	public Employee getFromGroovyEmployeeCache(String id) {
		return getGroovyEmployeeCacheService().getFromEmployeeCache(id);
	}	

	/**
	 * Removes Employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	public void removeFromGroovyEmployeeCache(Employee employee) {
		getGroovyEmployeeCacheService().removeFromEmployeeCache(employee);
	}

	public IGroovyEmployeeCacheService getGroovyEmployeeCacheService() {
		return groovyEmployeeCacheService;
	}

	public void setGroovyEmployeeCacheService(IGroovyEmployeeCacheService groovyEmployeeCacheService) {
		this.groovyEmployeeCacheService = groovyEmployeeCacheService;
	}	

}

STEP 8 : CREATE applicationContext.xml

Spring Configuration file, applicationContext.xml, is created.

<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-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd'>

	<context:component-scan base-package='com.onlinetechvision.spring.srv, com.onlinetechvision.groovy.srv'/>

</beans>

STEP 9 : CREATE Application CLASS

Application Class is created to run the application.

package com.onlinetechvision.exe;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.onlinetechvision.spring.srv.EmployeeService;
import com.onlinetechvision.spring.srv.IEmployeeService;
import com.onlinetechvision.employee.Employee;

/**
 * Application Class starts the application
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
public class Application
{
	/**
     * Starts the application
     *
     * @param  String[] args
     *
     */
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext('applicationContext.xml');

		IEmployeeService employeeService = (IEmployeeService) context.getBean(EmployeeService.class);

		Employee firstEmployee = new Employee('1', 'Jake', 'Gyllenhaal');
		Employee secondEmployee = new Employee('2', 'Woody', 'Harrelson');

		employeeService.addToGroovyEmployeeCache(firstEmployee);
		employeeService.getFromGroovyEmployeeCache(firstEmployee.getId());
		employeeService.removeFromGroovyEmployeeCache(firstEmployee);

		employeeService.addToGroovyEmployeeCache(secondEmployee);
		employeeService.getFromGroovyEmployeeCache(secondEmployee.getId());
	}

}

STEP 10 : BUILD PROJECT

After OTV_Spring_Groovy Project is build, OTV_Spring_Groovy-0.0.1-SNAPSHOT.jar is created.

STEP 11 : RUN PROJECT

After created OTV_Spring_Groovy-0.0.1-SNAPSHOT.jar file is run, output logs are shown as the followwing :

Employee [id=1, name=Jake, surname=Gyllenhaal] added to cache...
Employee [id=1, name=Jake, surname=Gyllenhaal] gotten from cache...
Employee [id=1, name=Jake, surname=Gyllenhaal] removed from cache...
Groovy Cache Entries :[:]

Employee [id=2, name=Woody, surname=Harrelson] added to cache...
Employee [id=2, name=Woody, surname=Harrelson] gotten from cache...

So far, first way has been explained. Let us take a look to the other ways :

METHOD 2 : USING GROOVY SYNTAX

IGroovyEmployeeCacheService Interface and GroovyEmployeeCacheService Impl can be also designed by using Groovy syntax as the following :

STEP 12.1 : CREATE IGroovyEmployeeCacheService INTERFACE

IGroovyEmployeeCacheService Interface is created by using Groovy syntax.

package com.onlinetechvision.groovy.srv

import com.onlinetechvision.employee.Employee

/**
 * IGroovyEmployeeCacheService Interface exposes cache functionality.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
interface IGroovyEmployeeCacheService {

	/**
	 * Adds employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	def addToEmployeeCache(Employee employee);

	/**
	 * Gets employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	def getFromEmployeeCache(String id);

	/**
	 * Removes employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	def removeFromEmployeeCache(Employee employee);

}

STEP 12.2 : CREATE GroovyEmployeeCacheService IMPL

GroovyEmployeeCacheService Class is created by using Groovy syntax.

package com.onlinetechvision.groovy.srv

import com.onlinetechvision.employee.Employee;
import org.springframework.stereotype.Service;

/**
 * GroovyEmployeeCacheService Class is implementation of IGroovyEmployeeCacheService Interface.
 *
 * @author onlinetechvision.com
 * @since 24 Dec 2012
 * @version 1.0.0
 *
 */
@Service
class GroovyEmployeeCacheService implements IGroovyEmployeeCacheService  {

	def cache = new HashMap();

	/**
	 * Adds employee entry to cache
	 *
	 * @param Employee employee
	 *
	 */
	def addToEmployeeCache(Employee employee) {
		getCache().put(employee.getId(), employee);
		println print(employee, 'added to cache...');
	}

	/**
	 * Gets employee entry from cache
	 *
	 * @param String id
	 * @return Employee employee
	 */
	def getFromEmployeeCache(String id) {
		Employee employee = getCache().get(id);
		println print(employee, 'gotten from cache...');
		return employee;
	}

	/**
	 * Removes employee entry from cache
	 *
	 * @param Employee employee
	 *
	 */
	def removeFromEmployeeCache(Employee employee) {
		getCache().remove(employee.getId());
		println print(employee, 'removed from cache...');
		println 'Groovy Cache Entries :' + getCache();
	}

	def getCache() {
		return cache;
	}

	def setCache(Map<String, Employee> map) {
		cache = map;
	}

	/**
	 * Prints operation information
	 *
	 * @param Employee employee
	 * @param String description
	 *
	 */
	def print(Employee employee, String desc) {
		StringBuilder strBldr = new StringBuilder();
		strBldr.append(employee)
		strBldr.append(' ');
		strBldr.append(desc);
	}
}

METHOD 3 : USING INLINE-SCRIPT FEATURE

GroovyEmployeeCacheService Impl can be also defined by using inline-script feature as the following :

STEP 13.1 : DEFINE GroovyEmployeeCacheService IMPL via applicationContext.xml

GroovyEmployeeCacheService Impl Class can be defined in applicationContext.xml.

<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'
	xmlns:lang='http://www.springframework.org/schema/lang'
	xsi:schemaLocation='http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/lang

http://www.springframework.org/schema/lang/spring-lang-3.0.xsd'>

	<context:component-scan base-package='com.onlinetechvision.spring.srv'/>

	<lang:groovy id='groovyEmployeeCacheService'>
	    <lang:inline-script>
			package com.onlinetechvision.groovy.srv

			import com.onlinetechvision.employee.Employee;
			import org.springframework.stereotype.Service;

			class GroovyEmployeeCacheService implements IGroovyEmployeeCacheService {

				def cache = new HashMap();

				def addToEmployeeCache(Employee employee) {
					getCache().put(employee.getId(), employee);
					println print(employee, 'added to cache...');
				}

				def getFromEmployeeCache(String id) {
					Employee employee = getCache().get(id);
					println print(employee, 'gotten from cache...');
					return employee;
				}

				def removeFromEmployeeCache(Employee employee) {
					getCache().remove(employee.getId());
					println print(employee, 'removed from cache...');
					println 'Groovy Cache Entities :' + getCache();
				}

				def getCache() {
					return cache;
				}

				def setCache(Map map) {
					cache = map;
				}

				def print(Employee employee, String desc) {
					StringBuilder strBldr = new StringBuilder();
					strBldr.append(employee)
					strBldr.append(' ');
					strBldr.append(desc);
				}
			}
	    </lang:inline-script>
	</lang:groovy>

</beans>

METHOD 4 : USING SPRING GROOVY LANGUAGE SUPPORT

GroovyEmployeeCacheService Impl can be also defined to Spring application-context without using stereotype(@Service) as the following :

STEP 14.1 : DEFINE GroovyEmployeeCacheService IMPL via applicationContext.xml

GroovyEmployeeCacheService Impl Class can be defined in applicationContext.xml.

<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'
	xmlns:lang='http://www.springframework.org/schema/lang'
	xsi:schemaLocation='http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/lang

http://www.springframework.org/schema/lang/spring-lang-3.0.xsd'>

	<context:component-scan base-package='com.onlinetechvision.spring.srv'/>

	<lang:groovy id='groovyEmployeeCacheService' script-source='classpath:com/onlinetechvision/groovy/srv/GroovyEmployeeCacheService.groovy'/>

</beans>

STEP 15 : DOWNLOAD

https://github.com/erenavsarogullari/OTV_Spring_Groovy

RESOURCES :

Groovy User Guide
Spring Dynamic Language Support
 

Reference: Spring Dynamic Language Support with Groovy from our JCG partner Eren Avsarogullari at the Online Technology Vision blog.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button