快捷搜索: 王者荣耀 脱发

简单理解jdk的动态代理

1. 静态代理

静态代理其实就是我们的装饰者设计模式,首先定义一个接口类,然后定义这个接口类的实现类,对每一个实现类定义一个代理类,这里面代理类里面传入这个实现类的引用。

1.1 接口类

public interface PersonInterface {
    void say();
}

1.2 实现类

public class Students implements PersonInterface{

@Override
public void say() {
    System.out.println("会说英语");
}
}

1.3 代理类

public class StudentProxy implements PersonInterface{
    private Students students = new Students();
    @Override
    public void say() {
        System.out.println("111");
        students.say();
        System.out.println("222");
    }
}

1.4 测试类

public static void main(String[] args){
        PersonInterface students = new StudentProxy();
        students.say();
    }

2. 动态代理

动态代理就是程序在运行期间,通过反射机制来实现对原始类的代理。首先定义一个接口类,在定义一个接口类的实现类,然后定义一个代理类。

2.1 接口类

public interface PersonInterface {
    void say();
}

2.2 实现类

public class Persons {

    public void say() {
        System.out.println("会说英语");
    }

}

2.3 代理类

public class Proxys implements InvocationHandler {
    private Object object;

    public Proxys(Object object){
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("3333");
        method.invoke(object,args);
        System.out.println("4444");
        return null;
    }
}

这个动态代理类主要是实现InvocationHandler接口,定义构造方法,里面用来传入代理类的对象,里面的invoke方法有三个参数,分别是proxy,method,args[] ,它们主要对应代理对象,真实对象的方法,真实对象方法的参数。

2.4 测试类

public static void main(String[] args){
    Students students = new Students();
    InvocationHandler proxys = new Proxys(students);
    PersonInterface p =(PersonInterface)Proxy.newProxyInstance(students.getClass().getClassLoader(),students.getClass().getInterfaces(),proxys);
    p.say();
}

3. 比较静态代理和动态代理和cglib代理

3.1 静态代理主要是一个实现类对应一个代理类,这样的话,如果实现类比较多的话,那么它将产生许多代理类,是面向接口编程,在编译已经产生与之对应的代理类。

3.2 动态代理使用接口编程,它的优点就是,很多个实现类可以用一个代理类,主要采用反射技术在运行期对实现类进行代理

3.3 cglib主要是因为jdk动态代理必须实现对应的接口,所以cglib就来解决没有接口时的代理,主要是通过字节码技术来实现代理,定义一个类,这个类就是父类被代理的类,然后cglib通过字节码技术生成一个子类,通过子类来完成对里面方法的增强,所以这就需要父类不能用final进行修饰。

3.4 什么时候用cglib代理?什么使用jdk动态代理?

如果是单例类的话,就使用cglib代理,不用产生很多的类,如果产生很多对象时,就是用jdk动态代理,cglib的性能比jdk代理的性能高

经验分享 程序员 微信小程序 职场和发展