jdk动态代理

动态代理·步骤:

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

package com.qcby.demo.proxyaop.proxy.jdk;

import com.qcby.demo.proxyaop.proxy.star.JiaLing;
import lombok.extern.slf4j.Slf4j;

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

/**
 * @className: AdvertisementHandler
 * @description: 广告代理类
 * @author: lxt
 * @create: 2021-05-12 15:30
 **/
@Slf4j
public class AdvertisementHandler implements InvocationHandler {

    private Object object;

    /**
     * 代理对象的逻辑:
     *      前置或后置或都增强我们的代理对象(比如aop:token验证、重复提交验证、操作日志)
     *      代替目标对象:mybatis mapper层
     */

    // 经纪人和贾玲建立关系
    public AdvertisementHandler(Object object) {
        this.object = object;
    }
    // 覆写接口的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.info("贾玲的代理正在与您沟通【广告代言】...");
//        method.invoke(object,args);
        log.info("贾玲的代理正在完成收尾【广告代言】...");
        return null;
    }
}

2.创建被代理的类以及接口
需要动态代理的接口

package com.qcby.demo.proxyaop.proxy.star;

/**
 * 广告接口
 */
public interface IAdvertisement {
    /**
     * 代言方法
     */
    void display();

    String displayRe();
}

需要动态代理·的目标对象

package com.qcby.demo.proxyaop.proxy.star;

import lombok.extern.slf4j.Slf4j;

/**
 * 贾玲
 *
 * lombok
 */
@Slf4j
public class JiaLing implements IAdvertisement {
    @Override
    public void display() {
        log.info("大家好!我是贾玲!");
    }

    @Override
    public String displayRe() {
        log.info("大家好!我是贾玲Re!");
        return "success!";
    }
}

3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理

        //因为JDK为我们生成的动态代理对象也会去实现真实对象实现了的所有的接口
        //所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
        //产生代理对象的方法
        IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(
                jiaLing.getClass().getClassLoader()
                , jiaLing.getClass().getInterfaces()
                ,advertisementHandler
        );

4.通过代理调用方法

package com.qcby.demo.proxyaop.proxy.jdk;

import com.qcby.demo.proxyaop.proxy.star.JiaLing;
import com.qcby.demo.proxyaop.proxy.star.IAdvertisement;
import sun.misc.ProxyGenerator;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;

/**
 * @className: JdkDynamicProxy
 * @description:jdk动态代理
 * @author: lxt
 * @create: 2021-05-12 15:34
 **/
public class JdkDynamicProxy {

    public static void main(String[] args) throws IOException {
        // 创建目标对象
        JiaLing jiaLing = new JiaLing();

        // 绑定贾玲和广告代理类的关系
        AdvertisementHandler advertisementHandler = new AdvertisementHandler(jiaLing);

        //因为JDK为我们生成的动态代理对象也会去实现真实对象实现了的所有的接口
        //所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
        //产生代理对象的方法
        IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(
                jiaLing.getClass().getClassLoader()
                , jiaLing.getClass().getInterfaces()
                ,advertisementHandler
        );

        //通过反编译工具可以查看源代码
         byte[]bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{IAdvertisement.class});
         // idea 打开字节码文件,可查看动态生成的代理类
        String dir = "D:/proxydemo/jdk/";
        File file = new File(dir);
        if(!file.exists()){
            file.mkdirs();
        }
         FileOutputStream os=new FileOutputStream(dir+"$Proxy0.class");
         os.write(bytes);
         os.close();

        //执行代理对象【经纪人】的display()方法
        advertisement.display();
   	 }
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值