动态代理学习

1.动态代理的作用:增强对象某些方法。

动态代理的角色:
1. 被代理对象(被增强对象)
2. 代理对象
3. 接口 (接口存在的意义:规定代理对象能够代理的方法)

需求: 生成一个代理对象增强ArrayList的add方法,添加成功或者添加失败都给用户提示信息。

动态代理涉及的类:
Proxy :
newProxyInstance() 生成一个对象。
ClassLoader loader : 类加载器, 直接使用当前类的类加载器即可
Class<?>[] interfaces : 代理对象要实现接口
InvocationHandler h : 处理器,

关注点: invoke方法的执行时机?
调用代理对象的任何方法都会执行一次invoke方法。

疑问: 调用代理对象任何的一个方法都调用一次invoke方法的意义在哪里?
让你自己把增强逻辑写在invoke方法里面。

总结动态代理的步骤:
1. 要维护一个被代理对象。
2. 获取当前的方法名
3. 判断当前执行方法是否是你需要增强的方法,如果是写上自己增强代码的业务逻辑
4. 如果不是需要增强的方法,使用被代理对象执行即可。
5. 不管方法是否需要增强都定义一个变量接收方法的返回结果,返回即可。

2.代码实现

public class Demo1 {

    public static List getListProxy(){
        List listProxy = (List) Proxy.newProxyInstance(Demo1.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler() {

            //被代理对象
            List list = new ArrayList();

            /*
               method:当前调用的方法
               args: 当前调用方法传递的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1. 获取当前调用的方法的方法名
                String methodName = method.getName();
                //2. 判断是否为需要增强的方法,如果是需要增强的方法,让被代理对象执行当前的方法,然后加上自己业务逻辑。
                Object result = null;
                if("add".equalsIgnoreCase(methodName)){
                    result =method.invoke(list,args); //add方法是返回值
                    if((boolean)result){
                        System.out.println("添加"+args[0]+"成功了喔!");
                    }else{
                        System.out.println("添加"+args[0]+"失败了喔!");
                    }
                }else {
                    //3. 如果不是增强的方法。使用被代理对象去执行当前方法即可。
                    result = method.invoke(list,args);
                }
                return result;
            }
        });
        return listProxy;
    }

    public static void main(String[] args) {
        List<String> list = getListProxy();
        list.add("宝强");
        list.add("霆锋");
        list.add("乃亮");
        System.out.println(list);
    }
}

3.代理实现mybatis关闭会话
这里用泛型是因为不确定返回的接口是什么类型

public class DaoFactoryUtils {


    /*
      定义方法可以返回任意类型的Mapper接口代理对象。
      使用这个方法返回代理对象的好处:使用任何方法
      都会自动提交与关闭sqlSession
            BrandMapper 接口,返回接口的代理对象
     */
    public static <T> T  getMapper(Class<T> mapperClass){
        Object o = Proxy.newProxyInstance(DaoFactoryUtils.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1. 维护一个被代理对象。
                SqlSession sqlSession = MyBatisUtils.getSession();
                T mapper = sqlSession.getMapper(mapperClass);
                //2. 让当前方法执行
                Object result = method.invoke(mapper,args);
                //3. 写上自己增强代码
                sqlSession.commit();
                sqlSession.close();
                System.out.println("=====sqlSessoin关闭l=====");

                return result;
            }
        });
        return (T) o;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值