2_2_2_JDK动态代理_Cglib动态代理

JDK动态代理实现

  • 1)创建一个接口:HelloWorld

package agency.jdk;

public interface HelloWorld {
    void sayHelloWorld();
}

 

  • 2)继承并实现接口中的方法:HelloWorldImpl

package agency.jdk;

public class HelloWorldImpl implements HelloWorld{

    @Override
    public void sayHelloWorld() {
        System.out.println("Hello World !!");
    }
    
}

 

  • 3)创建一个类并实现InvocationHandler接口

package agency.jdk;

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

public class JdkProxyExample implements InvocationHandler{

    //真实对象
    private Object target = null;
    
    /**
     * 建立代理对象和真实对象的代理关系,并返回代理对象
     * @param: target 真实对象
     * @return:代理对象

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);

  • 第一个参数:类加载器
  • 第二个参数:把动理对象挂在哪个接口下
  • 第三个参数:定义实现方法逻辑的代理类,this代表当前对象,它必须实现InvocationHandler接口的invoke方法,它就是代理逻辑方法的现实方法

    }
    /**
     * @param proxy:代理对象
     * @param method:当前调度方法
     * @param args:当前方法参数
     * @return 代理结果返回
     * @throws Throwable:异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("进入代理逻辑方法");
        System.out.println("在调度真实对象之前的服务");
        Object obj = method.invoke(target,args);
        System.out.println("在调度真实对象之后的服务");
        return obj;
    }

}
 

  • 4)创建一个测试类

package agency.jdk;

public class TestJdkProxy {
    
    public static void main(String[] args) {
        JdkProxyExample jpe = new JdkProxyExample();
        //绑定关系,因为挂在接口HelloWorld下,所以声明代理对象HelloWorld proxy
        HelloWorld Hproxy = (HelloWorld) jpe.bind(new HelloWorldImpl());
        //注意,此时HelloWorld对象已经是一个代理对象了,它会进入代理的逻辑方法invoke里
        Hproxy.sayHelloWorld();
    }
    
}

 

Cglib动态代理

  • 1)准备jar包
    • asm-3.3.1.jar
    • asm-commons-6.0.jar
    • asm-util-3.3.1.jar
    • cglib-nodep-3.2.5.jar
  • 2)创建一个真实对象

package agency.cglibdemo;

public class ReflectServiceImpl {

    public void sayHello(String str) {
        System.out.println("Hello "+str);
    }
}

 

  • 3)创建类并继承MethodInterceptor接口

package agency.cglibdemo;

import java.lang.reflect.Method;

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

public class CglibProxyExample implements MethodInterceptor{
    
    /**
     * 生成Cglib代理对象
     * @param cls-Class类
     * @return Class类的CGLIB代理对象
     */
    public Object getProxy(Class cls) {
        //设置CGLIB enhancer 增强类对象
        Enhancer enhancer = new Enhancer();
        //设置增强类型
        enhancer.setSuperclass(cls);
        //生成代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
        enhancer.setCallback(this);
        //生成并返回代理对象
        return enhancer.create();
    }

    /**
     * @param    proxy 代理对象
     * @param    method 方法
     * @param    args 方法参数
     * @param    methodProxy方法代理
     * @return    代理逻辑返回
     * @throws    Throwable 异常
     */
    @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;
    }

}

  • 4)创建测试类

package agency.cglibdemo;

public class TestCglibProxy {

    public static void main(String[] args) {
        CglibProxyExample cpe = new
                CglibProxyExample();
        ReflectServiceImpl obj = (ReflectServiceImpl) 
                cpe.getProxy(ReflectServiceImpl.class);
        obj.sayHello("张三");
    }
}

 

JDK动态代理与Cglib的区别

  • 前者是JDK自带的,后者是第三方提供的(在Sping中不需要自己导入jar包)
  • 前者需要提供一个接口,后者不用
  • 在sping中
    • 如果目标对象实现了接口,默认情况下使用jdk动态代理
    • 如果目标对象实现了接口,可以强制使用Cglib
    • 如果目标对象没有实现接口,默认情况下使用Cglib

猜你喜欢

转载自blog.csdn.net/weixin_41640994/article/details/82383871
今日推荐