Spring 源码梳理(八) Spring常用配置
前面的文章主要分析了Spring的生命周期,Spring如何处理它的配置文件,Bean的前置和后置处理器,Spring的后置处理器等; 这些都是与Spring Bean相关的内容,实际上都属于Spring两大特性中的IOC。 后面会介绍Spring的另一个特性AOP,这篇总结下Spring的IOC特性在项目中配置中的实现和它的原理。
1.加载配置文件时用到的<context:property-placeholder>
property-placeholder这个配置是用来加载属性文件,对属性文件的解析是通过PropertyPlaceholderConfi
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
这里的Spring后置处理器就是BeanFactoryPostProcessor,其实很好理解,在Spring配置文件中的所有属性配置预加载之后,就会执行BeanFactoryPostProcessor,这个时候会对已经预加载的属性文件进行读取,然后存入相关的值; 接着就会进行Bean的实例化,在实例化到dataSource的时候,就会取出刚刚存入的属性文件中的值。
2.导入Spring配置文件时用到的import
当项目中存在多个Spring的配置文件的时,可能会在web.xml中写上多个,也可以把所有的Spring配置文件引入到一个文件中,在web.xml中只需要引入一个配置文件即可。这个时候就需要用到,import属性,如:
<import resource="classpath:spring_mvc.xml" />
注:
1)classpath的使用问题
对于上面的1和2,即property-placeholder和import,都可以使用classthPath,classpath的使用如下:
A:classpath和classpath*都可以加载整个classpath下(包括jar包里面)的资源文件
B:classthpath只会返回第一个匹配的资源,查找路径是优先在项目中存在的资源文件,再查找jar包
详细的文章见大胡子的文章:http://blog.csdn.net/zl3450341/article/details/9306983 (深究calssthpath的加载问题,其实就是看Spring如何制定相应规则,不过深究的精神值得学习)
2)对于导入的配置文件需要用到属性文件中的属性,如
<context:property-placeholder location="classpath:spring_config.properties" />
<import resource="classpath:spring-${env}.xml" />
这种情况 下是不能够正确的的解析${env}的值,从而加载到配置文件的。 分析一下这两条配置的加载过程
接着前面文章分析的refresh方法,import的加载实际上是在bean的预加载进行的,所以会在obtainFreshBeanFactory方法中加载Spring的配置文件。当我们debug就会发现经过这个obtainFreshBeanFactory方法后,系统就会提示错误:
java.lang.IllegalArgumentException: Could not resolve placeholder 'env' in string value "classpath:Spring${env}.xml"
而这个时候属性文件还没有加载,因为上面1已经分析了,属性文件的加载是通过PropertyPlaceholderConfi
那如何解决这个问题,如果是web项目,可以配置监听器,在系统初始化的时候,可以把属性写在系统属性中。 还有更好的方法,以后介绍~
3.加载数据源的时用到的dataSource属性
1)org.springframework.jdbc.datasource.DriverManagerDataSource
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
这个是Spring框架提供的接口,建立数据库连接时只要有连接就新建一个connection,没有连接池的作用。
2)org.apache.commons.dbcp.BasicDataSource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
apache提供的的接口,使用了dbcp,实现了连接池。
(c3p0能够类似,也能够实现连接池,如下:)
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
3)org.springframework.jndi.JndiObjectFactoryBean
它是Spring提供的接口,它的应用场景是:
如果应用配置在高性能的应用服务器上(如Weblogic或Websphere),我们可能更希望使用应用服务器本身提供给的数据源。应用服务器的数据源使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类;
关于属性dataSource的详细,可以看 作者待絮的这篇文章 http://blog.csdn.net/yangyz_love/article/details/8199207
还有很多配置要么属性AOP特性,要么是属于Mvc和Shiro和Mybatis等框架的,在后面学习到这些框架的源码后,会逐渐补上。