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") {} }