转载请注明链接:https://blog.csdn.net/feather_wch/article/details/51721514
讲解编程语言的分类(什么是静态类型,动态类型,强类型和弱类型预研),介绍动态代理和反射机制,动态代理方面介绍JDK提供的动态代理,以及通过cglib等高效的字节码操作机制实现的动态代理。
动态代理
版本: 2018/09/07-1(18:00)
问题汇总
- 编程语言分类所用到的动态类型和静态类型是指什么?
- 编程语言分类所用到的强类型和弱类型是什么?
- 运行时检查的语言是属于什么类型的?
- 编译期检查的语言属于什么类型的?
- 不同类型的变量进行赋值时,需要显式进行类型转换的语言,是什么类型的语言?
- 不同类型的变量进行赋值时,不需显式进行类型转换的语言,是什么类型的语言?
哪些语言是动态类型语言?
JavaScript、Python
哪些语言是静态类型语言?
Java、C、C++、Kotlin
哪些语言是弱类型语言?
C、C++、PHP、JavaScript
哪些语言是强类型语言?
Java、Kotlin
反射机制是什么?
- 通过反射机制能干什么?
- AccessibleObject.setAccessible(bolean flag)的作用
- Java9中的setAccessible
- 动态代理是什么?有什么作用?
- 动态代理和静态代理的区别
- 动态代理的三要素
- 动态代理的应用场景
- 动态代理解决了什么问题?在具体业务中有哪些应用场景?
- 动态代理的实现方法?
- JDK动态代理在设计和实现上与cglib等方式有什么不同?
- JDK Proxy比cglib和Javassist慢几十倍?
- JDK Proxy和cglib如何进行取舍?
- JDK动态代理的实例
- JDK Proxy的作用
- JDK Proxy的缺点
- JDK Prxoy的优势
- cglib框架的优势
- 面向切面编程AOP是什么?
- 字节码操作机制是什么?
- ASM是什么?Javasist是什么?
语言分类(3)
1、编程语言的分类?2、Java语言是什么类型的语言?
- 动态类型和静态类型
- 动态类型:运行时检查
- 静态类型:编译期检查
- 强类型和弱类型。
- 强类型: 不同类型变量赋值时,需要显式的强制地进行
类型转换
- 弱类型:不同类型变量赋值时,不需要显式的
类型转换
3、哪些语言是动态类型、静态类型、强类型、弱类型?
- Java是静态的强类型的语言,但是因为具有反射机制,因此也具有部分动态类型语言的能力。
Java | Kotlin | C | C++ | JavaScript | Pyhton | Ruby | C# | PHP |
---|---|---|---|---|---|---|---|---|
动态类型 | ★ | ★ | ★ | |||||
静态类型 | ★ | ★ | ★ | ★ | ★ | |||
强类型 | ★ | ★ | ★ | ★ | ★ | |||
弱类型 | ★ | ★ | ★ |
反射机制()
1、反射机制是什么?2、通过反射机制能干什么?
- Java语言提供的基础功能
- 赋予程序在运行时自省(introspect)的能力
- 能够让Java灵活地操作运行时才能确定的信息。
3、AccessibleObject.setAccessible(bolean flag)的作用可以直接操作类或者对象:
1. 获取对象的类
1. 获取类声明的属性和方法
1. 调用方法
1. 构造对象
1. 在运行时修改类定义。
4、Java9中的setAccessible
- 可以在运行时修改成员访问限制。
- 比如去绕开一些API的限制。
- Java 9以后,Jigsaw项目新增的模块化系统,会对反射进行限制。并提出了Open的概念。
- 被反射操作的模块 以及 指定的包 需要对反射调用者模块是Open的,才能调用
setAccessible
- Java 9暂时保留和兼容了Java 8的行为,但以后可能会出现变化。
- 可以同参数显式设置,setAccessible是否可以使用。
--illegal-access={permit | warn | deny}
动态代理
1、动态代理是什么?有什么作用?2、动态代理和静态代理的区别
- 一种方便运行时动态构建代理、动态处理代理方法调用的机制
- 一种广泛应用于产品开发中的技术。
- 通过
动态代理
能优雅的解决繁琐的重复编程- 通过代理可以让
调用者
和实现者
解耦。
3、动态代理的三要素
- 静态代理:在编译阶段就知道需要代理哪一个对象。
- 动态代理:运行时才知道要代理哪一个对象
4、动态代理的应用场景
- 抽象类接口
- 被代理类:具体实现抽象接口
- 动态代理类:实际调用被代理类的方法和属性的类。需要实现InvocationHandler
5、动态代理解决了什么问题?在具体业务中有哪些应用场景?
- 包装RPC调用(Remote Programe Call—远程程序调用)
- 面向切面的编程(AOP)
- 框架内部的寻址、序列化、反序列化
6、动态代理的实现方法?
- 解决了调用者和实现者,
耦合度过高
的问题。- 进行RPC调用,Android中的AIDL、Binder
- 框架内部的寻址、序列化、反序列化等内容,与调用者解耦。
7、JDK动态代理在设计和实现上与cglib等方式有什么不同?
- JDK自身提供的动态代理:主要就是利用了反射机制。
JDK Proxy
- 利用字节码操作机制:性能更高,类似
ASM、cglib(基于ASM)、Javasist
等。
8、JDK Proxy比cglib和Javassist慢几十倍?
- JDK Proxy: 使用反射和部分字节码操作来实现。
- cglib使用字节码操作机制来实现。
9、JDK Proxy和cglib如何进行取舍?并没有这么大的差距。
1. 主流JDK版本中,JDK Proxy在大部分场景可以提供对等的性能水平。
1. 反射机制性能在现代JDK中,已经进行了极大的改进和优化。已经没有过高的性能损耗。
1. 此外JDK很多功能也不全是反射,也采用了ASM
进行字节码操作。
- 性能并不是唯一的标准,
- 可靠性、可维护性、工作量也是重要的因素。
- 可靠性上: 推荐JDK Proxy
- 编码工作量、性能上:推荐cglib
JDK Proxy
10、JDK动态代理的实例public class Main {
// 抽象类接口
public interface Animal {
void cry();
}
// 被代理类:具体实现抽象接口
public static class Dog implements Animal {
@Override
public void cry() {
System.out.println("汪汪!");
}
}
// 动态代理类:实际调用被代理类的方法和属性的类。需要实现InvocationHandler
static 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("invoking cry()");
Object result = method.invoke(target, args);
return result;
}
}
public static void main(String[] args) {
// 1. 创建被代理者
Dog dog = new Dog();
// 2. 实例化Handler: 用于插入额外的逻辑
MyInvocationHandler handler = new MyInvocationHandler(dog);
// 3. 构造代理,实例化的是Proxy对象。
Animal animal = (Animal) Proxy.newProxyInstance(Dog.class.getClassLoader(),
Dog.class.getInterfaces(),
handler);
// 4. 调用代理方法
animal.cry();
}
}
11、JDK Proxy的作用
12、JDK Proxy的缺点
- 使用代理模式,能通过代理去间接执行目标的逻辑。
- 此外使用代理,能够在执行被代理者的逻辑之间,去添加额外的逻辑。
13、JDK Prxoy的优势
- 被调用者(如Dog)必须要去实现被代理的接口(如Animal)
- 如果被调用者,没有实现接口,就无法使用JDK Proxy了,这时候可以使用
cglib
- 最小化依赖关系。减少依赖意味着简化开发和维护。
- 兼容性强:会随着JDK版本进行升级。但是字节码类库通常需要更新,以保证在新版Java上能够使用。
- 代码实现简单。
cglib
14、cglib框架的优势
- 侵入性低。cglib动态代理不需要调用者实现接口。
- 更专注。只操作关心的类,不需要额外工作量。
- 高性能
知识扩展
1、面向切面编程AOP是什么?2、字节码操作机制是什么? 3、ASM是什么?Javasist是什么?
- AOP是OOP的一种补充。
- 比如在一种场景中:业务A,业务B,业务C都有日志、安全等功能。但是A、B、C的日志可以统一进行处理,安全部分可以采用通用的安全策略、
- AOP通过动态代理机制,大幅度提高了代码的抽象程度和复用度。减少繁琐的工作量。
Facade、Observer
等设计模式都可以通过动态代理进行优雅的实现。