论坛首页 Java企业应用论坛

zk+hibernate+spring零配置

浏览 4398 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-12-13   最后修改:2011-03-16

 

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="org.zkway.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="org.zkway" />
	<!-- 使用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="org.zkway.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(&quot;onClick&quot;,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="org.zkway" />

 

将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 -

 

 

 

 

 

 

 

  • 大小: 9.1 KB
  • 大小: 10.5 KB
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics