设计模式之代理模式

代理模式:
代理模式:有代理类与委托类组成,两者有相同的接口.其中代理类主要负责为委托类预处理消息、过滤消息并把消息转发给委托类,以及事后处理消息等。
使用的目的:采用代理模式可以有效的将具体的实现与调用方进行解耦,通过面向接口进行编码完全将具体的实现隐藏在内部

静态代理的缺点:
1)代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法.这样就出现了大量的代码重复.造成代码冗余臃肿.
2)代理对象只能服务于一种类型的对象,如果要服务多种类型的对象.势必要为每一种对象都进行代理.

静态代理和动态代理的区别,什么场景使用? 

http://blog.csdn.net/mine_song/article/details/71373305?locationNum=15&fps=1

静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了.
动态代理类:在程序运行时,运用反射机制动态创建而成.
动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类.
静态代理与动态代理的区别:
(1)静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类.
(2)静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道.(动态代理需要在运行时因需实时创建)
(3)动态代理实现JDK的InvocationHandler接口的invoke方法,但注意的是代理的是接口,也就是你的业务类必须要实现接口,通过Proxy里的newProxyInstance得到代理对象.

动态代理的相关类和接口:
1.java.lang.reflect.Proxy:动态代理机制的主类,其提供了一组静态方法为一组接口(委托类)动态的生成对象和代理类
//用于获取特定代理对象所关联的调用处理器
1.1)public static InvocationHandler getInvocationHandler(Object proxy);
//用于获取关联特定类加载器和一组接口(委托类)的动态代理类的类对象
1.2)public static Class<?> getProxyClass(ClassLoader loader,Class<?> ... interface);
//用于判断特定类对象是否是一个动态代理类
1.3)public static boolean isProxyClass(Class<?> cl);
//获取特定类加载器、一组接口及调用处理器生成动态代理类的实例对象
1.4)public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);

2.java.lang.reflect.InvocationHandler:调用处理器接口,实现自定义invoke()方法,用于实现对于真正委托类的代理访问.

public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;

3.java.lang.ClassLoader:类加载器,将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用.Proxy类与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中.每次生成动态代理类对象时都需要指定一个类装载器对象:newProxyInstance()方法第一个参数

Java动态代理的两种实现方法:
jdk动态代理和cglib动态代理
其中jdk动态代理为interface接口代理;cglib动态代理是类代理;

动态代理的实现步骤:
1.先获取ClassLoader类加载器和Interface在虚拟机内的二进制字节码Class实例;
2.借助Proxy.newInstance(ClassLoader,Class<?>{...} clazz,InvocationHandler handler);方法构建代理类的实例,并实现InvocationHandler里面的invoke(object,args);方法来达到实现Interface接口里面需要代理的方法的目的;
3.运用反射的机制,通过第二步的代理对象,来调用Interface中相应的方法;
demo如下:
 //1.拿到类加载器以及接口的Class实例
ClassLoader classLoader = IEate.class.getClassLoader();

//2.构建代理对象并实现invoke方法
IEate eat = (IEate) Proxy.newProxyInstance(classLoader, new Class[]{IEate.class}, new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("eat")) {
    return args[0];
}
return method.invoke(proxy, args);
    }
});

//3.调用第二步的代理对象
System.out.println(eat.eat("蜀国"));

文章参考:

1.  java动态代理原理及解析
2.  Java动态代理的两种实现方法


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值