Spring4新特性:Groovy Bean定义DSL

Spring4支持使用Groovy DSL来进行Bean定义配置,其相似于XML,不过由于是Groovy DSL,能够实现任何复杂的语法配置,可是对于配置,咱们须要那么复杂吗?本着学习的态度试用了下其Groovy DSL定义Bean,其主要缺点:java

一、DSL语法规则不足,须要其后续维护;git

二、编辑器的代码补全须要跟进,不然没有代码补全,写这个很痛苦;github

三、出错提示不友好,排错难;web

四、当前对于一些配置仍是须要XML的支持,因此还不是100%的纯Groovy DSL;spring

五、目前对整个Spring生态支持仍是不够的,好比Web,须要观望。express

其优势就是其本质是Groovy脚本,因此能够作很是复杂的配置,若是以上问题可以解决,其也是一个不错的选择。在Groovy中的话使用这种配置感受不会有什么问题,可是在纯Java开发环境下也是有它,给个人感受是这个功能其目的是去推广它的groovy。比较怀疑它的动机。mvc

1、对比

对于我来讲,没有哪一个好/坏,只有适用不适用;开发方便不方便。接下来咱们来看一下各类类型的配置吧:app

XML风格配置编辑器

<context:component-scan base-package="com.sishuok.spring4"/>
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
        <property name="validator" ref="validator"/>
    </bean>
    <mvc:annotation-driven validator="validator"/>

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>

注解风格配置 ide

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.sishuok.spring4")
public class MvcConfiguration extends WebMvcConfigurationSupport {
    @Override
    protected Validator getValidator() {
        LocalValidatorFactoryBean localValidatorFactoryBean =
                new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
        localValidatorFactoryBean.setValidationMessageSource(messageSource());
        return localValidatorFactoryBean;
    }
}

Groovy DSL风格配置

import org.hibernate.validator.HibernateValidator
import org.springframework.context.support.ReloadableResourceBundleMessageSource
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean

beans {
    xmlns context: "http://www.springframework.org/schema/context"
    xmlns mvc: "http://www.springframework.org/schema/mvc"

    context.'component-scan'('base-package': "com,sishuok.spring4")
    mvc.'annotation-driven'('validator': "validator")

    validator(LocalValidatorFactoryBean) {
        providerClass = HibernateValidator.class
        validationMessageSource = ref("messageSource")
    }
}

由于Spring4 webmvc没有提供用于Web环境的Groovy DSL实现的WebApplicationContext,因此为了在web环境使用,单独写了一个WebGenricGroovyApplicationContext,能够到源码中查找。

能够看到,它们以前差异不是特别大;以上只提取了部分配置,完整的配置能够参考个人github: spring4-showcase

对于注解风格的配置,若是在Servlet3容器中使用的话,能够借助WebApplicationInitializer实现无配置:

public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(javax.servlet.ServletContext sc) throws ServletException {

// AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
// rootContext.register(AppConfig.class);
// sc.addListener(new ContextLoaderListener(rootContext));

        //二、springmvc上下文
        AnnotationConfigWebApplicationContext springMvcContext = new AnnotationConfigWebApplicationContext();
        springMvcContext.register(MvcConfiguration.class);

        //三、DispatcherServlet
        DispatcherServlet dispatcherServlet = new DispatcherServlet(springMvcContext);
        ServletRegistration.Dynamic dynamic = sc.addServlet("dispatcherServlet", dispatcherServlet);
        dynamic.setLoadOnStartup(1);
        dynamic.addMapping("/");

        //四、CharacterEncodingFilter
        FilterRegistration filterRegistration =
                sc.addFilter("characterEncodingFilter", CharacterEncodingFilter.class);
        filterRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

    }
}

到底好仍是很差,须要根据本身项目大小等一些因素来衡量。对于Servlet3能够参考我github的示例: servlet3-showcase 

对于Groovy风格配置,若是语法足够丰富、Spring内部支持完善,且编辑器支持也很是好的话,也是不错的选择。

2、Groovy Bean定义

接下来咱们来看下groovy DSL的具体使用吧:

一、安装环境

<dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>${groovy.version}</version>
        </dependency>

我使用的groovy版本是2.2.1

二、相关组件类

此处使用Spring Framework官网的hello world,能够前往 http://projects.spring.io/spring-framework/ 主页查看

三、Groovy Bean定义配置文件

import com.sishuok.spring4.xml.MessageServiceImpl
import com.sishuok.spring4.xml.MessagePrinter

beans {
    messageService(MessageServiceImpl) {//名字(类型) 
        message = "hello"  //注入的属性
    }

    messagePrinter(MessagePrinter, messageService) //名字(类型,构造器参数列表)

}

今后处能够看到 若是仅仅是简单的Bean定义,确实比XML简洁。

四、测试

若是不测试环境能够这样测试:

public class XmlGroovyBeanDefinitionTest1 {
    @Test
    public void test() {
        ApplicationContext ctx = new GenericGroovyApplicationContext("classpath:spring-config-xml.groovy");
        MessagePrinter messagePrinter = (MessagePrinter) ctx.getBean("messagePrinter");
        messagePrinter.printMessage();
    }
}

使用GenericGroovyApplicationContext加载groovy配置文件。

若是想集成到Spring Test中,能够这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config-xml.groovy", loader = GenericGroovyContextLoader.class)
public class XmlGroovyBeanDefinitionTest2 {

    @Autowired
    private MessagePrinter messagePrinter;

    @Test
    public void test() {
        messagePrinter.printMessage();
    }
}

此处须要定义咱们本身的bean loader,即从groovy配置文件加载:

public class GenericGroovyContextLoader extends AbstractGenericContextLoader {

    @Override
    protected String getResourceSuffix() {
        throw new UnsupportedOperationException(
                "GenericGroovyContextLoader does not support the getResourceSuffix() method");
    }
    @Override
    protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) {
        return new GroovyBeanDefinitionReader(context);
    }
}

使用GroovyBeanDefinitionReader来加载groovy配置文件。

到此基本的使用就结束了,还算是比较简洁,可是咱们已经注意到了,在纯Java环境作测试仍是比较麻烦的。 好比没有给咱们写好相关的测试支撑类。另外你们能够前往Spring的github看看在groovy中的单元测试:GroovyBeanDefinitionReaderTests.groovy

再看一下咱们使用注解方式呢:

@Component
public class MessageServiceImpl implements MessageService {
    @Autowired
    @Qualifier("message")
    private String message;
    ……
}
@Component
public class MessagePrinter {
    private MessageService messageService;
    @Autowired
    public MessagePrinter(MessageService messageService) {
        this.messageService = messageService;
    }
……
}

此处省略无关代码,须要的话直接去github查看 。 点击前往

Groovy配置文件:

beans {
    xmlns context: "http://www.springframework.org/schema/context"    //导入命名空间

    context.'component-scan'('base-package': "com.sishuok.spring4") {
        'exclude-filter'('type': "aspectj", 'expression': "com.sishuok.spring4.xml.*")
    }

    message(String, "hello") {}

}
相关文章
相关标签/搜索