时不时地,关于Spring框架如何充满XML,它多么可怕和冗长,以及作者因此而永远不会使用它的愤怒的帖子或评论bit之以鼻。 当然,那完全是胡扯。 首先,创建Spring时,XML非常热门。 J2EE部署描述符(是的,当时的名称)是基于XML的。
无论如何,这是2017年的人们,并且有多种方法可以给猫做皮。 本文旨在列出配置Spring应用程序上下文的不同方法,以启发上述人群-并停止围绕Spring和XML的争论。
XML格式
XLM是配置Spring应用程序上下文的第一种方法。 基本上,创建具有专用名称空间的XML文件。 非常简单:
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<beanid="foo"class="ch.frankel.blog.Foo">
<constructor-argvalue="Hello world!"/>
</bean>
<beanid="bar"class="ch.frankel.blog.Bar">
<constructor-argref="bar"/>
</bean>
</beans>
下一步是使用专用类创建应用程序上下文:
ApplicationContextctx=newClassPathXmlApplicationContext("ch/frankel/blog/context.xml");
ApplicationContextctx=newFileSystemXmlApplicationContext("/opt/app/context.xml");
ApplicationContextctx=newGenericXmlApplicationContext("classpath:ch/frankel/blog/context.xml");
XML的声明性质强制执行简单性,但要付出额外的冗长性。 它与代码正交-完全独立。 在JavaConfig出现之前,我仍然偏爱XML而不是自注释类。
自注释类
对于每种新的未来/技术,当Java 5引入注解时,便急于使用它们。 本质上,自注释类将自动神奇地注册到应用程序上下文中。
为此,Spring提供了@Component
批注。 但是,为了改善语义,还提供了专用注释,以区分分层体系结构原理的3个标准层:
-
@Controller
-
@Service
-
@Repository
这也很简单:
@Component
publicclassFoo{
publicFoo(@Value("Hello world!")Stringvalue){}
}
@Component
publicclassBar{
@Autowired
publicBar(Foofoo){}
}
要扫描自我注释的类,需要专用的应用程序上下文:
ApplicationContextctx=newAnnotationConfigApplicationContext("ch.frankel.blog");
自我注释类很容易使用,但是有一些缺点:
- 一个自我注释的类将依赖于Spring框架。 对于基于依赖注入的框架,这是一个很大的问题。
- 自我注释的使用模糊了类和bean之间的边界。 因此,该类不能以不同的名称和作用域多次注册到上下文中。
- 自我注释的类需要自动装配,这本身就有缺点 。
Java配置
鉴于上述有关自注释类的问题,Spring框架引入了一种配置上下文的新方法:JavaConfig。 本质上,JavaConfig配置类代替XML文件,但是具有编译时安全性,而不是XML模式运行时验证。 这基于对类的两个注释@Configuration
和对方法的@Bean
。
下面的代码段与上述XML等效:
@Configuration
publicclassJavaConfiguration{
@Bean
publicFoofoo(){
returnnewFoo("Hello world!");
}
@Bean
publicBarbar(){
returnnewBar(foo());
}
}
可以像自注释类一样扫描JavaConfig类:
ApplicationContextctx=newAnnotationConfigApplicationContext("ch.frankel.blog");
JavaConfig 就是这样来配置Spring应用程序:它是正交的代码,并带来一定程度的编译时间验证。
Groovy DSL
Spring 4添加了一种通过Groovy特定于域的语言配置上下文的方法。 配置在Groovy文件中进行,文件以beans
元素为根。
beans{
fooString,'Hello world!'
barBar,foo
}
有一个关联的应用程序上下文创建器类:
ApplicationContextctx=newGenericGroovyApplicationContext("ch/frankel/blog/context.groovy");
我不是Groovy开发人员,所以我从未使用过该选项。 但是,如果是这样,这很有道理。
Kotlin DSL
Groovy在一段时间前毫不客气地被踢出了Pivotal投资组合。 没有关联,Kotlin已经找到了解决之道。难怪即将发布的Spring 5提供了Kotlin DSL。
packagech.frankel.blog
funbeans()=beans{
bean{
Foo("Hello world!")
Bar(ref())
}
}
请注意,虽然bean声明是显式的,但连接是隐式的,就像在具有依赖项的JavaConfig @Bean
方法中一样。
与上述配置风格相反,Kotlin DSL需要现有的上下文才能在以下位置注册bean:
importch.frankel.blog.beans
funregister(ctx:GenericApplicationContext){
beans().invoke(ctx)
}
我没有使用Kotlin DSL,而是在演示中使用了它,所以我不能肯定地说出优缺点。
结论
到目前为止,JavaConfig替代方案是我的最爱:它与代码正交,并且提供了一定程度的编译时验证。 作为Kotlin的狂热者,我也非常渴望在大型项目中尝试Kotlin DSL,以亲身体验其优缺点。
翻译自: https://blog.frankel.ch/flavors-spring-application-context-configuration/