jdk动态代理和cglib动态代理的案例

代理

jdk动态代理
/**
 * jdk动态代理
 * @author Administrator
 *
 */

public class JDKProxyDemo {

    private Object target;//目标类

    public JDKProxyDemo(Object target){
        this.target=target;
    }
    /**
     * 创建代理类方法
     * @param target
     * @return
     */
    public Object createProxyObject(){

        ClassLoader loader=target.getClass().getClassLoader();//目标类类加载器
        Class[] interfaces=target.getClass().getInterfaces();//目标类所实现的所有接口
        InvocationHandler h=new InvocationHandler() {   
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("jdkProxyDemo");
                Object obj = method.invoke(target, args);//对原始操作进行调用(反射)
                return obj;
            }
        };
        Object object = Proxy.newProxyInstance(loader, interfaces, h);
        return object;

    }   
}
cglib动态代理

/**
 * cglib代理案例
 * @author Administrator
 *
 */
public class CglibProxyDemo {

    private Object target;//目标类

    public CglibProxyDemo(Object target){
        this.target=target;
    }

    public Object createProxyObject(){

        //1.创建内存中的动态类   Enhancer
        //内存中造出一个没有名称的动态类
        Enhancer enhancer=new Enhancer();
        //2.现在的类最终完成目标类的功能,同时对其进行功能的增强,必须先具有目标类对应的功能————继承
        enhancer.setSuperclass(target.getClass());
        ////3.进行功能的增强
        //设置了方法的调用拦截
        //设置具体的回调操作
        Callback callback = new MethodInterceptor() {
            //proxy:代理对象
            //method:被拦截的方法对象
            //args:调用参数
            //methodProxy:
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("cglib");

                //Object obj=method.invoke(proxy, args);//这种执行是代理类的方法,而不是目标类的,会造成内存溢出
                //以下的两种都是执行目标类的方法
                //Object obj = methodProxy.invokeSuper(proxy, args);//执行目标类的方法
                Object obj=method.invoke(target, args);


                return obj;
            }

        };

        enhancer.setCallback(callback);
        return enhancer.create();   
    }
}
1.jdk动态代理和cglib动态代理的区别

jdk:先有实现接口的类的对象,然后对对象进行代理
cglib:只要有类(无论是否实现接口),对类做代理,简单来说就是对指定的类生成一个子类,覆盖其中的方法(继承)

2.jdk动态代理和cglib动态代理在spring中

(1)当Bean实现接口时,Spring默认使用jdk动态代理
(2)当Bean没有实现接口时,Spring使用cglib动态代理
(3)如果Bean实现接口,也可以强制使用cglib动态代理(在spring配置中加入 `)

3.注意

使用cglib实现动态代理,cglib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,cglib不能对声明为final的方法进行代理,因为cglib原理是动态生成被代理类的子类(被final修饰的类不能被继承)。

你可能感兴趣的:(设计模式)