JavaConfig的历史
Spring在最初的时候,一直是采用XML作为容器配置的手段,但随着现代项目的复杂性越来越高,Spring项目大量的烂用XML反而变成一个灾难,遭受了非常严励的一个批评。由于Spring会把几乎所有的业务类都以Bean的形式配置在XML文件中,造成了大量的XML文件。使用XML来配置Bean失去了编译时的类型安全检查。大量的XML配置使得整个项目变得更加复杂。Rod Johnson也注意到了这个非常严重的问题。当随着JAVA EE 5.0的发布,其中引入了一个非常重要的特性——Annotations(注解)。注解是源代码的标签,这些标签可以在源代码层进行处理或通过编译器把它融入到class文件中。在JAVA EE 5以后的版本中,注解成为了一个主要的配置选项。
相对于传统的XML配置方式,JavaConfig有如下的优势:
- 它是纯Java的配置方式,这意味着你可以利用所有面向对象的优势,重用、继承、多态以及类型检查等。
- 拥有对于实例及其依赖更完全的控制权。
- 拥有更好的IDE支持。
- 配置与业务逻辑是在一起的,而不是分散成代码和配置。
- 当然,它仍然是和 XML 兼容的,你可以同时在项目中使用 XML 和 JavaConfig 进行配置。
常见的JavaConfig用法
我想大部分同学都已经使用JavaConfig来注解我们的SpringBean了,比如我们常用的:
@Component | 通用组件,可以标注在任意的SprinbBean上 |
---|---|
@Repository | 通常作为存储层的Bean定义,派生自 @Component |
@Service | 通常作为服务层的Bean定义,派生自 @Component |
@Controller | 通常作为控制层的Bean定义,派生自 @Component |
当然,以上所有的注解都必须配合ComponentScan
才能生效,比如我们会在XML配置中配置如下的节点:<component-scan base-package="packages.to.scan"
或者更加 JavaConfig 的做法是通过Java代码来声明,如下所示:
1 |
|
@Configuration 的用法
@Component
,@Repository
,@Service
,@Controller
等这些注解就不讲解了,实在太过于简单和常见,我们主要讲解一下@Configuration
的用法,习惯于用XML配置的同学可能对这个注解了解得比较少,也很少会使用。
在上面的代码中我们看到一个注解@Configuration
,这个注解是Spring基于JavaConfig配置的核心,这个注解的说明如下:
Indicates that a class declares one or more {@link Bean @Bean} methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime
Spring会去解析标注这个注解的类,将它作为Spring容器的配置入口,它将会通过一系列的方法定义SpringBean。比如:
1 |
|
这段代码就是通过JavaConfig定义了三个SpringBean,需要注意的是:
ExternalObjectB
类型的Bean注册了2个,分别来自于externalObjectB1()
方法的调用和externalObjectB2()
方法的调用,它们的名字分别来自于@Bean
对应的方法名。ExternalObjectA
被externalObjectB1
和externalObjectB2
以参数的方式依赖。由于
ExternalObjectA
也被注解为@Bean
,同时,默认的SpringBean的Scope是Singleton,所以虽然被2个Bean依赖以参数方式调用了2次,但实际上externalObjectA()
只会执行一次。
通过以下的代码测试:
1 |
@Import的用法
在现实的编码过程中,我们通常会将所需要的SpringBean分门别类的在不同的@Configuration
类中进行声明配置,而不是写一个超级大的配置类来管理所有的SpringBean,有点类似于我们在XML配置时写好几个文件比如application-context-dao.xml
,application-context-service.xml
之类的。
在这种情况下,我们就需要在不同的场景组合不同的配置类,这个组合的注解就是@Import
,该注解可以将其它的@Configuration
导入到当前的配置中。比如:
1 |
|
同时,如果其它的配置是在XML文件中,也可以通过@ImportResource
来导入,也是非常方便的,比如:
1 |
|