spring笔记6-AOP前置笔记代理的API

动态代理


    特点:字节码随用随创建,随用随加载
    作用:不修改源码的基础上对方法增强
    分类:①基于接口的动态代理 ②基于子类的动态代理


基于接口的动态代理:


    涉及的类:Proxy
    提供者:JDK官方


如创建基于接口的代理对象


    使用Proxy类中的Object  newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法


创建代理对象的要求


    被代理类最少实现一个接口,如果没有不能使用


newProxyInstance的三个参数

  •     ClassLoader loader : 用于加载被代理对象的字节码,和被代理对象使用相同的类加载器,固定写法((对象名称.getClass().getClassLoader())
  •     Class<?>[] interfaces :字节码数据,让代理对象和被代理对象由相同的方法,固定写法(对象.getClass().getInterfaces())
  •     InvocationHandler h :写如何代理,一般是这个对象接口的实现类,通常情况下都是匿名内部类,但不是必须的,谁要增强谁写

    

InvocationHandler的作用、参数和返回值

    作用:执行被代理对象的任何接口方法都会经过该方法
    @param proxy 代理对象的引用
    @param method 当前执行方法
    @param args 当前执行方法需要的参数
    @return 和被代理对象有相同的返回值
    @throws Throwable

代码示例

1.创建Producer 的接口和实现类
/**
 * 一个生产者
 */
public interface IProducer {

    /**
     * 销售
     * @param money 钱
     */
    public void saleProduct(float money);

    /**
     * 售后
     * @param money 钱
     */
    public void afterService(float money);
}
/**
 * 一个生产者
 */
public class Producer implements IProducer{

    /**
     * 销售
     * @param money 钱
     */
    public void saleProduct(float money){
        System.out.println("销售产品并拿到钱"+money);
    }

    /**
     * 售后
     * @param money 钱
     */
    public void afterService(float money){
        System.out.println("提供售后服务并拿到钱"+money);
    }
}
 2.代理方法演示
public class ClientByInterface {
    public static void main(String[] args) {
        Producer producer = new Producer();
        //创建producer对象的代理对象,使用 Proxy.newProxyInstance 方法
        IProducer proxProducer = (IProducer)Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), new InvocationHandler() {
            //使用 new InvocationHandler() 匿名内部类增强方法
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object returnVale = null;
                //提供增强的方法
                //1.获取方法执行的参数
                float money = (float) args[0];
                //2.判断方法是不是销售
                if ("saleProduct".equals(method.getName())) {
                    //执行增强,并接收返回值
                    returnVale = method.invoke(producer,money*0.8F);
                }
                return returnVale;
            }
        });
        //使用代理对象调用被代理对象的类方法
        proxProducer.saleProduct(10000F);
    }
}

package org.example.proxy;

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

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

public class ClientBySon {
    public static void main(String[] args) {
        Producer producer = new Producer();
        /**
         *动态代理:
         * 特点:字节码随用随创建,随用随加载
         * 作用:不修改源码的基础上对方法增强
         * 分类:①基于接口的动态代理 ②基于子类的动态代理
         * 基于接口的动态代理:
         *  涉及的类:Enhancer
         *  提供者:第三方类库cglib
         *      jar包坐标
         *      <dependency>
         *             <groupId>cglib</groupId>
         *             <artifactId>cglib</artifactId>
         *             <version>2.1_3</version>
         *      </dependency>
         *  如何创建代理对象:
         *      使用Enhancer类中的 void create(Class[] argumentTypes, Object[] arguments) 方法
         *  创建代理对象的要求:
         *      被代理类不能是最终类
         *  Class[] argumentTypes的两个参数
         *      Class[] argumentTypes :
         *          字节码数组,指定被代理的对象
         *      Object[] arguments :
         *          用于提供增强的代码,一般是这个对象接口的实现类,通常情况下都是匿名内部类,但不是必须的,谁要增强谁写
         */
        Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
            /**
             * @param o 代理对象的引用
             * @param method 当前执行方法
             * @param objects 当前执行方法需要的参数
             * @param methodProxy 当前执行方法的代理对象
             * @return 和被代理对象有相同的返回值
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object returnVale = null;
                //提供增强的方法
                //1.获取方法执行的参数
                float money = (float) objects[0];
                //2.判断方法是不是销售
                if ("saleProduct".equals(method.getName())) {
                    //执行增强,并接收返回值
                    returnVale = method.invoke(producer, money * 0.8F);
                }
                return returnVale;
            }
        });
        cglibProducer.saleProduct(1000F);
    }
}

 基于子类的动态代理:


    涉及的类:Enhancer
    提供者:第三方类库cglib

jar包坐标:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.1_3</version>
</dependency>


如创建基于子类的代理对象


    使用Enhancer类中的 void create(Class[] argumentTypes, Object[] arguments) 方法


创建代理对象的要求


    被代理类不能是最终类

Class[] argumentTypes的两个参数

  •  Class[] argumentTypes :字节码数组,指定被代理的对象
  • Object[] arguments :用于提供增强的代码,一般是这个对象接口的实现类,通常情况下都是匿名内部类,但不是必须的,谁要增强谁写

    

InvocationHandler的作用、参数和返回值

    作用:执行被代理对象的任何接口方法都会经过该方法 

    @param o 代理对象的引用
    @param method 当前执行方法
    @param objects 当前执行方法需要的参数
    @param methodProxy 当前执行方法的代理对象
    @return 和被代理对象有相同的返回值
    @throws Throwable

代码示例

1.创建Producer 类
/**
 * 一个生产者
 */
public class Producer implements IProducer{

    /**
     * 销售
     * @param money 钱
     */
    public void saleProduct(float money){
        System.out.println("销售产品并拿到钱"+money);
    }

    /**
     * 售后
     * @param money 钱
     */
    public void afterService(float money){
        System.out.println("提供售后服务并拿到钱"+money);
    }
}
 2.代理方法演示
public class ClientBySon {
    public static void main(String[] args) {

        Producer producer = new Producer();
        //创建producer对象的代理对象,使用 Enhancer.create 方法
        Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(),
                new MethodInterceptor() {
            //使用 new MethodInterceptor() 匿名内部类增强方法
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object returnVale = null;
                //提供增强的方法
                //1.获取方法执行的参数
                float money = (float) objects[0];
                //2.判断方法是不是销售
                if ("saleProduct".equals(method.getName())) {
                    //执行增强,并接收返回值
                    returnVale = method.invoke(producer, money * 0.8F);
                }
                return returnVale;
            }
        });
        cglibProducer.saleProduct(1000F);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值