您的位置:首页 > 编程语言 > Java开发

java 动态代理的两种方式(jdk,cglib)

2013-10-11 13:55 621 查看
动态代理 
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。 
动态代理示例: 
1、BookFacade.java 

Java代码  

package net.battier.dao;  

  

public interface BookFacade {  

    public void addBook();  

}  

 
2、BookFacadeImpl.java 

Java代码  

package net.battier.dao.impl;  

  

import net.battier.dao.BookFacade;  

  

public class BookFacadeImpl implements BookFacade {  

  

    @Override  

    public void addBook() {  

        System.out.println("增加图书方法。。。");  

    }  

  

}  

  

、BookFacadeProxy.java  

  

package net.battier.proxy;  

  

import java.lang.reflect.InvocationHandler;  

import java.lang.reflect.Method;  

import java.lang.reflect.Proxy;  

  

/** 

 * JDK动态代理代理类 

 *  

 * @author student 

 *  

 */  

public class BookFacadeProxy implements InvocationHandler {  

    private Object target;  

    /** 

     * 绑定委托对象并返回一个代理类 

     * @param target 

     * @return 

     */  

    public Object bind(Object target) {  

        this.target = target;  

        //取得代理对象  

        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  

                target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)  

    }  

  

    @Override  

    /** 

     * 调用方法 

     */  

    public Object invoke(Object proxy, Method method, Object[] args)  

            throws Throwable {  

        Object result=null;  

        System.out.println("事物开始");  

        //执行方法  

        result=method.invoke(target, args);  

        System.out.println("事物结束");  

        return result;  

    }  

  

}  

 
3、TestProxy.java 

Java代码  

package net.battier.test;  

  

import net.battier.dao.BookFacade;  

import net.battier.dao.impl.BookFacadeImpl;  

import net.battier.proxy.BookFacadeProxy;  

  

public class TestProxy {  

  

    public static void main(String[] args) {  

        BookFacadeProxy proxy = new BookFacadeProxy();  

        BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  

        bookProxy.addBook();  

    }  

  

}  

 
但是,JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。 
Cglib动态代理 
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 
示例 
1、BookFacadeCglib.java 

Java代码  

package net.battier.dao;  

  

public interface BookFacade {  

    public void addBook();  

}  

 
2、BookCadeImpl1.java 

Java代码  

package net.battier.dao.impl;  

  

/** 

 * 这个是没有实现接口的实现类 

 *  

 * @author student 

 *  

 */  

public class BookFacadeImpl1 {  

    public void addBook() {  

        System.out.println("增加图书的普通方法...");  

    }  

}  

3、BookFacadeProxy.java 

Java代码  

package net.battier.proxy;  

  

import java.lang.reflect.Method;  

  

import net.sf.cglib.proxy.Enhancer;  

import net.sf.cglib.proxy.MethodInterceptor;  

import net.sf.cglib.proxy.MethodProxy;  

  

/** 

 * 使用cglib动态代理 

 *  

 * @author student 

 *  

 */  

public class BookFacadeCglib implements MethodInterceptor {  

    private Object target;  

  

    /** 

     * 创建代理对象 

     *  

     * @param target 

     * @return 

     */  

    public Object getInstance(Object target) {  

        this.target = target;  

        Enhancer enhancer = new Enhancer();  

        enhancer.setSuperclass(this.target.getClass());  

        // 回调方法  

        enhancer.setCallback(this);  

        // 创建代理对象  

        return enhancer.create();  

    }  

  

    @Override  

    // 回调方法  

    public Object intercept(Object obj, Method method, Object[] args,  

            MethodProxy proxy) throws Throwable {  

        System.out.println("事物开始");  

        proxy.invokeSuper(obj, args);  

        System.out.println("事物结束");  

        return null;  

  

  

    }  

  

}  

4、TestCglib.java 

Java代码  

package net.battier.test;  

  

import net.battier.dao.impl.BookFacadeImpl1;  

import net.battier.proxy.BookFacadeCglib;  

  

public class TestCglib {  

      

    public static void main(String[] args) {  

        BookFacadeCglib cglib=new BookFacadeCglib();  

        BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  

        bookCglib.addBook();  

    }  

}  

 

java动态代理(JDK和cglib)

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: