动态代理学习小案例
1 package edu.nf.utils; 2 3 import edu.nf.dao.UserDao; 4 import edu.nf.dao.UserInvocationhandler; 5 import org.apache.ibatis.session.SqlSession; 6 7 import java.lang.reflect.InvocationHandler; 8 import java.lang.reflect.Proxy; 9 10 /** 11 * 代理工具 12 * @Author LQY 13 * @Date 2018/10/15 14 */ 15 public class ProxyUtil { 16 /** 17 * 在使用mybatis前提下,获取操作数据库dao的实现类的代理对象 18 * @param clazz dao接口的class对象 19 * @return 20 */ 21 public static Object getProxy(Class<?> clazz){ 22 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 23 Object dao = sqlSession.getMapper(clazz); 24 try { 25 InvocationHandler handler = new DaoInvocationhandler(dao); 26 return Proxy.newProxyInstance(clazz.getClassLoader(), dao.getClass().getInterfaces(), handler); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 return null; 31 } 32 }
package edu.nf.dao; import edu.nf.utils.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 回调处理器 * @Author LQY * @Date 2018/10/15 */ public class DaoInvocationhandler implements InvocationHandler{ private Object target ; public UserInvocationhandler(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; SqlSession sqlSession = MyBatisUtil.getSqlSession(); try { obj = method.invoke(target,args); //提交事务 sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); //回滚事务 sqlSession.rollback(); }finally { //释放SqlSession sqlSession.close(); } return obj; } }
代理类可以在运行时创建全新的类 。 这样的
代理类能够实现指定的接口
。 尤其是 , 它具有下列方法 :
• 指定接口所需要的全部方法 。
• Object
类中的全部方法 , 例如 , toString 、 equals 等
。
然而
, 不能在运行时定义这些方法的新代码 。 而是要提供一个调用处理器 ( invocation
handler ) 。 调用处理器是实现了 InvocationHandler 接口的类对象 。 在这个接口中只有一个方法 :
Object invoke ( Object proxy , Method method , Object □ args )
无论何时调用代理对象的方法
, 调用处理器的
invoke 方法都会被调用 , 并向其传递
Method 对象和原始的调用参数 。 调用处理器必须给出处理调用的方式 。
要使用上面这个小工具必须要有这两个类。
学习动态代理的小案例工具,写得不好请多多指教!
学会用不同的角度看待每个问题!