Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kenneth A. Kousen - Making Java Groovy - 2014.pdf
Скачиваний:
50
Добавлен:
19.03.2016
Размер:
15.36 Mб
Скачать

Refreshable beans

175

testing. From Spring’s point of view, Groovy beans are just bytecodes by another name. As long as the groovy-all JAR file is in the classpath, Spring is quite happy to use beans written in Groovy.

Spring manages beans from Groovy as easily as it manages beans from Java. There are special capabilities that Spring offers beans from dynamic languages, though. I’ll illustrate them in the next sections, beginning with beans that can be modified in a running system.

7.2Refreshable beans

Since version 2.0, Spring has provided special capabilities for beans from dynamic languages like Groovy. One particularly interesting, if potentially dangerous, option is to deploy what are known as refreshable beans.

For refreshable beans, rather than compile classes as usual, you deploy the actual source code and tell Spring where to find it and how often to check to see if it has changed. Spring checks the source code at the end of each refresh interval, and if the file has been modified it reloads the bean. This gives you the opportunity to change deployed classes even while the system is still running.3

I’ll demonstrate a somewhat contrived but hopefully amusing example. In the previous section I presented an application for managing accounts. Let me now assume that the account manager, presumably some kind of bank, decides to get into the mortgage business. I now need a class representing a mortgage application, which a client would submit for approval. I’m also going to need a mortgage evaluator, which I’ll implement both in Java and in Groovy. The overall system is shown in figure 7.3.

To keep this example simple, the mortgage application class only has fields representing the loan amount, the interest rate, and the number of years desired, as shown in the next listing.

Mortgage

 

 

 

<<interface>>

 

 

 

 

application

 

 

 

Evaluator

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

JavaEvaluator

 

GroovyEvaluator

 

 

Modify source code.

 

 

(refreshable)

 

 

Spring loads new version.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 7.3 The GroovyEvaluator is a refreshable bean. The source code is deployed, and Spring checks it for changes after each refresh interval. If it has changed, Spring reloads the bean.

3Yes, that’s a scary notion to me, too. The Spider-Man corollary applies: With Great Power Comes Great Responsibility.

www.it-ebooks.info

176

CHAPTER 7 The Spring framework

Listing 7.8 A trivial mortgage application class in Groovy

class MortgageApplication { BigDecimal amount BigDecimal rate

int years

}

As before, Groovy is used just to reduce the amount of code and to make it easier to work with BigDecimal instances. An instance of this class is submitted to the bank, which runs it through a mortgage evaluator to decide whether or not to approve it. The following listing shows a Java interface representing the evaluator, which will be implemented in both Java and Groovy.

Listing 7.9 The Evaluator interface in Java

public interface Evaluator {

boolean approve(MortgageApplication application);

}

The interface contains only one method, approve, which takes a mortgage application as an argument and returns true if the application is approved and false otherwise.

Pretend now that it is currently the summer of 2008. The general public is blissfully unaware of terms like credit default swaps, and banks are eager to loan as much money as possible to as many people as possible. In other words, here’s a Java implementation of the Evaluator interface.

Listing 7.10 A Java evaluator, with a rather lenient loan policy

public class JavaEvaluator implements Evaluator {

public boolean approve(MortgageApplication application) { return true;

}

}

That’s a very forgiving loan policy, but if everyone else is doing it, what could go wrong? What went wrong, of course, is that in the late summer and early fall of 2008, Bear Stearns collapsed, Lehman Brothers went bankrupt, and the U.S. economy nearly collapsed. The bank needs to stop the bleeding as soon as possible. If the evaluator in place is the Java evaluator just shown, then the system has to be taken out of service in order to modify it. The fear is that if the system is taken offline, then customers might

worry that it will never come back again.4

There’s another possibility, however. Consider the Groovy version of the mortgage evaluator, whose behavior is equivalent to the Java version, as shown in the following listing.

4 That’s an It’s a Wonderful Life reference: “George, if you close those doors, you’ll never open them again!”

www.it-ebooks.info

Refreshable beans

177

Listing 7.11 A Groovy mortgage evaluator deployed as source code

class GroovyEvaluator implements Evaluator {

boolean approve(MortgageApplication application) { true }

}

Again, it simply returns true, just as the Java version did. Rather than compiling this class and deploying it as usual, however, this time I want to create a refreshable bean. To do so, I need to work with the lang namespace in the Spring configuration file (assuming I’m using XML; alternatives exist for Java configuration files). I also need to deploy the source code itself, rather than the compiled version of this file.

DEPLOYING SOURCE Note that for refreshable beans you deploy the source, not the compiled bean.

The next listing shows the bean configuration file with both evaluators. Note the addition of the lang namespace and the Groovy bean.

Listing 7.12 The bean configuration file with the refreshable Groovy evaluator bean

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

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd">

Namespace for dynamic languages

<bean id="javaEvaluator" class="mjg.spring.JavaEvaluator" />

<lang:groovy id="groovyEvaluator" script-source="file:resources/GroovyEvaluator.groovy" refresh-check-delay="1000" />

</beans>

Refreshable bean

Groovy provides a namespace for beans from dynamic languages, including Groovy, BeanShell, and JRuby. One of the elements declared in that namespace is <lang: groovy>, whose script-source attribute is used to point to the source code of a Groovy class. Note that unlike the Java evaluator bean in the same file, this attribute points to the actual source file, rather than the compiled bean. The other important attribute for the element is refresh-check-delay, which indicates the time period, in milliseconds, after which Spring will check to see if the source file has changed. Here the delay has been set to one second.

Now comes the fun part.5 The next listing shows a demo application that loads the Groovy evaluator bean and calls the approve method 10 times, sleeping for one second between each call.

5 Seriously. This is a fun demo to do in front of a live audience. Try it and see.

www.it-ebooks.info

178

CHAPTER 7 The Spring framework

 

 

 

 

 

 

 

 

Listing 7.13 A demo application that loads the Groovy bean and calls approve 10 times

 

public class Demo {

 

 

public static void main(String[] args) {

 

 

ApplicationContext ctx =

 

 

new FileSystemXmlApplicationContext(

 

 

"resources/applicationContext.xml");

 

 

Evaluator e = null;

Load

 

boolean ok;

 

refreshable

 

 

 

 

 

 

for (int i = 0; i < 10; i++) {

bean

 

 

 

e = (Evaluator) ctx.getBean("groovyEvaluator");

 

 

 

 

 

 

 

 

ok = e.approve(null);

 

 

Check

 

System.out.println(ok ? "approved" : "denied");

 

 

 

approval

try { Thread.sleep(1000);

} catch (InterruptedException ie) { ie.printStackTrace();

}

}

}

}

Gives time to change the implementation of approve

The idea is to start the demo running and then, while the iteration is going, edit the source code to change the return value of the approve method from true to false.6 The output of the program resembles

approved

 

 

approved

 

 

approved

 

 

approved

 

 

approved

 

Code

 

denied

 

 

changed

 

 

denied

 

here

denied

 

 

denied

 

 

denied

 

 

The source code is changed halfway through the loop to stop the bleeding. If Congress should then spring7 into action and award a massive government bailout, it can be changed back.8

The ability to change the implementation of a bean inside a running system is powerful, but obviously risky. Spring only makes it available to beans from dynamic languages like Groovy.

6Did you notice that the approve method was invoked with a null argument, acknowledging that the mortgage application doesn’t matter at all? That’s part of the gag, so be sure to chuckle when you do it.

7Ouch. Yes, a bad pun, but an irresistible one.

8Or not.

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]