JDK动态代理与CGLIB动态代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rap_libai/article/details/79020041

一、JDK动态代理

被代理的实现类:

public interface Helloworld {
    public void sayHelloworld();
}
public class HelloWorldImpl implements Helloworld {
    @Override
    public void sayHelloWorld(){
        System.out.println("Hello World!");
    }
}

实现java.lang.reflect.InvocationHandler接口,它里面定义了一个invoke方法,并提供接口数组用于下挂代理对象代码如下:

public class JdkProxyExample implements InvocationHandler {
    //真实对象
    private Object target = null;
    public Object bind(Object target){
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("进入代理逻辑方法");
        System.out.println("在调度真实对象之间的服务");
        Object obj = method.invoke(target,args);//相当于调用sayHelloWorld
        System.out.println("在调度真实对象之后的服务");
        return obj;
    }
}

第一步,建立代理对象和真实对象的关系。这里用了bind方法来实现

newProxyInstance方法的3个参数:

  • 第一个是类加载器,用了target本身的类加载器
  • 第二个是把生成的动态代理对象下挂在哪些接口下
  • 第三个是定义实现方法的逻辑代理类,this指当前对象,他必须实现invoke方法

第二步,实现代理逻辑方法,invoke方法
invoke的3个参数:
  • proxy,代理对象,就是bind生成的对象
  • method,当前调度的方法
  • args,调度方法的参数
测试JDK动态代理:
    public void testJdkProxy(){
        JdkProxyExample jdk = new JdkProxyExample();
        HelloWorld proxy = (HelloWorld)jdk.bind(new HelloWorldImpl());
        proxy.sayHelloWorld();
    }
运行结果
进入代理逻辑方法
在调度真实对象之间的服务
Hello World!
在调度真实对象之后的服务
二、CGLIB动态代理
JDK动态代理必须提供接口才能使用,在一些不能提供接口的环境中药使用第三方技术,如CGLIB动态代理。它的优势在于不需要提供接口,只要一个非抽象类就能实现动态代理。
被代理类:
public class HelloWorldImpl{


    public void sayHelloWorld(String name){
        System.out.println("Hello" + name);
    }
}
代理类:
public class CglibProxyExample implements MethodInterceptor {
      @Override
     public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("调用真实对象前");
                 //CGLIB反射调用真实对象方法
                Object result = methodProxy.invokeSuper(proxy, args);
                 System.out.println("调用真实对象后");
                return result;
             }

    public Object getProxy(Class<?> cls){
             //CGLIB enhancer 增强类对象
             Enhancer enhancer = new Enhancer();
            //设置增强类型
             enhancer.setSuperclass(cls);
            //定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
             enhancer.setCallback(this);
             //生成并返回代理对象
           return enhancer.create();
        
            }
}
这里用了CGLIB的加强者Enhancer,通过设置超类方法(setUperclass),然后通过setCallback方法设置哪个类为他的代理类。其中this引用了intercept,然后返回代理对象。
测试:
CglibProxyExample cpe = new CglibProxyExample();
HelloWorldImpl obj = (HelloWorldImpl) cpe.getProxy(HelloWorldImpl.class);//获得代理对象
obj.sayHello("张三");//调用逻辑处理方法
结果:
调用真实对象前
Hello 张三
调用真实对象后





猜你喜欢

转载自blog.csdn.net/rap_libai/article/details/79020041