zoukankan      html  css  js  c++  java
  • JAVA代理方式使用示例总结

    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 com.lilin.maven.service;
    
    /**
     * @author lilin
     * 
     */
    public class BookFacadeProxy implements IBookFacade {
        private BookFacade bookFacade;
    
        public BookFacadeProxy(BookFacade bookFacade) {
            this.bookFacade = bookFacade;
        }
    
        @Override
        public void addBook(String name) {
            System.out.println("新增之前。。。");
            bookFacade.addBook("红楼梦");
            System.out.println("新增之后。。。");
        }
    
        @Override
        public void deleteBook() {
            System.out.println("删除之前。。。");
            bookFacade.deleteBook();
            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(new BookFacade());
          proxy.addBook("红楼梦");
          proxy.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

  • 相关阅读:
    居敬持志
    测试内容
    TestMarkDown
    git
    面试题
    兼容的可视区高度和宽度
    JS(数据类型、预解析、闭包、作用域、this)
    JavaScript new 一个构造函数
    Windows下gm打水印老是报gm convert: Unable to read font (n019003l.pfb)问题
    如何开始一个vue+webpack项目
  • 原文地址:https://www.cnblogs.com/lilin0719/p/5323296.html
Copyright © 2011-2022 走看看