动态代理--JDK-cglib

基于子类的动态代理(代理普通的java类)

 TODO 动态代理
      特点:字节码随用随创建 随用随加载
    作用:是在不修改源码的基础上增强
    分类:
      基于接口的动态代理
      基于子类的动态代理
    基于子类的动态代理:
        涉及的类:Enhancer
        提供者 :第三方cglib库
    如何创建代理对象:
        使用Enhancer类中的create方法
    创建代理对象的要求:
         被代理的类不能是最终类
    create方法的参数:
         Class:字节码
            它用于指定被代理对象的字节码
         Callback:用于提供增强的代码
              它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
               此接口的实现类都是谁用谁写。
               我们一般写的都是该接口的子接口实现类:MethodInterceptor
<!--基于子类的动态代理--> 依赖
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>


public class Producer_Son  {

    public void salesProduct(float money) {
        System.out.println("销售产品,并且拿到钱 "+money);
    }

    public void afterSalesService(float money) {
        System.out.println("提供服务,并且拿到钱 "+money);
    }
}
public class Client {

    public static void main(String[] args) {
        // 加载到常量池
        final Producer_Son producer =new Producer_Son();
        
 Producer_Son o = (Producer_Son) Enhancer.create(producer.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //1.提供增强的方法
                Object returnValue = null;
                //2.获取方法执行的参数
                Float money = (Float) args[0];
                //3.判断当前方法是不是销售
                if ("salesProduct".equals(method.getName()))
                    returnValue = method.invoke(producer, money * 0.8f);
                System.out.println(returnValue);
                return returnValue;
            }
        });

        o.salesProduct(1000f);
    }
}

基于接口的动态代理

TODO 动态代理
    特点:字节码随用随创建 随用随加载
    作用:是在不修改源码的基础上增强
    分类:
      基于接口的动态代理
      基于子类的动态代理(代理普通的java类)
    基于接口的动态代理;
      涉及的类:proxy
       提供者:JDK官方
    如何创建代理对象:
     使用Proxy类中的 newProxyInstance 方法
    创建代理对象的要求:
      被代理类最少实现一个接口 如果没有则不能使用
    newProxyInstance 方法的参数:
        ClassLoader loader :类加载器
            它是用于加载代理对象字节码的 和被代理对象使用相同的类加载器
        Class<?>[] interfaces: 字节码数组
            它是用于代理对象[接口]和被代理对象[一个类]有相同方法
        InvocationHandler:用于提供增强的代码
        他是让我们如何写代理。 我们一般都是写一个该接口的实现类 ;通常情况下是匿名内部类 但不是必须的
            此接口的实现类都是谁用谁写

Producer

/*
生产者
 */
public interface Producer {

    /*
    销售产品
     */
    void salesProduct(float money);

    /*
    售后服务
     */
    void afterSalesService(float money);
}

Agency

/*
经销商 提供 销售 售后服务
 */
public class Agency implements Producer{
    @Override
    public void salesProduct(float money) {
        System.out.println("销售产品,并且拿到钱 "+money);
    }

    @Override
    public void afterSalesService(float money) {
        System.out.println("提供服务,并且拿到钱 "+money);
    }
}

Client

/*
动态代理
 */
public class Client {

    public static void main(String[] args) {
        // 加载到常量池 (匿名内部类)
        final Agency agency = new Agency();
		Producer proxyInstance = (Producer) Proxy.newProxyInstance(agency.getClass().getClassLoader(), agency.getClass().getInterfaces(), new InvocationHandler() {
            /***
             * 作用:执行被代理对象的任何接口方法都会经过该方法
             * @param proxy 代理对象的引用
             * @param method 当前执行的方法
             * @param args   当前执行方法所需要的参数
             * @return   和被代理对象方法相同的返回值
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 提供增强方法
                Object returnValue = null;
                Float money = (Float) args[0];
                if ("salesProduct".equals(method.getName()))
                    returnValue = method.invoke(agency, money * 0.8f);
                System.out.println(returnValue);
                return returnValue;
            }
        });
        
        proxyInstance.salesProduct(10000f);
        
		}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值