动态代理模式原理之反射动态加载技术

本文介绍了Java中的反射机制及其用途,如调用私有方法和属性。接着讲解了代理模式,包括静态代理和动态代理,动态代理中重点讨论了JDK动态代理的实现原理,涉及到InvocationHandler接口和Proxy类。文章通过实例展示了如何创建和使用动态代理,并分析了动态代理相对于静态代理的优缺点。
摘要由CSDN通过智能技术生成

动态代理模式原理之反射动态加载技术

        Hello,大家好!我又来了,最近工作一直在忙于USB外接打印机接入速度高性能优化。从刚开始的接入到打印40s时长,极致性能优化到15s~19s时长,期间踩了不少吭最终达到理想效果。哎呀,话题扯的远了。前几天,一个小伙伴说:元哥,我在代码里老是看到 invoke() 这个方法,就是反射时候用到的,这是到底是干嘛的呀??正好我这几天在优化时,有阅读到底层源码里,用到动态代理。所以呢决定来写写,巩固一下知识,总结一下。
好啦,
在这里插入图片描述

        本文主要通过以下几个部分来写

1.什么是反射,反射的用途?

引用官方文档的原话
Reflection
        Reflection is a set of language and library features that allows for introspecting the structure of your own program at runtime.
        意思大概是说,反射是一组语言和库特性,允许在运行时反思自己程序的结构。

        读者:我嚓,你要不要这样,你这么直白的翻译,怎么一脸蒙呢。
在这里插入图片描述

        作者:哈哈哈,被你说中了。别急请听我用简单的话来讲,一切简单话

        反射,简单来讲,就是一开始并不清楚,不知道我们要去初始化的类是什么?
像平时我们在使用一个对象时,我们明确清楚要去怎么初始化对象,如:
正:val person = Person()
而我们反射呢,体现在一个“反” 上面。
反射就是在运行时才知道我们要操作的类是什么,包括获取类的构造,使用类的成员方法等等

 反射的用途
    举几个例子

  • 通过反射去调用其类的私有方法.。

  • 设计框架时为了扩展 使用反射。

  • 通过反射配合注解实现APT技术。

    。。。
    。。。 装逼,喜欢搞逼格高的代码!
    用途很多

2.反射的常用手段

        这里我们简单起见呢,首先就定义一个类,用于测试。类如下:

/**
 *  @description 描述人,用于验证反射
 *  @author 陈元
 *  @date  2020 07/14
 */
class Person {
   

    lateinit var name: String

    var age: Int = 0

    constructor()

    constructor(name: String, age: Int){
   
        this.name = name
        this.age = age
    }

    private var address = "南京市蓬莱仙岛"

    var doing = "练习反射,为动态代理的原理作准备!"

    private fun speakLanguage(name: String = "吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮") {
   
        println("南京人说:$name")
    }

    fun goodFood() {
   
        println("南京正宗桂花鸭")
    }

    fun sayAddress(){
   
        println(address)
    }

    var lambdaTest: (() -> Unit)? = null

}

        这里呢,基本我们上平时写的类的结构都有了,什么构造器呀,有参的,无参的,公开方法,私有方法,私有字段,公开字段 等等。
        我们说,一切皆对象!我们的class 也一样,也有一个专门的保存类的结构化信息的Class对象
1.获取类的Class对象,我们JDK为我们提供了三种方式。
示例:

/**
 * description: 反射初级用法
 * author: 陈元
 * data:2020/7/21
 */
fun main() {
   

    /**
     * class对象 获取方式一,通过 类的完整包名
     */
    val personClass = Class.forName("com.myapplication.Person")

    println(personClass)

    val personal = Person("刘亦菲", 18)

    /**
     * class对象 获取方式二,通过 javaClass
     */
    val personClass1 = personal.javaClass

    println(personClass1)

    /**
     * Class对象 获取方式三,通过 类名::class.java
     */
    val personClass2 = Person::class.java

    println(personClass2)

通过反射获取构造器

  /**
     * 通过反射获取Person的实例对象,无参的
     */
    val person1 = getPerson(personClass as Class<Person>)
    println(person1)

    /**
     * 通过反射获取Person的实例对象,带参数的
     */
    val person2 = getPerson1(personClass1,"周芷若",18)
    val person3 = getPerson1(personClass2,"赵敏",18)

通过反射获取方法

示例:

  /**
     * 反射获取类的方法,包括父类的方法
     */
    personClass.methods.forEach {
   
        println(it.name)
    }

    println("_____________ 疑问? 为啥打印出来没有私有方法呢??  原来需要使用declared _______________________")
    /**
   
/**
     * 反射获取类的自身的所有方法
     */
    personClass.declaredMethods.forEach {
   
        println(it.name)
    }
   

结果:

这里包括父类的wait notify 等等方法都能获取到。

getName
setName
sayAddress
getDoing
setAge
getLambdaTest
setDoing
getAge
setLambdaTest
goodFood
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
____________________________________
getName
setName
sayAddress
getDoing
speakLanguage
speakLanguage$default
setAge
getLambdaTest
setDoing
getAge
setLambdaTest
goodFood

setLambadaTest方法 哪来的??
        哎,兄弟。请看,这就是呀,在我们kotlin里面函数可以类似于前端写的ES6一样,函数声明

 var lambdaTest: (() -> Unit)? = null

        哦,这样啊。

        还可以获取属性,这里就简单提一下

 /**
     * 反射获取类的自身所有属性 成员变量
     */
    personClass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值