Tapestry中使用拦截器实现Hibernate的事务管理

从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;
    }

}


原文 :http://www.blogjava.net/javabin/archive/2006/10/23/56250.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值