动态代理常用的有两种方式

一、JDK代理

public class Client {
public static void main(String[] args) {

    final Product product = new Product();

    /**
     * 动态代理:
     *      特点:字节码随用随创建,随用随加载
     *      作用: 不修改源代码的基础上对方法进行增强
     *
     * 分类:
     *      基于接口的动态代理(一个是实现)
     *      基于子类的动态代理(一个是继承)
     * 基于接口的动态代理:
     *      涉及的类:proxy
     *      提供方:JDK官方
     * 怎么样创建代理对象:
     *      使用proxy类中的newProxyInstance
     *
     * 创建代理对象的要求“
     *      被代理类最少要实现一个接口,如果没有则不能使用
     *
     * newProxyInstance方法的参数:
     *      ClassLoader:类加载器(被代理对象)
     *          作用:用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法
     *      Class[]:字节码数组
     *          作用:用于让代理对象和被代理对象有相同方法。固定写法。
     *      InvocationHandler:用于提供增强的代码
     *
     */

    ProductInterface proxyProduct = (ProductInterface) Proxy.newProxyInstance(product.getClass().getClassLoader(),
            product.getClass().getInterfaces(),
            new InvocationHandler() {
                /**
                 * 作用:执行被代理对象实现接口的所有方法都会经过invoke()方法
                 *
                 * @param proxy  被代理对象
                 * @param method 当前执行的方法
                 * @param args   当前执行方法所需的参数
                 * @return       和被代理对象方法有相同的返回值
                 * @throws Throwable
                 */
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //提供增强的代码

                    Object returnValue = null;

                    //1.获取方法执行的参数
                    Float money = (Float) args[0];
                    if("saleProduct".equals( method.getName())){
                        returnValue = method.invoke(product, money * 0.8f);
                    }
                    return returnValue;
                }
            });

    proxyProduct.saleProduct(1000);

}

}

二、Cglib代理

public class Client {
public static void main(String[] args) {

    final Producer producer = new Producer();

    /**
     * 动态代理:
     *      特点:字节码随用随创建,随用随加载
     *      作用: 不修改源代码的基础上对方法进行增强
     *
     * 分类:
     *      基于接口的动态代理
     *      基于子类的动态代理
     * 基于接口的动态代理:
     *      涉及的类:Enhancer
     *      提供方:cglib第三方包
     * 怎么样创建代理对象:
     *      使用Enhancer中的create()方法
     *
     * 创建代理对象的要求“
     *      被代理类不是最终类,因为不是最终类才有子类才能被代理
     *
     * create方法的参数
     *      Class:字节码
     *          它是用于指定被代理对象的字节码。
     *
     *      Callback:用于提供增强的代码
     *          我们一般写的都是该接口的子接口实现类:MethodInterceptor
     *
     */
    Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
        /**
         * 执行北地阿里对象的任何方法都会经过该方法
         * @param proxy
         * @param method
         * @param args
         *    以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
         * @param methodProxy :当前执行方法的代理对象
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            //提供增强的代码
            Object returnValue = null;

            //1.获取方法执行的参数
            Float money = (Float)args[0];
            //2.判断当前方法是不是销售
            if("saleProduct".equals(method.getName())) {
                returnValue = method.invoke(producer, money*0.8f);
            }
            return returnValue;
        }
    });
    cglibProducer.saleProduct(1000f);
      }
  }
posted @ 2020-07-13 18:58  jock_javaEE  阅读(406)  评论(0编辑  收藏  举报