首页 > 编程语言 > 详细

JAVA代理方式使用示例总结

时间:2016-03-26 17:08:05      阅读:280      评论:0      收藏:0      [点我收藏+]

JAVA代理方式使用示例总结

一、    代理方式概括

  Java的代理方式主要包含了静态代理,动态代理两种方式,其中,动态代理根据实现的方式不同,又可以划分为jdk动态代理和cglib动态代理.

二、    代理方式实现

1.    静态代理

  静态代理,主要包含两个实例,被代理类和代理类,两者都要实现公共的接口,能够面向接口实现,把被代理类组合到代理类中,在被代理类的本身功能上,加上代理类的自己的处理逻辑,达到增强的效果,就简单的实现了代理功能.静态代理只能事先编写好代理代码,经过统一编译后才能执行.下面简单的代码实现:

1.1建立公共的接口

package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public interface IBookFacade {

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void addBook(String name);

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void deleteBook();

}

1.2建立被代理类


package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class BookFacade implements IBookFacade {

    @Override
    public void addBook(String name) {
        System.out.println("增加图书!"+name);
    }

    @Override
    public void deleteBook() {
        System.out.println("删除图书!");
    }
}

1.3建立代理类

package jdkcglib.staticagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class CountProxy implements ICount {

    private Count count;

    public CountProxy(Count count) {
        this.count = count;
    }

    @Override
    public void queryCount() {
        System.out.println("查询之前。。。");
        count.queryCount();
        System.out.println("查询之后。。。");
    }

    @Override
    public void updateCount() {
        System.out.println("更新之前。。。");
        count.updateCount();
        System.out.println("更新之后。。。");

    }
}

1.4建立测试类

package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class Test {

    /**
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param args
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void main(String[] args) {
        BookFacadeProxy proxy = new BookFacadeProxy();
        IBookFacade bookProxy = (IBookFacade) proxy.bind(new BookFacade());
        bookProxy.addBook("红楼梦");
        bookProxy.deleteBook();
    }

}

2.    动态代理---jdk动态代理(InvocationHandler 接口)

  依据java的反射机制动态生成.在运行期间可以动态生成被代理类的实例.利用反射。获取托付类的类载入器。托付类的全部接口,实例化代理类。通过反射类Proxy以及InvationHandler回调接口实现的。可是动态代理类仅仅能对该类所实现的接口中的方法进行代理。具有一定的局限性,而且反射的效率也不是非常高。下面是简单的代码实现:

2.1 建立公共接口类

package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public interface IBookFacade {

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void addBook(String name);

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void deleteBook();

}

2.2 建立被代理类

package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class BookFacade implements IBookFacade {

    @Override
    public void addBook(String name) {
        System.out.println("新增加图书!"+name);
    }

    @Override
    public void deleteBook() {
        System.out.println("直接删除图书!");
    }

}

2.3 建立代理类

package jdkcglib.dynmicagent;

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

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 * 
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class BookFacadeProxy implements InvocationHandler {

    /**
     * 被代理对象
     */
    private Object target;

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉绑定被代理对象 返回代理对象
     * 
     * @param target
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public Object bind(Object target) {
        this.target = target;
        // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
        // 返回代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        if (method.getName().startsWith("delete")) {
            System.out.println("#####方法执行之前#####");
            result = method.invoke(target, args);
            System.out.println("#####方法执行之后#####");
        } else {
            result = method.invoke(target, args);
        }
        return result;
    }

}

2.4 建立测试类

package jdkcglib.dynmicagent;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class Test {

    /**
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param args
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void main(String[] args) {
        BookFacadeProxy proxy = new BookFacadeProxy();
        IBookFacade bookProxy = (IBookFacade) proxy.bind(new BookFacade());
        bookProxy.addBook("红楼梦");
        bookProxy.deleteBook();
    }
}

3.    动态代理---CGLIB动态代理(MethodInterceptor 接口)

  CGLib (Code Generation Library) 是一个强大的,高性能,高质量的Code生成类库。它能够在执行期扩展Java类与实现Java接口。不仅仅能够接管接口类的方法,同时还能够接管普通类的方法.解决了jdk代理的只能代理接口类方法的难处,CGLib 的底层是Java字节码操作框架(ASM).动态的生成被代理类的子类, 增强的代码是硬编码在新生成的类文件内部的,不会存在反射的性能问题.下面是简单的代码实现:

3.1 建立被代理类

package jdkcglib.cglib;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class BookFacade {

    public void addBook() {
        System.out.println("增加图书的普通方法...");
    }

}

3.2 建立代理类

package jdkcglib.cglib;

import java.lang.reflect.Method;

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

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
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;
    }

}

3.3  建立测试类

package jdkcglib.cglib;

import java.io.UnsupportedEncodingException;

/**
 * 
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 * 
 * @author 12061799
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class TestCglib {
    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     * 
     * @param args
     * @throws UnsupportedEncodingException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        BookFacadeCglib cglib = new BookFacadeCglib();
        BookFacade bookCglib = (BookFacade) cglib.getInstance(new BookFacade());
        bookCglib.addBook();
    }

}

三、  java代理小结

静态代理: 代理类就是通过调用被代理类的方法进行执行的,自己本身并不用清楚被代理类的方法.需要编译后执行.耦合比较紧密.

JDK动态代理: 利用反射原理,动态的生成代理类,将类的载入延迟到程序执行之中,解耦了代理类和被代理类的联系.主要要实现InvationHandler接口.

CGLIB动态代理:原理是继承,把被代理类作为父类,动态生成被代理类的子类,三个步骤,设置父类,设置回调函数,创建子类.实现MethodInterceptor 接口,拦截调用父类方法时,会处理回调方法,处理自己的增强方法.

参考:

http://www.cnblogs.com/bhlsheji/p/5316693.html

 

JAVA代理方式使用示例总结

原文:http://www.cnblogs.com/lilin0719/p/5323296.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!