其他分享
首页 > 其他分享> > 2021-10-02

2021-10-02

作者:互联网

代理模式详解

	在学习spring的时候发现spring的aop底层用的就是代理模式,JDK,CGLIB代理方式,研究了一下,总结一下自己的理解。
	代理模式分为静态代理和动态代理,核心思想就是在原有的方法上做出增强,而aop正好切合了这个思想,就借用代理模式进行实现。
	静态代理是在编译期间就需要完成的,编译完成了之后程序就已经知道了你的代理对象是谁,这样一旦代理对象很多的话,就会造成代码冗余不好维护。
package model;

interface Speaker{
    void speak();
}
class ZhangShan implements Speaker{
    @Override
    public void speak() {
        System.out.println("我老婆打我!");
    }
}
class Lawyer implements Speaker{
    private ZhangShan zhangShan;

    public Lawyer(ZhangShan zhangShan) {
        this.zhangShan = zhangShan;
    }

    @Override
    public void speak() {
        System.out.println("法律条文!");
        zhangShan.speak();
        System.out.println("道德批判!");
    }
}

public class ProXY {
    public static void main(String[] args) {
        Speaker speaker=new Lawyer(new ZhangShan());
        speaker.speak();
    }
}

这里layer通过实现相同的speaker接口,注入张三,代替张三进行speak,曾强了张三的speak方法。但是要是出现李四,王五怎么办,每个人都写一个代理对象吗?太复杂了!
可以用动态代理,在运行区才会知道你代理的对象是谁。

package model;

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

interface Speaker{
    void speak();
}
class ZhangShan implements Speaker{
    @Override
    public void speak() {
        System.out.println("我老婆打我!");
    }
}
class Lawyer implements Speaker{
    private ZhangShan zhangShan;

    public Lawyer(ZhangShan zhangShan) {
        this.zhangShan = zhangShan;
    }

    @Override
    public void speak() {
        System.out.println("法律条文!");
        zhangShan.speak();
        System.out.println("道德批判!");
    }
}
class LawyerProxy implements InvocationHandler{
    private Object obj;

    public LawyerProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(method.getName().equals("speak")){
            System.out.println("法律条文!");
            method.invoke(obj,args);
            System.out.println("道德批判!");
        }
        return null;
    }
}

public class ProXY {
    public static void main(String[] args) {
        //静态
        Speaker speaker=new Lawyer(new ZhangShan());
        speaker.speak();
        //动态
        LawyerProxy lawyerProxy=new LawyerProxy(new ZhangShan());
        Speaker speaker1= (Speaker) Proxy.newProxyInstance(ProXY.class.getClassLoader(),new Class[]{Speaker.class},lawyerProxy);
        speaker1.speak();
    }
}

动态代理实现JDK提供的InvocationHandler接口,重写方法,从字节码层面拿到需要的数据,就不会像静态代理一样写死了,后面用proxy.newProxyInstance方法创建接口的实现类。
但是以上都是基于接口实现的代理,要是没有接口怎么办呢?
用CGLIB,他的对JDK的一个补充,不要求实现接口。
CGLIB的方式和JDK代码几乎相同,就不做演示。

标签:02,10,ZhangShan,zhangShan,代理,Speaker,2021,public,speak
来源: https://blog.csdn.net/wanabe3/article/details/120584865