美文网首页
代理设计模式

代理设计模式

作者: kanaSki | 来源:发表于2019-08-14 19:45 被阅读0次

代理设计模式:
1.真实对象
2.代理对象
3.抽象对象(抽象功能)

代理设计模式优点:
1.保护真实对象
2.让真实对象职责更明确
3.扩展

静态代理:
由代理对象代理所有真实对象的功能,需要自己编写代理类,每个代理的功能需要单独编写。

真实对象:

package com;

public class President implements Gongneng {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public President(String name) {
        this.name = name;
    }

    public void talk() {
        System.out.println("talk");
    }
}

代理对象:

package com;

public class StaticProxy implements Gongneng {
    private President president = new President("pre");

    @Override
    public void talk() {
        System.out.println("proxy talk");
        president.talk();
    }
}

抽象接口:

package com;

public interface Gongneng {
    public void talk();
}

Test类:

package com;

public class TestDemo {
    public static void main(String[] args) {
        StaticProxy proxy = new StaticProxy();
        proxy.talk();
    }
}

静态代理缺点:当代理功能比较多时,代理类中方法需要写很多。

动态代理:
为解决静态代理需要频繁编写代理功能方法的缺点。
分类:JDK、CGLIB

JDK动态代理:
与CGLIB动态代理对比:
1.优点:JDK自带,不需要导入额外jar包
2.缺点:真实对象必须实现接口;采用反射机制,效率比较低

代理类:(相当于处理程序)

package com;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyOb implements InvocationHandler {
    private ProxyedMain proxyedMain = new ProxyedMain();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("预约时间");
        Object result = method.invoke(proxyedMain, args);
        return result;
    }
}

真实对象类:

package com;

public class ProxyedMain implements Gongneng {
    @Override
    public void chifan() {
        System.out.println("吃饭");
    }

    @Override
    public void mubiao() {
        System.out.println("目标");
    }
}

程序会根据接口创建一个对象,之后当调用该对象的方法时会调用invoke方法(即处理程序)。

package com;

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        // 三个参数分别代表类加载器,实现接口,处理程序,返回代理对象
        Gongneng gongneng = (Gongneng) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Gongneng.class}, new ProxyOb());
        gongneng.chifan();
    }
}

Proxy.newProxyInstance中第一个参数表示反射时使用的类加载器,第二个参数表示Proxy需要实现什么接口,第三个参数表示通过接口调用方法时,需要调用哪个类的invoke方法

CGLIB动态代理:
优点:基于字节码,生成真实对象的子类,运行效率高于JDK,不需要实现接口
缺点:第三方非JDK功能,需要额外导入jar包

导入jar
package com;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ProxyOb implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("预约时间");
//        invoke调用子类重写方法
//        method.invoke(o,objects);
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        return invokeSuper;
    }
}
package com;

import net.sf.cglib.proxy.Enhancer;

public class Test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ProxyedMain.class);
        enhancer.setCallback(new ProxyOb());
        ProxyedMain o = (ProxyedMain) enhancer.create();
        o.chifan();
    }
}

相关文章

网友评论

      本文标题:代理设计模式

      本文链接:https://www.haomeiwen.com/subject/dgmijctx.html