动态代理学习小案例

 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;
    }
}
View Code

代理类可以在运行时创建全新的类 。 这样的
代理类能够实现指定的接口
。 尤其是 , 它具有下列方法 :
• 指定接口所需要的全部方法 。
• Object
类中的全部方法 , 例如 , toString 、 equals 等

然而
, 不能在运行时定义这些方法的新代码 。 而是要提供一个调用处理器 ( invocation
handler ) 。 调用处理器是实现了 InvocationHandler 接口的类对象 。 在这个接口中只有一个方法 :
Object invoke ( Object proxy , Method method , Object □ args )
无论何时调用代理对象的方法
, 调用处理器的
invoke 方法都会被调用 , 并向其传递
Method 对象和原始的调用参数 。 调用处理器必须给出处理调用的方式 。

 

 

要使用上面这个小工具必须要有这两个类。

学习动态代理的小案例工具,写得不好请多多指教!

posted @ 2018-10-16 14:18  逆思维  阅读(221)  评论(0编辑  收藏  举报