Spring4新特性——Groovy Bean定义DSL

编程技术  /  houtizong 发布于 3年前   64

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

 

Spring4支持使用Groovy DSL来进行Bean定义配置,其类似于XML,不过因为是Groovy DSL,可以实现任何复杂的语法配置,但是对于配置,我们需要那么复杂吗?本着学习的态度试用了下其Groovy DSL定义Bean,其主要缺点:

1、DSL语法规则不足,需要其后续维护;

2、编辑器的代码补全需要跟进,否则没有代码补全,写这个很痛苦;

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

4、当前对于一些配置还是需要XML的支持,所以还不是100%的纯Groovy DSL;

5、目前对整个Spring生态支持还是不够的,比如Web,需要观望。

 

其优点就是其本质是Groovy脚本,所以可以做非常复杂的配置,如果以上问题能够解决,其也是一个不错的选择。在Groovy中的话使用这种配置感觉不会有什么问题,但是在纯Java开发环境下也是有它,给我的感觉是这个功能其目的是去推广它的groovy。比较怀疑它的动机。

 

接下来我们来看看Spring配置的发展:

Spring 2时代是XML风格配置  可以参考《跟我学Spring3》的前几章

Spring 3时代引入注解风格配置  可以参考《跟我学Spring3》的第12章 

Spring 4时代引入Groovy DSL风格来配置 后续讲解

 

一、对比

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

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>

 

注解风格配置 

@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.HibernateValidatorimport org.springframework.context.support.ReloadableResourceBundleMessageSourceimport org.springframework.validation.beanvalidation.LocalValidatorFactoryBeanbeans {    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));        //2、springmvc上下文        AnnotationConfigWebApplicationContext springMvcContext = new AnnotationConfigWebApplicationContext();        springMvcContext.register(MvcConfiguration.class);        //3、DispatcherServlet        DispatcherServlet dispatcherServlet = new DispatcherServlet(springMvcContext);        ServletRegistration.Dynamic dynamic = sc.addServlet("dispatcherServlet", dispatcherServlet);        dynamic.setLoadOnStartup(1);        dynamic.addMapping("/");        //4、CharacterEncodingFilter        FilterRegistration filterRegistration =                sc.addFilter("characterEncodingFilter", CharacterEncodingFilter.class);        filterRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");    }}

 

到底好还是不好,需要根据自己项目大小等一些因素来衡量。对于Servlet3可以参考我github的示例:servlet3-showcase  

 

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

 

 

二、Groovy Bean定义

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

1、安装环境

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

我使用的groovy版本是2.2.1

 

2、相关组件类

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

 

3、Groovy Bean定义配置文件

import com.sishuok.spring4.xml.MessageServiceImplimport com.sishuok.spring4.xml.MessagePrinterbeans {    messageService(MessageServiceImpl) {//名字(类型)         message = "hello"  //注入的属性    }    messagePrinter(MessagePrinter, messageService) //名字(类型,构造器参数列表)}

从此处可以看到 如果仅仅是简单的Bean定义,确实比XML简洁。

 

 

4、测试

如果不测试环境可以这样测试:

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

 

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

@Componentpublic class MessageServiceImpl implements MessageService {    @Autowired    @Qualifier("message")    private String message;    ……}
 
@Componentpublic 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") {}}
在该配置文件中支持导入xml命名空间, 其中context.'component-scan'部分等价于XML中的:

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客