Spring IOC 有一个非常核心的概念——Bean。由 Spring 容器来负责对 Bean 的实例化,装配和管理。XML 是用来描述 Bean 最为流行的配置方式。Spring 可以从 XML 配置文件中读取任何类型的元数据并自动转换成相应的 Java 代码。Spring 改变了 java 的编程模式,Spring 的下载已经超过了 1 亿次, 可见 Spring 已经有多流行。
随着 Spring 的日益发展,越来越多的人对 Spring 提出了批评。“Spring 项目大量的烂用 XML” 就是最为严励的一个批评。由于 Spring 会把几乎所有的业务类都以 Bean 的形式配置在 XML 文件中,造成了大量的 XML 文件。使用 XML 来配置 Bean 失去了编译时的类型安全检查。大量的 XML 配置使得整个项目变得更加复杂。Rod Johnson 也注意到了这个非常严重的问题。
当随着 JAVA EE 5.0 的发布,其中引入了一个非常重要的特性——Annotations(注释)。注释是源代码的标签,这些标签可以在源代码层进行处理或通过编译器把它熔入到 class 文件中。在 JAVA EE 5 以后的版本中,注释成为了一个主要的配置选项。Spring 使用注释来描述 Bean 的配置与采用 XML 相比,因类注释是在一个类源代码中,可以获得类型安全检查的好处。可以良好的支持重构。
JavaConfig 就是使用注释来描述 Bean 配置的组件。JavaConfig 是 Spring 的一个子项目, 比起 Spring,它还是一个非常年青的项目。目前的版本是 1.0 M2。使用 XML 来配置 Bean 所能实现的功能,通过 JavaConfig 同样可以很好的实现。
考虑使用 JavaConfig 替代 XML 配置
对于总是固执地使用 Spring 的 XML 配置方式,同事们总是讥讽我。是的,这看起来太二太过时了,不过 XML 还是有它的优势:
-
集中式配置。这样做不会将不同组件分散的到处都是。你可以在一个地方看到所有 Bean 的概况和他们的装配关系。
-
如果你需要分割配置文件,没问题,Spring 可以做到。它可以在运行时通过
<import>
标签或者上 Context 文件对分割的文件进行重新聚合。 -
相对于自动装配 (autowiring),只有 XML 配置允许显示装配 (explicit wiring)
-
最后一点并不代表不重要,XML 配置完全和 JAVA 文件解耦:两种文件完全没有耦合关系,这样的话,类可以被用作多个不同 XML 配置文件。
XML 唯一的问题是,只有在运行时环境时你才能发现各种配置及语法错误,但是如果使用 Spring IDE Plugin(或者 STS) 的话,它会在编码时提示这些问题。
在 XML 配置和直接注解式配置之外还有一种有趣的选择方式 - JavaConfig,它是在 Spring 3.0 开始从一个独立的项目并入到 Spring 中的。它结合了 XML 的解耦和 JAVA 编译时检查的优点。JavaConfig 可以看成一个 XML 文件,只不过是使用 Java 编写的。相关文档在官方网站是可以找到的,这篇文章只是带你了解 JavaConfig。下面的例子,让我们将从 XMl 文件移植到 JavaConfig。
XML 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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-3.2.xsd">
<bean id="button" class="javax.swing.JButton">
<constructor-arg value="Hello World" />
</bean>
<bean id="anotherButton" class="javax.swing.JButton">
<property name="icon" ref="icon" />
</bean>
<bean id="icon" class="javax.swing.ImageIcon">
<constructor-arg>
<bean class="java.net.URL">
<constructor-arg value="http://morevaadin.com/assets/images/learning_vaadin_cover.png" />
</bean>
</constructor-arg>
</bean>
</beans>
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MigratedConfiguration {
@Bean
public JButton button() {
return new JButton("Hello World");
}
@Bean
public JButton anotherButton(Icon icon) {
return new JButton(icon);
}
@Bean
public Icon icon() throws MalformedURLException {
URL url = new URL(
"http://morevaadin.com/assets/images/learning_vaadin_cover.png");
return new ImageIcon(url);
}
}
用法非常简单:
-
用 @Configuration 注解 JavaConfig 类,
-
用每个方法来表示 Bean 并使用 @Bean 注解方法。
-
每个方法名代表 XML 配置文件中的 name
注意在 Web 环境中,需要在 web.xml 中加入如下代码:
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.packtpub.learnvaadin.springintegration.SpringIntegrationConfiguration</param-value>
</context-param>