Groovier Spring, Part 2: Change application behavior at run time

Adding dynamically refreshable beans to Spring applications with Groovy

The Spring Framework provides a solid foundation for Web and enterprise applications. Spring's support for dynamic languages like Groovy adds capabilities that can make your application architecture more flexible and dynamic. In the second and final installment of the Groovier Spring series, you'll learn how to change the behavior of Spring applications at run time using dynamically refreshable beans.

Scott Leberknight (scott.leberknight@nearinfinity.com), Chief Architect, Near Infinity Corporation

Scott LeberknightScott Leberknight has been developing software professionally for 14 years. He is Chief Architect at Near Infinity Corporation and speaks frequently at the No Fluff Just Stuff conference series and other developer conferences.



06 January 2009

Also available in Chinese Russian Japanese

In Part 1 of this two-article series, you saw how to make Spring applications more flexible using Groovy beans. Spring's Groovy support allows you to use compiled or scripted Groovy language beans and to configure them in several different ways including the lang XML schema and the Grails Bean Builder. When you integrate Groovy scripts into your application, you can include additional logic in the bean-creation process (for example, to determine which implementation strategy to use when creating a bean). You can also use separate scripted Groovy beans to provide additional deployment and packaging flexibility.

Probably the most interesting and powerful feature of Spring's dynamic-language support is the ability to monitor and detect changes to dynamic-language scripts while your application is running and automatically reload the changed beans in the Spring application context. The potential use cases for automatically refreshing Spring beans in a running application are vast. A few examples include:

  • PDF generation (bills, invoices, sales reports, investment reports, receipts, schedules, and so on)
  • E-mail templates
  • Report generation
  • Externalized business logic, domain-specific languages (DSLs), and rules engines
  • System administrative tasks
  • Changing logging levels and run-time debugging

I'm sure you can think of even more potential uses. This article shows you how to add bean refresh to your Spring applications and explores how it works. The complete source code (see Download) for all of the article's examples is available for download.

Refreshable Groovy beans

In Part 1, you defined the PdfGenerator interface and implemented it as a Groovy class (GroovyPdfGenerator) in the GroovyPdfGenerator.groovy script file located in the application CLASSPATH. You configured the Groovy-based pdfGenerator bean by specifying the location where the Groovy script is located. Listing 1 shows the interface, implementation, and configuration using the lang XML schema:

Listing 1. PdfGenerator interface, implementation, and configuration
// PdfGenerator.java
public interface PdfGenerator {
    byte[] pdfFor(Invoice invoice);
}

// GroovyPdfGenerator.groovy
class GroovyPdfGenerator implements PdfGenerator {

    String companyName

    public byte[] pdfFor(Invoice invoice) {
        ...
    }

}

// applicationContext.xml
<lang:groovy id="pdfGenerator"
             script-source="classpath:groovierspring/GroovyPdfGenerator.groovy">
    <lang:property name="companyName" value="Groovy Bookstore"/>
</lang:groovy>

So far, so good. You have a bean named pdfGenerator implemented in Groovy that resides in the application CLASSPATH. When the Spring application context is created, Spring reads the script, compiles it into a Java class, and instantiates a GroovyPdfGenerator in the application context. Any other classes that depend on pdfGenerator can simply declare it as a dependency, and Spring wires them together as usual.

How Spring detects script changes

Under the covers, Spring uses a Spring AOP (see Resources) RefreshableScriptTargetSource to intercept calls to the target object (the pdfGenerator bean), perform the reload check, and obtain a newer version of a bean. Basically, beans that depend on refreshable beans have a reference to an AOP proxy rather than to the beans themselves.

Here is where things get really interesting. Suppose you make frequent changes to the PDF-generation code, and you'd like it if you could make changes while your application is running and have them take effect immediately. Spring makes adding this capability trivial. All you need to do is add the refresh-check-delay attribute to the <lang:groovy> element that defines your bean. This attribute defines the number of milliseconds after which Spring checks for changes to the underlying Groovy script. If a change to the script is detected (for example, the timestamp on the .groovy script has changed since last check), then Spring reads the script, compiles it, and replaces the old pdfGenerator bean with the new one. It does this without any of the beans that use pdfGenerator knowing anything about the change.

Listing 2 shows the pdfGenerator bean configured with a refresh-check delay of 10 seconds (10,000 milliseconds). After adding refresh-check-delay, Spring configures the bean for automatic refresh when the underlying GroovyPdfGenerator.groovy script file changes.

Listing 2. Adding refresh-check-delay to scripted bean definition
<lang:groovy id="pdfGenerator"
             script-source="classpath:groovierspring/GroovyPdfGenerator.groovy"
             refresh-check-delay="10000">
    <lang:property name="companyName" value="Refreshable Groovy Bookstore"/>
</lang:groovy>

Now, if a change is made to the GroovyPdfGenerator.groovy script while the application is running, Spring detects the change and reloads the pdfGenerator bean at run time without requiring a restart. Note that the refresh check occurs only after the delay period has elapsed and a method is called on the refreshable bean. For example, suppose the refresh-check delay is 10 seconds for the pdfGenerator bean, but no method is invoked on the bean for 50 seconds. In that situation, Spring checks whether a refresh is required after 50 seconds, not every 10 seconds. To state it another way, Spring is not actively polling the script for changes; instead, it determines the time elapsed since the last method invocation and then calculates whether that time exceeds the refresh check delay. Only if the elapsed time exceeds the refresh-check delay does Spring check if the script has changed and thereby determine whether a refresh is needed. On the other hand, suppose the pdfGenerator bean is under heavy load and its methods are being invoked multiple times per second. With a 10-second refresh-check-delay, the bean can't be reloaded any faster than once every 10 seconds, regardless of the number of times it is used. So you don't need to worry about whether Spring is expending system resources actively polling Groovy scripts; it isn't.

If you have more than one scripted Groovy bean in your Spring application and you want to set a default value for the refresh-check delay for all of them, you can easily do that using the <lang:defaults> element, as shown in Listing 3:

Listing 3. Setting a default refresh-check delay
<lang:defaults refresh-check-delay="20000"/>

Using <lang:defaults> as shown in Listing 3, all scripted dynamic language beans (those written in Groovy, JRuby, BeanShell, and so on) have a 20-second refresh-check delay. You can override the default for individual beans simply by adding a refresh-check-delay attribute to each bean that should have a different value from the default. You can even turn the automatic refresh behavior for individual scripted beans off by setting refresh-check-delay to a negative value, as shown in Listing 4:

Listing 4. Overriding the default refresh-check delay
<lang:defaults refresh-check-delay="20000"/>

<lang:groovy id="pdfGenerator"
             script-source="classpath:groovierspring/GroovyPdfGenerator.groovy"
             refresh-check-delay="60000">
    <lang:property name="companyName" value="Refreshable Groovy Bookstore"/>
</lang:groovy>

<lang:groovy id="invoiceEmailer"
             script-source="classpath:groovierspring/GroovyInvoiceEmailer.groovy"
             refresh-check-delay="-1"/>

In Listing 4, you can see that the default refresh check delay is 20 seconds. However, I've configured the pdfGenerator bean refresh-check delay as 60 seconds and turned off the refresh check entirely on the invoiceEmailer bean.

Configuring refreshable Groovy beans using the Grails Bean Builder

In Part 1, you saw how the Grails Bean Builder (see Resources) can be used to define Spring beans programmatically. If you are using the Bean Builder, you can add automatic refresh to your beans relatively easily — though in this case more of Spring's internals are exposed because Bean Builder has no equivalent to the <lang:groovy> syntactic sugar. Listing 5 shows how to add a default refresh check to all scripted beans and how to set a refresh delay on an individual bean:

Listing 5. Configuring refreshable Groovy beans using the Grails Bean Builder
def builder = new grails.spring.BeanBuilder()
builder.beans {
    scriptFactoryPostProcessor(ScriptFactoryPostProcessor) {
        defaultRefreshCheckDelay = 20000
    }
    pdfGenerator(GroovyScriptFactory,
                 'classpath:groovierspring/GroovyPdfGenerator.groovy') { bean ->
        companyName = 'Refreshable Bean Builder Bookstore'
        bean.beanDefinition.setAttribute(
            ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, 60000)
    }
}

The Bean Builder configuration in Listing 5 is logically equivalent to the configuration of the pdfGenerator bean in Listing 4. You set a default refresh-check delay on all scripted beans using the defaultRefreshCheckDelay property of the ScriptFactoryPostProcessor bean. To set a refresh-check delay on an individual bean when using Bean Builder, you must set an attribute on the underlying Spring bean definition. When you use the <lang:groovy> XML-based configuration, Spring takes care of the underlying details for you, whereas with Bean Builder you need to get your hands dirty and do it yourself. Note that you also need to declare a bean argument to the closure on the pdfGenerator bean in order to set the attribute on the bean definition.


Customizing Groovy beans

You've now seen how to make Groovy beans automatically update at run time using the refreshable beans feature and make your applications much more dynamic at run time. Spring's Groovy support provides an additional way to make Groovy beans even more flexible: customization. Customization is a way to inject custom logic into the Groovy bean-creation process. The GroovyObjectCustomizer interface (shown in Listing 6) allows you to perform custom logic on a newly created GroovyObject:

Listing 6. GroovyObjectCustomizer interface
public interface GroovyObjectCustomizer {
    void customize(GroovyObject goo);
}

A GroovyObjectCustomizer is a callback that Spring invokes after creating a Groovy bean. You can apply additional logic to a Groovy bean or perform metaprogramming magic, such as replacing the object's metaclass (see Resources). Listing 7 shows an implementation that writes how long it took to execute a method on a Groovy bean:

Listing 7. Performance logging GroovyObjectCustomizer
public class PerformanceLoggingCustomizer implements GroovyObjectCustomizer {

    public void customize(GroovyObject goo) {
        DelegatingMetaClass metaClass = new DelegatingMetaClass(goo.getMetaClass()) {
            @Override
            public Object invokeMethod(Object object, String method, Object[] args) {
                long start = System.currentTimeMillis();
                Object result = super.invokeMethod(object, method, args);
                long elapsed = System.currentTimeMillis() - start;
                System.out.printf("%s took %d millis on %s\n", method, elapsed, object);
                return result;
            }
        };
        metaClass.initialize();
        goo.setMetaClass(metaClass);
    }
}

The PerformanceLoggingCustomizer in Listing 7 replaces the GroovyObject's metaclass and overrides invokeMethod in order to add the performance-timing logic. Next you need to configure your customizer so it gets applied to one or more Groovy beans. Listing 8 shows use of the customizer-ref attribute in <lang:groovy> to add a customizer to an existing Groovy bean:

Listing 8. Configuring a Groovy object customizer
<bean id="performanceLoggingCustomizer"
      class="groovierspring.PerformanceLoggingCustomizer"/>

<lang:groovy id="pdfGenerator"
    refresh-check-delay="60000"
    script-source="classpath:groovierspring/GroovyPdfGenerator.groovy"
    customizer-ref="performanceLoggingCustomizer">
    <lang:property name="companyName" value="Customized Groovy Bookstore"/>
</lang:groovy>

Now when any method in the GroovyPdfGenerator is invoked, you'll see output like the following on standard output. (If you're thinking it would have been better to use a logging framework, you're probably right!)

pdfFor took 18 millis on groovierspring.GroovyPdfGenerator@f491a6

Adding customization to Groovy beans is pretty simple; the hard part is implementing the actual customization logic — that is, what you want to do to Groovy beans when they are created. You saw configuration using <lang:groovy> and its customizer-ref attribute. If you prefer using the Grails Bean Builder to build your Spring beans, it is simple to do. Listing 9 shows how to add the peformanceLoggingCustomizer bean:

Listing 9. Adding a Groovy object customizer using the Grails Bean Builder
builder.beans {
    performanceLoggingCustomizer(PerformanceLoggingCustomizer)
    scriptFactoryPostProcessor(ScriptFactoryPostProcessor) {
        defaultRefreshCheckDelay = 20000
    }
    pdfGenerator(GroovyScriptFactory,
                 'classpath:groovierspring/GroovyPdfGenerator.groovy',
                 performanceLoggingCustomizer) { bean ->
        companyName = 'Refreshable Bean Builder Bookstore'
        bean.beanDefinition.setAttribute(
            ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, 60000)
    }
}

Groovier databases

Out of the JAR, Spring provides support for inline scripts and scripts loaded via the Spring Resource abstraction (see Resources). You saw inline scripts and Resource-based scripts — specifically CLASSPATH resources — in Part 1. You've just added more dynamic behavior using refreshable beans. Spring's ability to load, compile, and refresh dynamic language beans rests on the ScriptSource interface, shown in Listing 10 (Javadocs omitted):

Listing 10. ScriptSource interface
public interface ScriptSource {

    String getScriptAsString() throws IOException;

    boolean isModified();

    String suggestedClassName();
}

ScriptSource defines three methods: one to obtain the script source code, one to determine if the script has been modified, and one that returns a suggested class name for the script. Spring provides two implementations of this interface: StaticScriptSource and ResourceScriptSource. You use StaticScriptSource when defining scripts in your Spring configuration file. ResourceScriptSource is used to load scripts from any Resource (for example, from scripts located in files, on the CLASSPATH, or from URLs).

Toward a pluggable script-source locator

When I first implemented the capability to store Groovy scripts in a database, I thought perhaps this mechanism should be pluggable so that users can plug in different ScriptSource implementations and script-locator strategies. I consulted Keith Donald of SpringSource about this, and he agreed and asked me to submit a new feature request to Spring. As a result, in a future version of Spring (currently scheduled for 3.1RC1), the script-source locator mechanism will become pluggable (see Resources).

Static and Resource-based scripts provide a wide range of places to define scripts, but you might want to use a database as the script location, for several good reasons. For example, many organizations do not allow file-system access to production machines, or they might require deployment as a WAR or EAR file. In addition, databases are transactional resources that most organizations already use and are familiar with. Databases also provide one relatively easy means to centralize data access and security without needing to know specifics about file systems, servers, and so on. Finally, storing scripts in a database means you could update the scripts from an application by allowing users to edit the scripts. (Of course, when you store active code in a database, it is important to consider the potential security implications and secure your application appropriately.)

Suppose you want to store your Groovy scripts in a relational database. As of Spring 2.5, you can create new types of scripts, but you must create your own ScriptSource and extend some of the Spring classes. Specifically, you need to define your own ScriptSource implementation and modify Spring's ScriptFactoryPostProcessor so it knows how to work with your new type of ScriptSource.

Listing 11 implements a DatabaseScriptSource that uses Spring JDBC to load scripts from a relational database:

Listing 11. DatabaseScriptSource implementation
public class DatabaseScriptSource implements ScriptSource {

    private final String scriptName;
    private final JdbcTemplate jdbcTemplate;
    private Timestamp lastKnownUpdate;

    private final Object lastModifiedMonitor = new Object();

    public DatabaseScriptSource(String scriptName, DataSource dataSource) {
        this.scriptName = scriptName;
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public String getScriptAsString() throws IOException {
        synchronized (this.lastModifiedMonitor) {
            this.lastKnownUpdate = retrieveLastModifiedTime();
        }
        return (String) jdbcTemplate.queryForObject(
                "select script_source from groovy_scripts where script_name = ?",
                new Object[]{ this.scriptName }, String.class);
    }

    public boolean isModified() {
        synchronized (this.lastModifiedMonitor) {
            Timestamp lastUpdated = retrieveLastModifiedTime();
            return lastUpdated.after(this.lastKnownUpdate);
        }
    }

    public String suggestedClassName() {
        return StringUtils.stripFilenameExtension(this.scriptName);
    }

    private Timestamp retrieveLastModifiedTime() {
        return (Timestamp) this.jdbcTemplate.queryForObject(
                "select last_updated from groovy_scripts where script_name = ?",
                new Object[]{ this.scriptName }, Timestamp.class);
    }
}

DatabaseScriptSource in Listing 11 is fairly straightforward, though you could make it more generic in terms of the database table structure it expects. It assumes a table named groovy_scripts having columns script_name, script_source, and last_updated. It supports loading scripts from the groovy_scripts table and checking for modifications.

Now, you need to teach Spring to recognize the DatabaseScriptSource. To do this, you must extend ScriptFactoryPostProcessor and override the convertToScriptSource method, which is responsible for converting a script-source locator (for example, classpath:groovierspring/GroovyPdfGenerator.groovy) into a ScriptSource. The default implementation in ScriptFactoryPostProcessor is shown in Listing 12:

Listing 12. ScriptFactoryPostProcessor's convertToScriptSource method
protected ScriptSource convertToScriptSource(
        String beanName, String scriptSourceLocator, ResourceLoader resourceLoader) {

    if (scriptSourceLocator.startsWith(INLINE_SCRIPT_PREFIX)) {
        return new StaticScriptSource(
                scriptSourceLocator.substring(INLINE_SCRIPT_PREFIX.length()), beanName);
    }
    else {
        return new ResourceScriptSource(resourceLoader.getResource(scriptSourceLocator));
    }
}

As you can see, the default implementation handles only inline and resource-based scripts. You can create a new subclass of ScriptFactoryPostProcessor and override convertToScriptSource to load scripts from your database also, using the DatabaseScriptSource, as shown in Listing 13:

Listing 13. CustomScriptFactoryPostProcessor implementation
public class CustomScriptFactoryPostProcessor extends ScriptFactoryPostProcessor {

    public static final String DATABASE_SCRIPT_PREFIX = "database:";

    private DataSource dataSource;

    @Required
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    protected ScriptSource convertToScriptSource(String beanName,
                                                 String scriptSourceLocator,
                                                 ResourceLoader resourceLoader) {
        if (scriptSourceLocator.startsWith(INLINE_SCRIPT_PREFIX)) {
            return new StaticScriptSource(
                scriptSourceLocator.substring(INLINE_SCRIPT_PREFIX.length()), beanName);
        }
        else if (scriptSourceLocator.startsWith(DATABASE_SCRIPT_PREFIX)) {
            return new DatabaseScriptSource(
                scriptSourceLocator.substring(DATABASE_SCRIPT_PREFIX.length()),
                dataSource);
        }
        else {
            return new ResourceScriptSource(
                resourceLoader.getResource(scriptSourceLocator));
        }
    }

}

The CustomScriptFactoryPostProcessor in this listing is similar to ScriptFactoryPostProcessor, except that it adds the ability to use a database-based script if the script source locator starts with database: (for example, database:groovierspring/GroovyPdfGenerator.groovy). Ideally, this mechanism would be more flexible (see the Toward a pluggable script source locator sidebar). But for now you have what you need to store Groovy scripts in your database.

The only task remaining is to configure the pdfGenerator bean to be read from your database. You first need to define a scriptFactoryPostProcessor bean using the CustomScriptFactoryPostProcessor shown in Listing 13. Then you define the pdfGenerator bean using the database script-source locator. You could define the pdfGenerator bean using either plain <bean/> syntax or the more clear <lang:groovy> syntax. When you use <lang:groovy>, Spring checks to see if a ScriptFactoryPostProcessor bean is in the application context named scriptFactoryPostProcessor and creates one automatically if one does not already exist. If a scriptFactoryPostProcessor is already defined, Spring uses that bean, which is how you can substitute your own custom implementation. Listing 14 shows the new configuration:

Listing 14. Database pdfGenerator bean configuration
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/GroovierSpringDataSource"/>

<bean id="scriptFactoryPostProcessor"
      class="groovierspring.CustomScriptFactoryPostProcessor">
    <property name="dataSource" ref="dataSource"/>
</bean>

<lang:groovy id="pdfGenerator"
             refresh-check-delay="60000"
             script-source="database:groovierspring/GroovyPdfGenerator.groovy">
    <lang:property name="companyName" value="Database Groovy Bookstore"/>
</lang:groovy>

The code in Listing 14 is not much more complicated than anything you've seen so far. The scriptFactoryPostProcessor bean requires that a DataSource be injected, so you also define the dataSource bean. Otherwise, the only difference is the change from a CLASSPATH-based script to one that resides in a database. If you're more inclined to use the Grails Bean Builder, you can easily use it to configure the data source and the custom ScriptFactoryPostProcessor bean.

At this point, you can load Groovy scripts from your database and also refresh them after making changes to the scripts in the database, making Spring's already flexible Groovy support even more flexible and dynamic. You've also seen how you can add your own ScriptSource implementation to allow scripts to be loaded from wherever you choose.


When Groovy scripts go bad

Everyone probably agrees you should thoroughly test your applications, though people may disagree on exactly how to go about it. For example, is 100 percent code coverage necessary, or possible, or simply a waste of time? Regardless of your personal view, testing becomes that much more important when you suddenly have the ability to deploy changes into a running production system and have those changes take effect immediately, as you can do with Spring's dynamic-language support.

If you decide to use the refreshable beans feature, then you need a solid strategy to ensure that new code works properly and as expected. How to do this effectively depends on your situation:

  • How critical is the system?
  • If you break something, what is the impact?
  • How quickly can you fix problems that arise?

Your specific situation probably involves additional considerations, but the bottom line is that the bean-refresh feature is both powerful and potentially dangerous. You need to use it responsibly. The two main types of problems you can encounter are script-compilation errors and run-time errors.

Script-compilation errors

Suppose you change a script at run time such that it will not compile. When Spring detects the change and tries to reload the bean, a ScriptCompilationException is thrown wrapping the original exception, such as a Groovy MultipleCompilationErrorsException. When this occurs, Spring cancels the attempt to reload the bean, and the original bean keeps on chugging as if nothing had happened. Your application needs to respond to ScriptCompilationExceptions appropriately. Mostly likely, you should display some kind of error message and send a notification (such as an e-mail message or instant message) to developers or operations staff. Of course, whoever is deploying the changes to the script should monitor the application to make sure the script compiles successfully and that the new bean replaces the old bean.

All is not lost, however, because scripts that don't compile have no effect on already deployed beans. So, you can fix the problem that caused the compilation exception and try again. Assuming the bean compiles successfully, Spring replaces the existing bean with the new one transparently to application code. Your changes are now in place without requiring redeployment or restarting your application.

Run-time script errors

Run-time script errors have the same problems as run-time errors thrown by compiled code: they cause a failure condition in your application that most likely will propagate up to users and cause whatever action they try to perform to fail. For example, suppose you make a change to the GroovyPdfGenerator such that it compiles but throws a run-time exception whenever it tries to generate a PDF. In that case, the code using the pdfGenerator either must handle the exception or propagate it, and most likely the user will receive an error message stating that a PDF could not be generated (and that it will be fixed as soon as possible!)

But as with script-compilation errors, all is not lost when run-time script errors occur. In fact, because scripts can be changed at run time, they can be fixed more easily than compiled code. You fix whatever problem exists in your script, and once the script is reloaded, the problem is no more. So from a certain perspective, the ability to change code at run time gives you not only more flexibility to make changes, but also more flexibility when errors strike. This doesn't mean you should make all beans in your Spring applications refreshable, though. Like many things, refreshable beans are probably best used in moderation.


Script security

One last, but certainly not least, consideration is security. It's important to secure your scripts and ensure that only authorized users or administrators can modify them. In some ways, this is no different from how you secure any other part of your application. For example, most applications need to ensure data integrity and restrict users' access to functionality that's specific to their roles or privileges. But on the other hand, this capability potentially opens up new attack vectors for hackers to intrude into your system and change not only data but also system behavior. You certainly want to reduce your application's attack surface and must weigh pros and cons as with all design trade-offs.

What makes security perhaps more important is the fact that with Spring's dynamic-language support, you can change not just system data, but behavior as well. This is to some extent true anyway: think about an SQL injection attack that injects malicious code, or JavaScript cross-site scripting, or cross-site request forgery attacks that can change or replace your system's behavior. My point is that you need to think about how to ensure proper controls on your Groovy scripts, especially if they are refreshable.

Depending on how you use refreshable beans, the additional security risk may be outweighed by the advantages of changing behavior at run time. Imagine a customer-facing sales application that needs frequent rule changes for offering discounts to customers, or perhaps an insurance application whose business rules can change frequently. In such cases, you could design a DSL written in Groovy that salespeople or insurance agents could change to suit the current business need. Maybe you want to add a bit of logic to offer a 10 percent discount on purchases over $50. It is certainly possible to accommodate this type of change by allowing users to edit small bits of a DSL directly in a running application. Or maybe you design a graphical editor they can use to change the discount policy.


Conclusion

You've now seen how to integrate Groovy into Spring-based applications using either compiled Groovy classes or scripts that are dynamically compiled and loaded. You also know how to make scripted Groovy beans refreshable, how to customize Groovy beans at creation time, and even how to store them in a relational database. You've learned how script-compilation and run-time errors affect running applications in different ways, and how refreshable beans can make fixing bugs at run time easier than using traditional architectures that require redeployment or an application restart. Finally, I briefly touched on security implications of scripted and refreshable beans, noting that you need to assess thoroughly the type of level of security required for your applications.

Together, Spring and Groovy make a powerful combination: Spring provides architecture and infrastructure, while Groovy adds dynamic capabilities. Spring's ability to reload Groovy scripts when they change can take your applications into uncharted territory. Remember though: "With great power comes great responsibility." Adding a much more dynamic nature to your applications is sure to make them more flexible and powerful, but it also brings up issues and challenges that you might not have had to deal with before.


Download

DescriptionNameSize
Sample codej-groovierspringcode.zip8.5MB

Resources

Learn

Get products and technologies

  • Spring: Download the latest Spring release.
  • Groovy: Download the latest Groovy release.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Open source
ArticleID=362235
ArticleTitle=Groovier Spring, Part 2: Change application behavior at run time
publish-date=01062009