天天看點

Spring’s so Groovy

Spring’s so Groovy

Spring 2.0 introduced comprehensive support to use dynamic languages. It supports three different scripting languages; JRuby , Groovy and BeanShell . The scripting language used in this article is Groovy; which I think was designed for Java developers. As Scott Davis says in his book, Groovy Recipes ” Groovy is Java at the end of the day”. “Spring Recipes - A Problem -Solution Approach ” written by Gary Mak has a complete chapter dedicated to Scripting in Spring . The author covers all the three dynamic languages supported by Spring; JRuby , Groovy and BeanShell .

There are times when in your application you have certain modules that require frequent changes, and based on these changes you need to change the business logic within your modules. If these modules were written in Java, you can imagine what needs to be done at this point; recompile, package, redeploy. This is where modules written in these dynamic languages come in handy, there is no need to recompile, or redeploy for these changes to take effect. In most cases, you want the Spring container to be able to detect these changes and also pick up the new state from the changed script source. Spring allows you to do this as well by setting one simple attribute.

Hello World Example: It is customary to start any tutorial by writing a simple HelloWorld program, right? We are going to use Groovy in this tutorial. This tutorial assumes you have some knowledge of Spring and Groovy. I used Eclipse IDE for this tutorial, and to work with Spring and Groovy in Eclipse, you need the following libraries in your build path.

Spring’s so Groovy

So, lets begin with the HelloWorld example here.

Step 1: Lets define an interface for our HelloWorld Service :

package com.springandgroovy;

public interface HelloWorldService {

	String sayHello();

}           

Step 2 : Implement the interface in Groovy.

Next, we implement this interface in Groovy by creating a simple script within the com.springandgroovy package as such:

import com.springandgroovy.HelloWorldService;

class HelloWorldServiceImpl implements HelloWorldService {

	String name

   String sayHello()
   {
   		"Hello $name. Welcome to Scripting in Groovy."
   }
}           

Step 3: Make changes to Spring’s configuration file.

Here comes the Spring’s bean configuration file, in which you have to include the lang schema to use the custom dynamic language tags.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/lang
        http://www.springframework.org/schema/lang/spring-lang-2.5.xsd">           

the bean definition for the Groovy backed HelloWorldService looks like this:

<lang:groovy id="helloWorldService"
			 script-source="classpath:com/springandgroovy/HelloWorldServiceImpl.groovy">
			 <lang:property name="name" value="meera"/>
</lang:groovy>           

That’s all you need to use Groovy backed beans in Spring. So, how do we know this works, right? Lets write a simple Main class and test it within our IDE:

Step 4: Run the HelloWorldService.

package com.springandgroovy;

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

public class Main {

   public static void main(String[] args) throws Exception {

     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
     HelloWorldService service = (HelloWorldService) context.getBean("helloWorldService");

     System.out.println(service.sayHello());

    }

}           

And you should be able to see output in the console as such:

Spring’s so Groovy

Step 5: Refreshable Beans.

As I mentioned earlier also, to turn on this feature we have to specify one simple attribute refresh-check-delay on the element of our bean definition as such:

<lang:groovy id="helloWorldService"
			 script-source="classpath:com/springandgroovy/HelloWorldServiceImpl.groovy"
			 refresh-check-delay="5000">
			 <lang:property name="name" value="meera"/>
</lang:groovy>           

Again, how do we know this works when we make changes to our Groovy Script? A small change in our Main class and, and you should be set to test that this works as well:

package com.springandgroovy;

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

public class Main {

    public static void main(String[] args) throws Exception {

    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    HelloWorldService service = (HelloWorldService) context.getBean("helloWorldService");
    System.in.read();
    System.out.println(service.sayHello());

    }

}           

Now, run the Main class in your IDE, it halts because of the System.in.read line, make a few changes within your script, save it, hit enter in your console window in your IDE. The Spring container read our new changes and prints the results within the console window.

The script change can be as simple as adding a few special characters as such within the sayHello() method:

String sayHello()
   {
   		"Hello $name!!!. Welcome to Scripting in Groovy."
   }           

And the console window reflects these changes:

Spring’s so Groovy

Step 6: Inline Scripts

Spring also allows you to embed scripts directly within the Spring bean definitions inside your Spring configuration file. I am no fan of doing this, because it has a drawback; the refresh attribute is not applicable for inline scripts. Lets take a look at this in case you need to use this feature:

Copy the script we wrote in Step 2 and paste it within the lang:inline-script element as such:

<lang:groovy id="helloWorldService">
        <lang:inline-script>
        <![CDATA[
 import com.springandgroovy.HelloWorldService;
  class HelloWorldServiceImpl implements HelloWorldService {

	String name

   String sayHello()
   {
   		"Hello $name. Welcome to Scripting in Groovy"
   }
}
        ]]>
        </lang:inline-script>
        <lang:property name="name" value="meera" />
    </lang:groovy>
           

Run the Main class and you should see the same output in your console window.

Spring’s so Groovy

In this tutorial we learned how to use Groovy with Spring using an external script source file, how to refresh changes when a script source file is changed, and finally saw an inline script which was embedded within the Spring configuration file.

Additional Resources:

1. JRuby

2. Groovy

3. BeanShell

4. Spring

5. Spring Recipes