动态代理(基于接口)

Posted lililixuefei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理(基于接口)相关的知识,希望对你有一定的参考价值。

  1. 特点:字节码随用随创建,随用随加载

  2. 作用:不修改源码的基础上对方法进行增强

  3. 分类:

    1. 基于接口的动态代理

    2. 基于类的动态代理

  4. 基于接口的动态代理:

    1. 涉及 的类:Proxy

    2. 提供者:jdk

    3. 如何创建代理对象:使用Proxy类中的newProxyInstance方法

    4. 创建代理对象的要求:被代理的类最少实现一个接口,如果没有则不能使用

    5. Proxy.newProxyInstance(), newProxyInstance方法的参数:

      1. ClassLoader :类加载器

        它是同于加载代理对象的字节码的,写的是被代理对象的类加载器。(代理谁就写谁的类加载器)

      2. Class[] : 字节码数组

        它是让代理对象和被代理对象有相同的方法

      3. InvocationHandler:用于提供增强的代码

        它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类谁用谁写

        package com.xuefei.proxy;
        
        //生产商的接口
        public interface IProducer {
            public void saleProduct(float money);
        
            public void afterProduct(float money);
        }
        package com.xuefei.proxy;
        
        //生产商实现接口
        public class Producer implements IProducer{
            public void saleProduct(float money) {
                System.out.println("拿到钱,给你商品"+money);
            }
        
            public void afterProduct(float money) {
                System.out.println("拿到钱给你售后"+money);
            }
        }
        package com.xuefei.proxy;
        
        import java.lang.reflect.InvocationHandler;
        import java.lang.reflect.Method;
        import java.lang.reflect.Proxy;
        
        public class Client {
            public static void main(String[] args) {
        
                final Producer producer = new Producer();
                IProducer proxyProducer = (IProducer)                 Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(),
                        new InvocationHandler() {
                            /**
                             * 作用:执行被代理对象的任何接口方法都会执行该方法
                             * 方法参数的含义
                             * @param proxy     代理对象的引用
                             * @param method    当前执行的方法
                             * @param args      当前执行方法所需要的参数
                             * @return          和被代理对象有相同的返回值
                             * @throws Throwable
                             */
                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                //提供增强的代码
                                Object returnValue = null;
                                //获取方法执行的参数
                                Float money = (Float)args[0];
                                //判断当前方法是不是销售
                                if("saleProduct".equals(method.getName())){
                                    returnValue = method.invoke(producer,money*0.8f);
                                }
                                return returnValue;
                            }
                        });
                proxyProducer.saleProduct(1000f);
            }
        }

        运行结果:

      4. 技术图片

以上是关于动态代理(基于接口)的主要内容,如果未能解决你的问题,请参考以下文章

java 动态代理示例,带主要注释

java-动态代理

深挖JDK动态代理

Spring aop 基于JDK动态代理和CGLIB代理的原理以及为什么JDK代理需要基于接口

Spring aop 基于JDK动态代理和CGLIB代理的原理以及为什么JDK代理需要基于接口

基于接口和基于子类的动态代理