sping+struts+iBatis框架搭建
一、配置spring文件,applicationContext-db-config.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" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
">
<!--tomcatJNDI配置方式配置,默认JNDI名字为default,如果修改JNDI名字,请修改本配置的jndiName属性-->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/default"/>
</bean>
<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor" />
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"
lazy-init="true">
<property name="nativeJdbcExtractor" ref="jdbcExtractor" />
</bean>
<!--ibatisSqlMapClient -->
<bean id="ibatisSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
scope="prototype">
<property name="configLocation" value="classpath:sqlmap-config.xml" />
<property name="lobHandler" ref="lobHandler" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="ibatisDao" class="com.dao.IbatisDaoImpl">
<property name="sqlMapClient" ref="ibatisSqlMapClient" />
</bean>
<!-- ibatis事务管理 -->
<bean id="ibatisTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="ibatisTxAdvice" transaction-manager="ibatisTransactionManager">
<tx:attributes>
<tx:method name="insert*" />
<tx:method name="update*" />
<tx:method name="delete*" />
<tx:method name="execute*" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(* *..*DaoFactory.*(..))"
advice-ref="ibatisTxAdvice" />
</aop:config>
</beans>
二、配置struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<!-- struts2中action后缀名 -->
<constant name="struts.action.extension" value="action" />
<!-- 默认编码方式 -->
<constant name="struts.i18n.encoding" value="utf-8" />
<!-- 是否为开发模式,在开发模型中可以获得更多的跟踪信息 -->
<constant name="struts.devMode" value="false" />
<!-- 标签主题 -->
<constant name="struts.ui.theme" value="xframe" />
<!-- 资源文件名称 -->
<constant name="struts.custom.i18n.resources" value="globalMessages" />
<!--静态资源文件配置 -->
<constant name="struts.serve.static" value="true" />
<!-- 在开发模式下启用 配置改变时自动加载 -->
<constant name="struts.convention.classes.reload" value="true" />
<!-- 允许Ognl表达式访问静态方法-->
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<!-- 上传文件的最大文件大小 -->
<constant name="struts.multipart.maxSize" value="20485760" />
<!-- 在寻找资源时是否忽略大小写 -->
<constant name="struts.configuration.classpath.forceLowerCase"
value="false" />
<!-- codebehind中查找action的返回结果资源时的默认文件夹 -->
<constant name="struts.codebehind.pathPrefix" value="/pages/" /
</struts>
三、IbatisDaoImpl需继承SqlMapClientDaoSupport
四、sping中 FactoryBean接口及机制
在上面的配置片段中可以,类ShopDaoRelease是我们具体的一个dao实现,其继承了SqlMapClientDaoSupport,后者暴露出一个sqlMapClient属性,用于接受Spring的注射。SqlMapClientDaoSupport会对其中封装的SqlMapClientTemplate做相应的设置,所以DAO子类便可在取用SqlMapClientTemplate时正常地工作了。
但是我们可以通过查看源码发现在SqlMapClientDaoSupport类中,关于setSqlMapClient方法的定义:
/**
* Set the iBATIS Database Layer SqlMapClient to work with.
* Either this or a "sqlMapClientTemplate" is required.
* @see #setSqlMapClientTemplate
*/
public final void setSqlMapClient(SqlMapClient sqlMapClient) {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
}
}
而我们的配置文件中名字为“sqlMapClient”的bean的类型却为org.springframework.orm.ibatis.SqlMapClientFactoryBean,而非为com.ibatis.sqlmap.client.SqlMapClient。这不免让人产生疑问,怎么能把org.springframework.orm.ibatis.SqlMapClientFactoryBean类型的实例注入给com.ibatis.sqlmap.client.SqlMapClient类型的属性呢?
这是因为Spring的机制的缘故。简单的说,如果一个bean实现了 FactoryBean接口,那么Spring就不会把该bean本身实例化并返回,而是返回该bean的getObject()返回的对象。这是Sprign的游戏规则。我们来看一眼 SqlMapClientFactoryBean的源码片段:
public class SqlMapClientFactoryBean implements FactoryBean,InitializingBean { private SqlMapClient sqlMapClient; protected SqlMapClient buildSqlMapClient(Resource configLocation,Properties properties) throws IOException { InputStream is = configLocation.getInputStream(); if (properties != null) { if (buildSqlMapClientWithInputStreamAndPropertiesMethodAvailable) { return SqlMapClientBuilder.buildSqlMapClient(is,properties); } else { return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is), properties); } } else { if (buildSqlMapClientWithInputStreamMethodAvailable) { return SqlMapClientBuilder.buildSqlMapClient(is); } else { return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is)); } } } //这里就是返回的、并会被注入到其它类里的对象 public Object getObject() { return this.sqlMapClient; } }