前言
众所周知,Spring最大的特点就是控制反转,而实现控制反转就是通过那一系列的配置文件。平时笔者在开发过程中也写过不少XML配置文件,但大部分都是基于现有的配置文件稍作修改,很多标签内容只能做到“知其然却不知其所以然”,而有很多标签根本不知其然,所以便抽时间认真学习一下相关内容,希望能够编写一份优雅的Spring配置文件。
声明
随便打开一份Spring工程的配置文件,第一行基本上都如下所示:
<?xml version="1.0" encoding="UTF-8"?>
从字面意义基本就能知道大概是关于版本和编码信息的,而事实也的确如此。1998年,W3C就发布了XML1.0规范,也许将来会发布新版本,但是目前仍然是1.0版本。encoding是编码声明,代表xml文件采用utf-8的编码格式。
需要注意的是,XML 声明通常在 XML 文档的第一行出现。 XML 声明不是必选项,但是如果使用 XML 声明,必须在文档的第一行,前面不得包含任何其他内容或空白。
正文
声明信息之后,就是配置文件的正文了,内容基本上如下所示:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
//具体配置信息
</beans>
beans标签是整个配置文件的根节点,包含一个或者多个bean元素
,而我们的学习也从这里展开。
命名空间
xmlns
XML NameSpace的缩写,因为XML文件的标签名称都是自定义的,自己写的和其他人定义的标签很有可能会重复命名,而功能却不一样,Spring默认的命名空间就是http://www.springframework.org/schema/beans
。Spring容器在解析xml文件时,会获取标签的命名空间来跟上述url比较,判断是否为默认命名空间。
xmlns:xsi
全名xml schema instance,是指具体用到的schema资源文件里定义的元素所准守的规范。即http://www.w3.org/2001/XMLSchema-instance
这个文件里定义的元素遵守什么标准 。
xsi:schemaLocation
本文档里的xml元素所遵守的规范,这些规范都是由官方制定的,可以进你写的网址里面看版本的变动。xsd的网址还可以帮助你判断使用的代码是否合法。
那么问题来了,感觉上述信息都要在线验证,如果我的应用离线运行,那怎么办呢?Spring也考虑到了这个问题,所以都会在jar包中附带上相应的的xsd文件。通常,META-INF目录下有如下spring.handlers和spring.schemas两个文件,我们以spring 2.5.6为例,进入相应文件:
spring.handlers文件内容:
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/jms=org.springframework.jms.config.JmsNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
spring.schemas文件内容:
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/jms/spring-jms-2.5.xsd=org/springframework/jms/config/spring-jms-2.5.xsd
http\://www.springframework.org/schema/jms/spring-jms.xsd=org/springframework/jms/config/spring-jms-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd
http\://www.springframework.org/schema/tx/spring-tx-2.0.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd
http\://www.springframework.org/schema/tx/spring-tx-2.5.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd
http\://www.springframework.org/schema/tx/spring-tx.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
两个文件的内容都是常量的定义,值都是jar包的路径,打开对应的文件可以知道,xsd文件是命名空间schema的定义文件,而*Namespacehandler文件则负责将定义的xml文件信息注册Spring容器中,具体的逻辑其实可以参考spring容器的启动过程,此处不再赘述。
import标签
在实际开发过程中,一些大型项目会将配置信息按照不同的模块划分成多个配置文件,spring import标签就可以达到此目的,我们会经常看到如下的配置信息:
<import resource="file:..."/>
<import resource="classpath:..."/>
- file:表示使用文件系统的方式寻找后面的文件(文件的完整路径)
- classpath:相当于/WIN-INF/classes/,如果使用了classpath,那就表示只会到你的class路径中去查找文件
- classpath*:表示不仅会在class路径中去查找文件,还会在jar中去查找文件
需要注意的是,Spring采取递归的方式解析import标签,很可能会出现变量无法解析的情况,如果存在变量引用的情况,需要注意。
context标签
spring从2.5版本开始支持注解注入,注解注入可以省去很多的xml配置工作。由于注解是写入java代码中的,所以注解注入会失去一定的灵活性,我们要根据需要来选择是否启用注解注入。
<context:annotation-config />
<context:component-scan base-package="xxxxxxxxx"/>
前者的作用是隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor 这 4 个BeanPostProcessor。
后者启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能。当使用 < context:component-scan/ > 后,就可以将 < context:annotation-config/ > 移除了。base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
aop标签
<aop:aspectj-autoproxy/>
<aop:config>
<aop:aspect id = "aspectXML" ref="actionAspectXML">
<aop:pointcut id="anyMethod" expression="execution(* com.maowei.learning.aop.ActionImpl.*(..))"/>
<aop:before method="beforeMethod" pointcut-ref="anyMethod"/>
<aop:after method="afterMethod" pointcut-ref="anyMethod"/>
<aop:after-returning method="afterReturningMethod" pointcut-ref="anyMethod"/>
<aop:after-throwing method="afterThrowMethod" pointcut-ref="anyMethod"/>
<aop:around method="aroundMethod" pointcut-ref="anyMethod"/>
</aop:aspect>
</aop:config>
aop:aspectj-autoproxy
声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。它有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为true时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。
aop:aconfig
便是具体的AOP信息了,具体内容可以查看相关内容,不再赘述。
bean标签
bean标签
在配置文件中最常见,具体的格式有如下几种:
<bean id = "bean实例名" class="bean类全名" />
<bean id = "bean实例名" class="bean类全名" scope="prototype" />
<bean id = "bean实例名" class="bean类全名" init-method="初始化时调用的方法" destory-method="对象销毁时调用方法"/>
<bean id = "bean实例名" class="bean类全名" >
<property name="bean类的属性名称" ref="要引用的bean名称"/>
<property name="bean类的属性名称" value="直接指定属性值"/>
……
</bean>
<bean id = "bean实例名" class="bean类全名" >
<constructor-arg index="构造方法中参数的序号,从0开始计算" type="构造方法参数类型" value="参数值" />
<constructor-arg index="构造方法中参数的序号,从0开始计算" type="构造方法参数类型" ref="引用的bean名称" />
</bean>
tx标签
tx标签
一般用于事务管理,常见的用法如下:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"
isolation="READ_COMMITTED"
propagation="REQUIRED"
timeout="100"/>
<tx:method name="get*"
read-only="100"/>
</tx:attributes>
</tx:advice>
上述配置文件内容涵盖了TransactionDefinition 事务定义信息,具体解释详见《Spring 事务管理》。
总结
本文列出了spring配置文件中常见的标签,阐述了相关标签的含义及使用注意点。纸上得来终觉浅,绝知此事要躬行,只有多多练习,才能写出一份优雅的spring配置文件。