首页 > 其他分享 >jdk动态代理

jdk动态代理

时间:2023-06-29 19:57:31浏览次数:44  
标签:jdk interfaces 代理 Class loader proxy new 动态 class

一、Class.forName的作用

class c = Class.forName(“com.xxx.Example”); 返回的是一个类的实例

factory = (ExampleInterface)c.newInstance();  newInstance之前必须保证类被加载了

jvm在装载类时会执行类的静态代码段,要记住静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了,而且以后不会再执行这段静态代码了。

Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

通过过new 方式会直接加载类

 二、源码分析(参考)

 

自己实现InvocationHander接口,里边的invoke方法,实际调用目标对象的时候,前后想加啥就加啥

 

 

(1条消息) 从源码角度解读JDK动态代理_程序员李哈的博客-CSDN博客

@CallerSensitive
    public static Class<?> getProxyClass(ClassLoader loader,
                                         Class<?>... interfaces)
        throws IllegalArgumentException
    {
// 根据接口克隆一份 final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } return getProxyClass0(loader, intfs); 继续走 }

  

private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        return proxyClassCache.get(loader, interfaces); 继续走,其中get方法里边有个apply方法
    }

  

@Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
// 通过类 interfaceClass = Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != intf) { throw new IllegalArgumentException( intf + " is not visible from class loader"); } /* * Verify that the Class object actually represents an * interface. */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * Verify that this interface is not a duplicate. */ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { throw new IllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } } String proxyPkg = null; // package to define proxy class in int accessFlags = Modifier.PUBLIC | Modifier.FINAL; /* * Record the package of a non-public proxy interface so that the * proxy class will be defined in the same package. Verify that * all non-public proxy interfaces are in the same package. */ for (Class<?> intf : interfaces) { int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { accessFlags = Modifier.FINAL; String name = intf.getName(); int n = name.lastIndexOf('.'); String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); if (proxyPkg == null) { proxyPkg = pkg; } else if (!pkg.equals(proxyPkg)) { throw new IllegalArgumentException( "non-public interfaces from different packages"); } } } if (proxyPkg == null) { // if no non-public proxy interfaces, use com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } /* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement();
生成类名 String proxyName = proxyPkg + proxyClassNamePrefix + num; /* * Generate the specified proxy class. */
// 生成字节流 byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try {
生成class对象,native方法 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); } } }

  

标签:jdk,interfaces,代理,Class,loader,proxy,new,动态,class
From: https://www.cnblogs.com/xiaoroubao/p/17514894.html

相关文章

  • 代理服务器之 squid、lvs、nginx、haproxy之间的区别
    代理服务器之squid、lvs、nginx、haproxy之间的区别代理服务可简单的分为正向代理和反向代理1、正向代理正向代理服务器:squid用于代理内部网络对Internet的连接请求(如VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标Web服务器的HTTP请求先发送到代理服务器上......
  • 解决minio使用nginx代理出现问题(上传文件可以,创建桶404)
    minio使用nginx代理出现问题(上传文件可以,创建桶失败)server{listen80;#error_page500502503504404/404.html;注释掉location/{proxy_set_headerX-Forwarded-Proto$scheme;proxy_set_headerX-Real-IP$remote_addr;......
  • 动态规划十大经典案例
    动态规划十大经典案例动态规划是一种常用的算法思想,它可以解决很多优化问题,比如求最大值、最小值、最长子序列等。动态规划的基本思想是把一个复杂的问题分解成若干个子问题,然后从最简单的子问题开始,逐步推导出更大的子问题的解,最终得到原问题的解。动态规划通常需要定义一个状态......
  • ip代理的应用场景
        ip代理在许多场景中都有其应用。以下是一些常见的应用场景:    1.自动化程序:自动化程序是在网上自动浏览和获取信息的程序。但是,由于并不是所有的网站都允许无限制地访问,因此,自动化程序可能会因为访问频率过高而被封锁。在这种情况下,代理IP可以用来隐藏网络的真实IP,使......
  • leetcode动态规划-
    什么是动态规划动态规划的定义和特点动态规划的基本思想和步骤动态规划的分类和常见问题线性动态规划最长公共子序列最长递增子序列最大子数组和区间动态规划矩阵链乘法括号化问题背包动态规划0-1背包问题完全背包问题多重背包问题状态压缩动态规划......
  • 动态规划入门指南
     动态规划入门指南动态规划是一种解决复杂问题的方法,它可以将一个问题分解为若干个子问题,并利用子问题的最优解来构造原问题的最优解。动态规划适用于具有重叠子问题和最优子结构的问题,即子问题之间有相互依赖的关系,且子问题的最优解可以推导出原问题的最优解。本文将介绍动态......
  • leetcode动态规划题目总结
     ref:https://leetcode.cn/circle/article/2Xxlw3/ 这是一篇我在leetcode.com上撰写的文章DynamicProgrammingSummary,就不翻回中文了,直接copy过来了。Helloeveryone,IamaChinesenoobprogrammer.Ihavepracticedquestionsonleetcode.comfor2years.During......
  • mybatis 动态数据源核心--AbstractRoutingDataSource
    1publicabstractclassAbstractRoutingDataSourceextendsAbstractDataSourceimplementsInitializingBean{2@Nullable3privateMap<Object,Object>targetDataSources;4@Nullable5privateObjectdefaultTargetDataSource;......
  • sshhuttle 实现 子网代理功能
    首先实现讲本地流量转发远程指定的网段将本地的子网192.168.3.1/24和10.172.0.12/24转发到远程主机172.16.37.208的端口5004。远程主机必须是访问通过的主机IP实现方式[email protected]:5004192.168.3.1/2410.172.0.12/24原理使用ssh隧道将......
  • python使用隧道代理做爬虫模版
    以下是一个使用隧道代理进行爬虫的Python模板:```pythonimportrequests#设置代理服务器proxy_host="your_proxy_host"proxy_port="your_proxy_port"proxy_username="your_proxy_username"proxy_password="your_proxy_password"#设置目标网址target_url=......