动态代理Demo

 

动态代理简介:

 

java代理有jdk动态代理、cglib代理,这里只说下jdk动态代理,jdk动态代理主要使用的是java反射机制(既java.lang.reflect包)

动态代理原理:

原理是(歌手、经纪人做例子):

   建立一个公共的接口,比如:歌手public interface Singer;

   用具体的类实现接口,比如:周杰伦,他是歌手所以实现Singer这个类,class MySingerimplements Singer;

   建立代理类,这里也就是经纪人,他需要实现InvocationHandler类,并重写invoke方法;

这样当有什么事情,要找周杰伦(具体类)的时候,就必须先到经纪人(代理类)那里处理,代理人在决定要不要与你见面(该方法要不要执行);

Proxy类:

 

动态代理:程序运行时,使用JDK提供工具类(Proxy),动态创建一个类,此类一般用于代理。

代理:你 -- 代理(增强) -- 厂商.

代理类: 目标类:被代理的.

动态代理使用前提:必须有接口.

Object proxyObj= Proxy.newProxyInstance(参数1,参数2,参数3);

参数1:ClassLoader,负责将动态创建类,加载到内存。当前类.class.getClassLoader();

参数2:Class[] interfaces ,代理类需要实现的所有接口(确定方法),被代理类实例.getClass().getInterfaces();

参数3:InvocationHandler, 请求处理类,代理类不具有任何功能,代理类的每一个方法执行时,调用处理类invoke方法。

voke(Object proxy ,Method ,Object[] args)

                   参数1:代理实例

                   参数2:当前执行的方法

                   参数3:方法实际参数。

 

废话不说先看一段代码:

 

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Daili {

    @Test
    public void Demo01() {
        List<String> list = new ArrayList<>();
        list.add("a");
        System.out.println(list);
        List<String> list2 = Collections.unmodifiableList(list);
        list2.add("b"); // 错误提示,不允许操作  因为Collections工具类使得list2变得不能增删改了,只能查询
        System.out.println(list2);
    }
}

输出的结果:

 

结果是有异常的,因为Collections工具类已经把list变成了list2且list2只能查询不能增删改了.

接下来我们用代理自己手动实现这个功能,也就是我们自己增强功能:

 

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Daili {

    @Test
    public void Demo02() {
        List<String> list = new ArrayList<>();
        list.add("a");
        List<String> list2 = MyCollections.unmodifiableList(list);
        list2.add("b"); 
        System.out.println(list2.size());
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class MyCollections {
    public static List<String> unmodifiableList(final List<String> list) {

        // list 增删改查功能都有,这是目标类 我们现在进行不能增

        // 参数1:ClassLoader ,动态代理需要一个类加载器
        ClassLoader classLoader = MyCollections.class.getClassLoader();

        // 参数2:Class[] interfaces 需要与目标类接口保持一致
        Class[] interfaces = list.getClass().getInterfaces();

        //proxyList 希望不能进行增删改,只能查询  (代理类)
        List<String> proxyList = (List<String>) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 处理(增强) -- 不允许添加
                String methodName = method.getName();
                if ("add".equals(methodName)) {
                    throw new UnsupportedOperationException("不允许添加");
                }
                return method.invoke(list,args);
            }
        });
        return proxyList;
    }
}

输出结果:

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值