JDK动态代理机制
代理模式有两种,一种是静态代理,这种方式需要为每一个被代理类写一个代理类,显示比较麻烦。还一种是动态代理,动态代理实现方式一般有两种,JDK动态代理与CGLIB动态代理,这里说一下对JDK动态代理的理解。
JDK动态代理最核心的就类就是java.lang.reflect.Proxy,可调用Proxy.newInstance(..)生成动态代理。
如果有一个UserService接口(JDK动态代理必须有接口),一个UserService接口实现类UserServiceBean,现在要生成一个UserServiceBean的动态代理类代码如下:
package cn.it.shopping.service.system.impl;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import org.hibernate.Session;import cn.it.shopping.misc.SessionFactoryHelper;import cn.it.shopping.pojo.system.Admin;import cn.it.shopping.service.base.DaoSupport;import cn.it.shopping.service.system.AdminService;import cn.it.shopping.utils.MD5;/** * 自己实现的动态代理AdminServiceBean,在方法开始前打开事务,在方法执行打开事务,提交或回滚后关闭session * 出现异常自动回滚 * @author zj * */public class ProxyAdminServiceBean extends DaoSupport<Admin> implements AdminService {private static ProxyAdminServiceBean instance = new ProxyAdminServiceBean();private ProxyAdminServiceBean(){} //保证单例/** * 真正返回的是instance的一个代理对象 */public static AdminService getInstance() {return (AdminService) Proxy.newProxyInstance(instance.getClass().getClassLoader(), new Class[]{AdminService.class}, new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//SessionFactoryHelper为获取SessionFactory的一个工具类//这样获取的Session会在事务提交或回滚时自动提交,因为返回的本身就已经是个代理对象Session session = SessionFactoryHelper.getSessionFactory().getCurrentSession();session.getTransaction().begin();//开始前开启事务Object result;try {result = method.invoke(instance, args);//执行业务逻辑session.getTransaction().commit();//业务逻辑执行完成后提交事务return result;} catch (Exception e) {session.getTransaction().rollback(); //如果业务逻辑出现例外则事务回滚throw new RuntimeException(e);} finally {if(null!=session && session.isOpen()) {session.close();//这里是不会执行的,因为Session会在事务提交或回滚时自动提交,如果调用的是openSession获取Session这里就会执行}}}});}public void save(Admin entity) {String pass = MD5.MD5Encode(entity.getPass());entity.setPass(pass);super.save(entity);}}