posts - 2, comments - 2, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
从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;
    }

}


评论

# re: 在Tapestry中使用拦截器实现Hibernate的事务管理  回复  更多评论   

2006-10-23 09:49 by ELFer
你好,我现在正在学习tapestry+hivemind+hibernate框架,不知道你有没有什么好的实例,谢谢。我有一定的struct+spring+hibernate基础!
非常感谢!

# re: 在Tapestry中使用拦截器实现Hibernate的事务管理  回复  更多评论   

2006-10-24 09:30 by 浪迹天涯
@ELFer
你好,如果有好的实例我会发布出来的,谢谢你的关注。

只有注册用户登录后才能发表评论。


网站导航: