24.4. 场景

在某些可能的场景下,使用脚本语言定义受Spring管理的bean是有好处的,当然这样的场景是各式各样的。 这一节描述了两个能使用Spring动态语言支持特性的用例。

请注意Spring的发布包中包括了一个动态语言支持的示例项目(示例项目只是一个小项目,仅用于演示Spring框架的某些特定的特征)。

24.4.1. Spring MVC控制器的脚本化

有一组类可以使用dynamic-language-backed bean并从中获益,那就是Spring MVC控制器。在纯Spring MVC应用中,贯穿整个web应用的导航流程,相当大的部分都封装在Spring MVC控制器的代码中。因为web应用的导航流程和其他表示层逻辑需要能够积极响应业务需求的变化和问题,通过编辑一个或多个动态语言源文件也许可以更容易响应这样那样的变化,而且通过这种方式,一个处于运行状态的应用可以立即反映出所做的改动。

像Spring这样由项目支持的轻量级架构模型中,你的目标是拥有一个真正瘦小 的表示层,而应用的所有业务逻辑都在包装在领域层和服务层的类中,将Spring MVC控制器作为dynamic-language-backed bean来进行开发,可以简单的编辑保存文本文件就可以修改表示层逻辑,这些动态语言源文件的任何变化都可以(取决于配置)自动的反射为bean(底层为动态语言源文件)的变化。

注意

请注意为了自动“获取”dynamic-language-backed bean的各种变化,你必须启用'refreshable beans' 功能。 关于该特征的详细情况请参考第 24.3.1.2 节 “Refreshable bean”一节。

下面的示例是使用Groovy动态语言实现的org.springframework.web.servlet.mvc.Controller。这个例子选自Spring发布包中提供的动态语言支持示例项目。关于该项目的详情请参考Spring发布包中的'samples/showcases/dynamvc/'目录。

// from the file '/WEB-INF/groovy/FortuneController.groovy'
package org.springframework.showcase.fortune.web

import org.springframework.showcase.fortune.service.FortuneService
import org.springframework.showcase.fortune.domain.Fortune
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.Controller

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class FortuneController implements Controller {

    @Property FortuneService fortuneService

    ModelAndView handleRequest(
            HttpServletRequest request, HttpServletResponse httpServletResponse) {

        return new ModelAndView("tell", "fortune", this.fortuneService.tellFortune())
    }
}
<lang:groovy id="fortune"
             refresh-check-delay="3000"
             script-source="/WEB-INF/groovy/FortuneController.groovy">
    <lang:property name="fortuneService" ref="fortuneService"/>
</lang:groovy>

24.4.2. Validator的脚本化

在使用Spring进行应用程序开发时,校验可能会是另一个可以从dynamic-language-backed bean提供的灵活性中获益的方面。 相对于Java语言,使用松散类型的动态语言(可能还支持内置的正则表达式)也许可以更容易地表示复杂的校验逻辑。

使用dynamic-language-backed bean作为校验器,可以很容易的改变校验逻辑,只要编辑简单的文本文件即可; 任何此类修改会(根据配置)自动反应到正在运行的应用程序中,而无需重启应用程序。

注意

请注意为了自动“获取”dynamic-language-backed bean的各种变化,你必须启用 'refreshable beans' 功能。关于该特征的详细情况请参考第 24.3.1.2 节 “Refreshable bean”一节。

下面的示例是使用Groovy动态语言实现的org.springframework.validation.Validator。(关于Validator接口的讨论请参考第 5.2 节 “使用Spring的Validator接口进行校验” 一节)

import org.springframework.validation.Validator
import org.springframework.validation.Errors
import org.springframework.beans.TestBean

class TestBeanValidator implements Validator {

    boolean supports(Class clazz) {
        return TestBean.class.isAssignableFrom(clazz)
    }
    
    void validate(Object bean, Errors errors) {
        if(bean.name?.trim()?.size() > 0) {
            return
        }
        errors.reject("whitespace", "Cannot be composed wholly of whitespace.")
    }
}