Posted on 2006-07-03 10:11
浪迹天涯 阅读(1082)
评论(2) 编辑 收藏 所属分类:
Tapestry
从Tapestry4.0开始使用了Hivemind作为注入容器,合理有效的使用该容器,可以极大的简化开发工作,减少代码量.比如说,在开发Hibernate应用时,就有一个关于事务控制的问题,在Spring中可以使用Spring来管理事务,但是我觉得那样对自己的代码侵入性比较大,而利用Hivemind中的拦截器,则可以方便的解决此问题,而且侵入性小.
步骤是这样的:
1.配置Hibernate Session服务,并保证该服务是线程级的.
2.配置拦截器服务,并向其注入Hibernate Session服务.
3.配置DAO服务,并配置其拦截器为上一步的拦截器.
具体的实现如下:1.配置文件
<?xml version="1.0"?>
<!--
Copyright 2004, 2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<module id="mymodule" version="4.0.0">
<service-point id="userDao" interface="com.ims.dao.UserInfoDAO">
<invoke-factory>
<construct class="com.ims.dao.impl.UserinfoDAOImpl">
<set-object property="session" value="service:hibernateSession"/>
</construct>
</invoke-factory>
<interceptor service-id="ims.SessionInterceptor">
<include method="make*"/>
</interceptor>
</service-point>
<service-point id="SessionInterceptor" interface="org.apache.hivemind.ServiceInterceptorFactory">
<invoke-factory>
<construct class="com.hivemind.util.interceptor.SessionInterceptor" >
<set-object property="session" value="service:hibernateSession" />
</construct>
</invoke-factory>
</service-point>
<service-point id="hibernateHivemindFactory" interface="org.apache.hivemind.ServiceImplementationFactory">
<invoke-factory>
<construct class="com.hivemind.util.HibernateHivemindFactory" initialize-method="init">
<set-object property="threadEventNotifier" value="service:hivemind.ThreadEventNotifier"/>
</construct>
</invoke-factory>
</service-point>
<service-point id="hibernateSession" interface="org.hibernate.Session">
<invoke-factory service-id="ims.hibernateHivemindFactory" model="threaded">
<config file="hibernate.cfg.xml"/>
</invoke-factory>
</service-point>
</module> 2.代码:
/** *//**
* SessionInterceptor.java
*
* */
package com.hivemind.util.interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.hivemind.Element;
import org.apache.hivemind.InterceptorStack;
import org.apache.hivemind.ServiceInterceptorFactory;
import org.apache.hivemind.internal.Module;
import org.apache.hivemind.service.impl.LoggingUtils;
import org.apache.hivemind.util.StringUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
/** *//**
* Hibernate Session的拦截器,对符合指定条件的方法进行拦截, 加入事务处理功能。
*
*
*/
public class SessionInterceptor implements ServiceInterceptorFactory {
private String[] required_method;
private Session session;
public void setSession(Session session) {
this.session = session;
}
/** *//**
* 核心服务方法,生成拦截器
*/
public void createInterceptor(InterceptorStack stack,
Module invokingModule, List parameters) {
Log log = stack.getServiceLog();
for (int i = 0; i < parameters.size(); i++) {
Object obj = parameters.get(i);
if (obj instanceof Element) {
Element element = (Element) obj;
if ("include".equals(element.getElementName())) {
String value = element.getAttributeValue("method");
required_method = StringUtils.split(value);
}
}
}
Object obj = stack.peek();
InvocationHandler handler = new HibernateSessionInvocationHandler(log,
obj, session, required_method);
Object interceptor = Proxy.newProxyInstance(invokingModule
.getClassResolver().getClassLoader(), new Class[] { stack
.getServiceInterface() }, handler);
stack.push(interceptor);
}
}
/** *//**
* 拦截器方法调用处理类。
*
*/
class HibernateSessionInvocationHandler implements InvocationHandler {
private Log log;
/** *//**
* 原始对象
*/
private Object delegate;
private Session session;
/** *//**
* 配置的方法名称列表
*/
private String[] requredName;
public HibernateSessionInvocationHandler(Log log, Object delegate,
Session session, String[] required_name) {
this.log = log;
this.delegate = delegate;
this.session = session;
this.requredName = required_name;
}
/** *//**
* 处理拦截到的方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
boolean debug = log.isDebugEnabled();
Transaction tx = null;
if (debug) {
LoggingUtils.entry(log, method.getName(), args);
}
if (isMatch(method.getName(), requredName)) {
try {
tx = session.beginTransaction();
result = method.invoke(delegate, args);
if (debug) {
if (method.getReturnType() == void.class)
LoggingUtils.voidExit(log, method.getName());
else
LoggingUtils.exit(log, method.getName(), result);
}
tx.commit();
return result;
} catch (InvocationTargetException ex) {
try {
tx.rollback();
} catch (Exception e) {
}
Throwable targetException = ex.getTargetException();
if (debug)
LoggingUtils.exception(log, method.getName(),
targetException);
throw targetException;
}
} else {
try {
result = method.invoke(delegate, args);
if (debug) {
if (method.getReturnType() == void.class)
LoggingUtils.voidExit(log, method.getName());
else
LoggingUtils.exit(log, method.getName(), result);
}
return result;
} catch (InvocationTargetException e) {
Throwable targetException = e.getTargetException();
if (debug)
LoggingUtils.exception(log, method.getName(),
targetException);
throw targetException;
}
}
}
/** *//**
* 当前调用的方法名称是否符合指定的条件
*
* @param name
* @param names
* @return
*/
private boolean isMatch(String name, String[] names) {
if (names == null)
return false;
for (int i = 0; i < names.length; i++) {
String sname = names[i];
if (name.equals(sname) || sname.endsWith("*")
&& name.startsWith(sname.substring(0, sname.length() - 1))
|| sname.startsWith("*")
&& name.endsWith(sname.substring(1)))
return true;
}
return false;
}
}