标签:
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。比较怀疑它的动机。
对于我来说,没有哪个好/坏,只有适用不适用;开发方便不方便。接下来我们来看一下各种类型的配置吧:
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.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));
//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 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.MessageServiceImpl
import com.sishuok.spring4.xml.MessagePrinter
beans {
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
再看一下我们使用注解方式呢:
@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") {}
}
标签:
原文地址:http://blog.csdn.net/hj7jay/article/details/51372484