文档章节

Java动态代理

bithup
 bithup
发布于 2017/11/29 16:50
字数 627
阅读 5
收藏 0

被代理的类及其实现的接口

package proxy.demo;


public interface ServiceDemo {
    /**
     * 返回姓名
     */
    void getName();

    /**
     * 返回年龄
     */
    void getAge();
}
package proxy.demo;


public class ServiceDemoImpl implements ServiceDemo {
    @Override
    public void getName() {
        System.out.println("kevin");
    }

    @Override
    public void getAge() {
        System.out.println("20");
    }
}

为ServiceDemoImpl动态创建代理类

首先编写InvocationHandler

package proxy.demo;

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


public class MyInvocationHandler implements InvocationHandler {
    private Object target;//被代理的对象,通过构造函数传入

    public MyInvocationHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
        System.out.println("before");//调用目标方法前执行的代码
        Object result = method.invoke(target, args);
        System.out.println("after");//调用目标方法后调用的代码 

        return result;
    }
}

创建代理类并调用

import proxy.demo.Demo2;
import proxy.demo.MyInvocationHandler;
import proxy.demo.ServiceDemo;
import proxy.demo.ServiceDemoImpl;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Created with IntelliJ IDEA
 *
 * @Author: bit hup
 * @Date: 11/10 0010
 * @Time: 18:17
 */
public class Demo {

    public static void main(String[] args) throws Exception {
        ServiceDemo serviceDemo = new ServiceDemoImpl();
       
        //创建InvocationHandler,注入被代理类的实例
        InvocationHandler invocationHandler = new MyInvocationHandler(serviceDemo);
        //获取代理类对象
        ServiceDemo serviceDemoProxy = (ServiceDemo) Proxy.newProxyInstance(serviceDemo.getClass().getClassLoader(),
                serviceDemo.getClass().getInterfaces(),invocationHandler);
        //将动态创建的代理类写入到磁盘class文件中,然后反编译查看生成的代码
        String path = "D://$Proxy0.class";
        byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0",serviceDemo.getClass().getInterfaces());

        FileOutputStream out = null;

        try {
            out = new FileOutputStream(path);
            out.write(classFile);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //调用代理类
        serviceDemoProxy.getName();
        serviceDemoProxy.getAge();
    }
}

生产的代理类,反编译后的代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import proxy.demo.ServiceDemo;

public final class $Proxy0 extends Proxy implements ServiceDemo {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m4;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void getName() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void getAge() throws  {
        try {
            super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m3 = Class.forName("proxy.demo.ServiceDemo").getMethod("getName", new Class[0]);
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m4 = Class.forName("proxy.demo.ServiceDemo").getMethod("getAge", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

1.静态代理三种角色
(一)抽象角色:接口或抽象类
(二)被代理角色:实现或继承抽象角色
(三)代理角色:实现或继承抽象角色,包含被代理对象的引用

© 著作权归作者所有

下一篇: Java反射笔记
bithup
粉丝 8
博文 101
码字总数 82172
作品 0
朝阳
程序员
私信 提问

暂无文章

Archiva 不小心删掉了管理员权限怎么办

Archiva 的界面和 UI 比较容易出问题。 在添加用户和为用户进行权限修改的时候,不小心连 admin 这个用户的权限都删掉了。 这个时候应该如何恢复 admin 这个用户的权限? 这个时候你可以尝试...

honeymoose
28分钟前
4
0
Java8新特性之空指针异常的克星Optional类

Java8新特性系列我们已经介绍了Stream、Lambda表达式、DateTime日期时间处理,最后以“NullPointerException” 的克星Optional类的讲解来收尾。 背景 作为开发人员每天与NullPointerExceptio...

程序新视界
40分钟前
3
0
OSChina 周四乱弹 —— 福布斯终身秃头奖

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享如是我闻的单曲《地藏经上卷》: 如是我闻#今日歌曲推荐# 《地藏经上卷》- 如是我闻 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
43分钟前
142
7
Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
今天
6
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部