zk+hibernate+spring零配置
by
at 2010-12-13 15:47:55
original http://www.javaeye.com/topic/840871
zk+hibernate+spring零配置
zk5.0.5
hibernate3.6
spring3.05
也许你在使用apply或者use一个类名的或者<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
那么下面的方法对你也许是一种更优雅的方式
一,spring自动扫描注解配置,如果熟悉ss2h,看起来没什么不同
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<description>系统配置信息</description>
<!-- 定义受环境影响易变的变量 -->
<context:property-placeholder location="/WEB-INF/config/application.properties" />
<!-- -->
<!-- 数据源配置 -->
<!-- -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
<property name="minPoolSize" value="${jdbc.minPoolSize}">
</property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}">
</property>
<property name="maxIdleTime" value="${jdbc.maxIdleTime}">
</property>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}">
</property>
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}">
</property>
<property name="acquireRetryDelay" value="${jdbc.acquireRetryDelay}">
</property>
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}">
</property>
<property name="preferredTestQuery" value="${jdbc.preferredTestQuery}">
</property>
<property name="numHelperThreads" value="${jdbc.numHelperThreads}">
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
</props>
</property>
<property name="packagesToScan" value="com.linktel.linkRec.entity" />
</bean>
<!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 -->
<context:component-scan base-package="com.linktel.linkRec" />
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
</beans>
二,zk controller 注解配置,注意scope必须是prototype,因为composer是一个状态对象
@Controller
@Scope("prototype")
public class LoginController extends GenericAutowireComposer {
三,页面中使用ctrl
首先要引入我自定义的el函数库,zktools工具将在下面讲到
<?taglib uri="http://www.zkoss.org/zktools/zktools" prefix="z" ?>
然后在window apply中使用,其中z是prefix="z" 中的z,ctrl是zktools.jar中定义的一个el函数,这个和c标签很类 似, 'loginController'是【二】中LoginController类spring 受管理bean名字,通常我们喜欢使用
长长的类路径apply="com.linktel.linkRec.web.controller.LoginController",
但这样创建的对象不是spring管理,你无法向LoginController类里注入service,当然你可以使用SpringUtil.getBean
获取bean事例,但就丧失使用annotation的好处了
<window apply="${z:ctrl('loginController')}" width="300px"
完整使用
<?xml version="1.0" encoding="utf-8"?>
<?page cacheable="false" language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?>
<?taglib uri="http://www.zkoss.org/zktools/zktools" prefix="z" ?>
<div
style="background: url('images/headerbg.png') repeat-x; background-position:0 -53px;height:100%;"
xmlns:w="client" xmlns:n="native" xmlns="http://www.zkoss.org/2005/zul"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">
<window apply="${z:ctrl('loginController')}" width="300px"
height="140px" onOK="Events.postEvent("onClick",btnLogin,null);"
mode="overlapped" position="center,top" style="margin-top:100px;">
四,获取spring bean的el函数
在【三】中的页面zul中,我们仅仅简单的使用了一个表达式${z:ctrl('loginController')}, 这个表达式由
zk框架解释,还记的我们在页面首部添加的一个指令吗?
<?taglib uri="http://www.zkoss.org/zktools/zktools" prefix="z" ?>
和jsp c标签类似, zk中的标签也是在tld文件中定义的,大部分的web容器都可以自动加载tld文件,
zk也是一样,但zk不会自动加载tld,它自动加载类路径下的一个metainfo/tld/config.xml文件,这是zk的约定

在config.xml文件中我定义了如下内容,当然这些也是zk的约定,taglib-location告诉zk框架tld文件位置,
那么zk自动去找这个文件并解析
<?xml version="1.0" encoding="UTF-8"?>
<!--
by sunflower
-->
<config>
<version>
<version-class>org.zkway.zktools.Version</version-class>
<version-uid>1.0</version-uid>
</version>
<taglib>
<taglib-uri>http://www.zkoss.org/zktools/zktools</taglib-uri>
<taglib-location>/web/WEB-INF/tld/zktools/zktools.tld</taglib-location>
</taglib>
</config>
那么我们看看zktools.tld里如何定义的
<!-- -->
<!-- 获取spring 管理bean -->
<!-- -->
<function>
<name>ctrl</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.lang.Object getController(java.lang.String)</function-signature>
<description>获取spring 管理controller</description>
</function>
<function>
<name>comp</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.lang.Object getComponent(java.lang.String)</function-signature>
<description>获取spring 管理组件对象</description>
</function>
<function>
<name>bean</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.lang.Object getBean(java.lang.String)</function-signature>
<description>获取spring 管理bean对象</description>
</function>
<!-- -->
<!-- 工具函数 -->
<!-- -->
<function>
<name>size</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>int size(java.lang.Object)</function-signature>
<description>获取一个对象的大小</description>
</function>
<function>
<name>length</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>int size(java.lang.Object)</function-signature>
<description>获取一个对象的大小</description>
</function>
<function>
<name>empty</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>boolean isEmpty(java.lang.Object)</function-signature>
<description>判断一个对象是否是空对象</description>
</function>
<!-- -->
<!-- 日期工具函数 -->
<!-- -->
<function>
<name>now</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.util.Date currentTime()</function-signature>
<description>获取当前时间</description>
</function>
<function>
<name>today</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.util.Date today(int, int, int)</function-signature>
<description>获取今天的日期时间,可以指定今天时分秒,-1表示不设置</description>
</function>
<function>
<name>firstDayOfMonth</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.util.Date firstDayOfMonth()</function-signature>
<description>获取当前月的第一天</description>
</function>
<function>
<name>lastDayOfMonth</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.util.Date lastDayOfMonth()</function-signature>
<description>获取当前月的最后一天</description>
</function>
<function>
<name>fmtDate</name>
<function-class>org.zkway.zktools.ZkCommonTools</function-class>
<function-signature>java.lang.String formatDate(java.lang.String)</function-signature>
<description>根据参数指定的模式,格式化当前日期</description>
</function>
1)<name>定义了el函数的名字,例如${z:ctrl('loginController')}中的ctrl对应以下中的ctrl
<function> <name>ctrl</name> <function-class>org.zkway.zktools.ZkCommonTools</function-class> <function-signature>java.lang.Object getController(java.lang.String)</function-signature> <description>获取spring 管理controller</description> </function>
2)function-signature函数指定了函数签名,具体哪个函数
3)function-class为function-signature函数所属的类
4)description为函数描述
那么这个函数必须符合什么规范呢:public,static 可以不是final
public class ZkCommonTools {
/**
* 获取spring管理的控制器对象,
* <p>
*
* 支持的类型为:{@link Composer},{@link Component},{@link FullComposer}
*
* @param beanName
* @return
*/
public static final Object getController(String beanName) {
Object controller = SpringUtil.getBean(beanName);
if (controller instanceof Composer)
return controller;
else if (controller instanceof FullComposer)
return controller;
else if (controller instanceof Component)
return controller;
return null;
}
五,总结
首先我们在spring的配置中开启自动扫描
<!-- 使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 -->
<context:component-scan base-package="com.linktel.linkRec" />
将controller注册为spring bean
@Controller
@Scope("prototype")
public class LoginController extends GenericAutowireComposer {
然后我们需要解决的问题是如何获取bean,如果直接apply或use一个类名,
那么类实例由zk创建,我们无法享受spring管理bean给我们带来的任何好处。
也许会这么做,就是在forward到一个zul页面前,先将spring bean放在可用作用域(execution,request,session,ThreadLocal),
然后目标页面直接使用el表达式获取${reqeustScope['loginController']},但实际项目中,下一站到底是什么,大多数情况我们是无法预知的,
只有到达目标你才能知道结果,所以预先读取bean很多情况下有他的局限性。
在本文中我定义了一个el函数ctrl,这个函数的参数为spring bean名字,el函数的返回值是spring管理的bean事例
大致流程如下
spring scan bean ---> register controller bean ---> el function 获取 spring bean -->zk interpret -
-
本文附件下载:
<li><a href="http://dl.javaeye.com/topics/download/88bbc8ba-b8dc-3616-af7c-acad669f9a59">zk_spring_hibernate零配置.part3.rar</a> (5.2 MB)</li>
<li><a href="http://dl.javaeye.com/topics/download/039df5fa-993a-3152-bddf-4216d2455b23">zk_spring_hibernate零配置.part1.rar</a> (7 MB)</li>
<li><a href="http://dl.javaeye.com/topics/download/158fa228-091e-3671-b775-52077cab26fa">zk_spring_hibernate零配置.part2.rar</a> (7 MB)</li>
<li><a href="http://dl.javaeye.com/topics/download/c1a0cb02-1725-3aad-8d58-fe0673f64124">zktools函数库.rar</a> (4.4 KB)</li>
<li><a href="http://dl.javaeye.com/topics/download/625386a0-f432-35f7-9ac1-6bd3ce8d84e0">zktools源码.rar</a> (2.4 MB)</li>
<br><br>
作者: <a href="http://sun4love.javaeye.com">sun4love</a>
<br>
声明: 本文系JavaEye网站发布的原创文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
<br><br>
<span style="color:red">
<a href="http://www.javaeye.com/topic/840871" style="color:red">已有 <strong>0</strong> 人发表回复,猛击->><strong>这里</strong><<-参与讨论</a>
</span>
<br><br><br>
JavaEye推荐