先声明下,本人系菜鸟一个,问的问题如果类似于1+1为什么等于2,请少拍板
这2天在学习CGLIB,一时兴起用CGLIB实现了一个管理hibernate事务的类。
代码如下:
package com.test;import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.linbs.core.common.hibernate.HibernateUtil;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;/**
@author linbs
*/
public class TransactionDAOProxy implements MethodInterceptor {
private static Log logger = LogFactory.getLog(TransactionDAOProxy.class);
private Enhancer enhancer=new Enhancer();
public Object getDAO(Class clz){
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
Session session = null;
Transaction tx = null;
Object result = null;
try{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
result = proxy.invokeSuper(obj, args);
tx.commit();
session.flush();
}catch(HibernateException e){
try {
tx.rollback();
} catch (HibernateException e1) {
logger.error(e1.getMessage());
throw e;
}
}finally{
try {
HibernateUtil.closeSession();
} catch (HibernateException e) {
logger.error(e.getMessage());
throw new Throwable("关闭session时出错!");
}
}
return result;
}
}
其中的HibernateUtil类的getSession()方法是一个从线程中取得session副本的函数,代码相信各位大牛已经很熟悉,在此就不贴出来了。
测试类如下:
package com.test;import com.linbs.core.common.hibernate.BaseHibernateDAO;
import com.linbs.usermanage.model.User;public class Test {
public static void main(String[] args){
TransactionDAOProxy proxy = new TransactionDAOProxy();
BaseHibernateDAO baseDAO = (BaseHibernateDAO)proxy.getDAO(BaseHibernateDAO.class);
User user = new User();
user.setUserName("abcProxy");
user.setUserPwd("abcProxy");
user.setEmail("abc@126.cn");
baseDAO.save(user);
}
}
/**
* 取得当期进程的session对象
* @return
*/
public Session getSession() {
return HibernateUtil.getSession();
}/** * 保存一个新的实体类的实例,并返回标识号 * @param obj * @return */ public Serializable save(final Object obj) { return this.getSession().save(obj); }
[code="java"]enhancer的原理就是用Enhancer生成一个原有类的子类,并且设置好callback到proxy, 则原有类的每个方法调用都会转为调用实现了MethodInterceptor接口的proxy的intercept() 函数:
public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy)[/code]
你的代码中代理的是BaseHibernateDAO这个类,再调用save的时候,会内部调用到getSession的方法,而这个方法同样也会给拦截。。同样进入intercept,最后还把事务给提交了,再回到调用真的save的时候,就会出现session已经关闭的提示。。。
这是我的想法,兄弟你可以再测试测试。