“动态代理、CGLIB 与 切面编程”的版本间差异
跳到导航
跳到搜索
无编辑摘要 |
(→CGLIB) |
||
第22行: | 第22行: | ||
== CGLIB == | == CGLIB == | ||
CGLIB是一个功能强大,高性能的代码生成包。 | |||
* 使用CGLib实现动态代理,完全'''不受代理类必须实现接口的限制'''; | |||
* CGLib底层采用ASM字节码生成框架,使用'''字节码技术生成代理类''',比使用Java反射效率要高。 | |||
=== 原理 === | |||
# 动态生成一个要'''代理类的子类''',子类重写要代理的类的所有不是final的方法。 | |||
# 在子类中采用'''方法拦截'''的技术,拦截所有父类方法的调用,并织入横切逻辑。 | |||
* 为没有实现接口的类提供代理,比于JDK动态代理(只能代理接口)更加强大; | |||
* 不能代理final方法; | |||
=== CGLIB组成结构 === | |||
:[[File:CGLIB组成结构.png|400px]] | |||
CGLIB底层使用了'''ASM'''(一个短小精悍的字节码操作框架)来操作字节码生成新的类。 | |||
* 因为使用字节码技术生成代理类,所以CGLIB比java反射的JDK动态代理更快; | |||
* 关于“ASM”: | |||
** 除了CGLIB库外,脚本语言(如:“Groovy”、“BeanShell”)也使用ASM生成字节码; | |||
** ASM使用类似SAX的解析器来实现高性能; | |||
**(如果直接使用ASM,需要对Java字节码非常了解) | |||
=== jar包 === | |||
* “cglib-nodep-2.2.jar”:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类. | |||
* “cglib-2.2.jar”:使用此jar包需要关联asm的jar包,否则运行时报错. | |||
=== 类库 === | |||
CGLIB类库: | |||
* “net.sf.cglib.core”:底层字节码处理类,他们大部分与ASM有关系; | |||
* “net.sf.cglib.transform”:编译期或运行期类和类文件的转换; | |||
* “net.sf.cglib.proxy”:实现创建代理和方法拦截器的类; | |||
* “net.sf.cglib.reflect”:实现快速反射和C#风格代理的类; | |||
* “net.sf.cglib.util”:集合排序等工具类; | |||
* “net.sf.cglib.beans”:JavaBean相关的工具类; | |||
=== 常用的API === | |||
{| class="wikitable" | |||
! 命令 !! 说明 !! 示例 | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|- | |||
| | |||
| | |||
| | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
|} | |||
<syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
=== 使用 === | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
public class TargetObject { | |||
public String method1(String paramName) { | |||
return paramName; | |||
} | |||
public int method2(int count) { | |||
return count; | |||
} | |||
public int method3(int count) { | |||
return count; | |||
} | |||
@Override | |||
public String toString() { | |||
return "TargetObject []"+ getClass(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> | |||
# | |||
#: <syntaxhighlight lang="java"> | |||
</syntaxhighlight> |
2020年10月29日 (四) 01:39的版本
关于代理
代理,简单说就是:不直接操作对象,而使用代理对象来完成操作;
- 通过代理对象,可以对原对象进行方法扩展;
代理又可以分为
- 静态代理:通过聚合、继承的方式生成代理对象;
- 代理关系在编译时就确定了
- 动态代理:
- 运行期动态生成代理对象;
- Java动态代理:(针对实现了接口的类)
- CGLIB:(针对没有实现接口的类)
- AspectJ:(springframework的aop基于此实现)
Java动态代理
AspectJ
- 参见:Spring:AOP
CGLIB
CGLIB是一个功能强大,高性能的代码生成包。
- 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制;
- CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。
原理
- 动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。
- 在子类中采用方法拦截的技术,拦截所有父类方法的调用,并织入横切逻辑。
- 为没有实现接口的类提供代理,比于JDK动态代理(只能代理接口)更加强大;
- 不能代理final方法;
CGLIB组成结构
CGLIB底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。
- 因为使用字节码技术生成代理类,所以CGLIB比java反射的JDK动态代理更快;
- 关于“ASM”:
- 除了CGLIB库外,脚本语言(如:“Groovy”、“BeanShell”)也使用ASM生成字节码;
- ASM使用类似SAX的解析器来实现高性能;
- (如果直接使用ASM,需要对Java字节码非常了解)
jar包
- “cglib-nodep-2.2.jar”:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类.
- “cglib-2.2.jar”:使用此jar包需要关联asm的jar包,否则运行时报错.
类库
CGLIB类库:
- “net.sf.cglib.core”:底层字节码处理类,他们大部分与ASM有关系;
- “net.sf.cglib.transform”:编译期或运行期类和类文件的转换;
- “net.sf.cglib.proxy”:实现创建代理和方法拦截器的类;
- “net.sf.cglib.reflect”:实现快速反射和C#风格代理的类;
- “net.sf.cglib.util”:集合排序等工具类;
- “net.sf.cglib.beans”:JavaBean相关的工具类;
常用的API
命令 | 说明 | 示例 |
---|---|---|
使用
-
public class TargetObject { public String method1(String paramName) { return paramName; } public int method2(int count) { return count; } public int method3(int count) { return count; } @Override public String toString() { return "TargetObject []"+ getClass(); } }