java反射の动态代理与静态代理

来源:互联网 发布:网络特产商城行业分析 编辑:程序博客网 时间:2024/05/17 15:37

静态代理弊端:

之前博客中有讲静态代理机制的,特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理

 

最好可以通过一个代理类完成全部代理功能

动态代理

定义

动态代理是指客户通过代理类来调用其他对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。

使用场合

调试

远程方法调用

代理设计模式的原理

使用一个代理将对象包装起来(对象成为代理类属性),然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理,代理对象决定是否以及何时将方法调用转到原始对象上

 

3.动态代理--反射的应用,体会反射的动态性

静态代理:

要求被代理类和代理类同时实现相应的一套接口;

通过被代理类的对象调用重写接口的方法时,直接上执行的是被代理类的同样的方法调用

动态代理:

反射的动态性

在程序运行时根据被代理类及其实现的接口,动态的创建一个代理类,当调用代理类实现的抽象方法时,就发起对被代理类方法的调用。

技术点

实现了InvocationHandler接口实现类,并重写invoke()方法

Proxy.newInstance(obj.getClass.getClassLoader,obj.getClass().getInterfaces(),h);    obj是被代理类的对象h是实现了InvocationHandler接口实现类的对象

package myNetDemo;//静态代理模式//接口interface ClothesFactory {void productCloth();}// 被代理类class NikeClothFactory implements ClothesFactory {@Overridepublic void productCloth() {System.out.println("Nike工厂生产衣服");}}// 代理类class ProxyFactory implements ClothesFactory {ClothesFactory cf;// 虽然声明的是总接口,但实例化时实际传进去的是具体被代理实现类// 在构造器内完成初始化public ProxyFactory(ClothesFactory cf) {this.cf = cf;}@Overridepublic void productCloth() {System.out.println("代理类开始执行,收代理费");cf.productCloth();// 实际调用的是实际被代理类的实现方法}}public class TestProductClothes {public static void main(String[] args) {NikeClothFactory nikeClothFactory = new NikeClothFactory();// 创建被代理类的对象ProxyFactory pFactory = new ProxyFactory(nikeClothFactory);// 创建爱你代理类的对象pFactory.productCloth();// 实际调用的是被代理类方法// 若再有一个接口,还要在于一个接口的实现类(被代理类,目标类),在造一个代理类实现接口// 于是想要动态代理}}

package myNetDemo;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//动态代理的使用//反射式动态语言的关键,不在编译的时候,而是在运行的时候动态的创建被代理类interface Subject {void action();}// 被代理类class RealSubject implements Subject {@Overridepublic void action() {System.out.println("我是被代理类");}}// 凡是与动态代理相关的必须要实现这个接口,实现这个接口的抽象方法class MyInvocationHandler implements InvocationHandler {Object obj;// 实现了接口的被代理类的对象的声明// 方法有两个作用①创建代理类时初始化被代理类对象②返回一个代理类对象// ①给被代理类的对象实例化②返回一个代理类的对象public Object blind(Object object) {this.obj = object;// ②返回一个代理类的对象()return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(), this);// h第三个参数,指的是实现了InvocationHandler接口的对象}// 当通过代理类的对象发起对被重写的方法的调用时,都对转化为对如下的invoke方法的调用@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// 抽象方法的返回值,method方法的返回值.返回定义抽象接口的对象Object returnVal = method.invoke(obj, args);return returnVal;}}public class TestProxy {public static void main(String[] args) {//被代理类的对象RealSubject real=new RealSubject();//创建一个实现了InvacationHandler接口的对象MyInvocationHandler handler=new MyInvocationHandler();//调用blind方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象Object obj=handler.blind(real);//返回定义接口的对象Subject sub=(Subject)obj;//此时的sub就是代理类的对象sub.action();//转到对InvacationHandler实现类的invoke方法的调用//在举一例NikeClothFactory nike=new NikeClothFactory();ClothesFactory proxyCloth=(ClothesFactory)handler.blind(nike);//proxyCloth即为代理类的对象proxyCloth.productCloth();}}

0 0
原创粉丝点击