查看cglib动态生成的类
操作图
查看cglib动态生成的类
文本说明
/**
*
* @param cg
* @param cw
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IOException
*
* debug停在 org.springframework.cglib.core.DefaultGeneratorStrategy#generate的
* 语句 "this.transform(cg).generateClass(cw);"
* 之前 调用本方法: com.zzz.spring_boot_demo.controller.TestController.writeClassFile(cg,cw)
* 即可写入动态生成的类的.class文件
而:包路径重命名: cglib-2.2.jar: net.sf.cglib -> spring-cglib-repack-3.2.6.jar: org.springframework.cglib
可知, DefaultGeneratorStrategy#generate 原来是 : net.sf.cglib.core.DefaultGeneratorStrategy#generate
所以只需要修改 net.sf.cglib.core.DefaultGeneratorStrategy#generate 即可
*/
public static void writeClassFile(ClassGenerator cg, DebuggingClassWriter cw) throws NoSuchFieldException, IllegalAccessException, IOException {
Field classNameF =
org.springframework.cglib.core.AbstractClassGenerator.class.getDeclaredField("className");
classNameF.setAccessible(true);
String classNameV = (String) classNameF.get(cg);
try( FileOutputStream fos=new FileOutputStream("d:/tmp/"+classNameV+".class") ){
fos.write(cw.toByteArray());
}
}
所以以下进一步完善为:
cglib增加功能: 生成字节码时写出文件 并 应用到 spring-boot-demo
- cglib增加功能: 生成字节码时写出文件
cglib 3.2.6z: 动态生成class时写字节码文件到磁盘
此修改有个bug 指定的输出目录-DCglibDebugWriteClassDir=d:/tmp/不起作用 而总是输出到当前目录
#替换
cd D:\GRADLE_USER_HOME\caches\modules-2\files-2.1\cglib\cglib\3.3.0\c956b9f9708af5901e9cf05701e9b2b1c25027cc
#备份原始
mv cglib-3.3.0.jar cglib-3.3.0.jar.original
#替换:
#换成具有 功能"生成字节码时写出文件" 的cglib-3.3.0.jar:
wget -o cglib-3.3.0.jar https://gitlab.com/pubz/cglib/-/wikis/uploads/54da2a311f06b5eb505ce493e11da069/cglib-3.3.0z.jar
- spring-framework 5.2.22.RELEASE 重新编译
ls D:\spring-framework\spring-core\build\libs\
# spring-cglib-repack-3.3.0.jar , spring-core-5.2.22.RELEASE.jar 这两个文件 中的 方法 org.springframework.cglib.core.DefaultGeneratorStrategy#generate 是被修改过的
cd D:\GRADLE_USER_HOME\caches\modules-2\files-2.1\org.springframework\spring-core\5.2.22.RELEASE\e380e393a975c1b7ce7c2059d17c8a55ae52b90e\
#备份原始
mv spring-core-5.2.22.RELEASE.jar spring-core-5.2.22.RELEASE.jar.orginal
#替换
cp D:\spring-framework\spring-core\build\libs\spring-core-5.2.22.RELEASE.jar ./
- 运行 spring-boot-demo 写出 字节码文件
#
git clone https://gitlab.com/pubz/spring-boot-demo.git
cd spring-boot-demo
#编译, 此时用到了步骤2中被替换后的 spring-core-5.2.22.RELEASE.jar
gradle build
#运行, 将 写出 字节码文件
java -DCglibDebugWriteClass=true -DCglibDebugWriteClassVerbose=true -DCglibDebugWriteClassDir=d:/tmp/ -jar com.zzz.demo.SpringBootDemoApplication
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.mybatis.spring.boot.autoconfigure;
import java.lang.reflect.InvocationTargetException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration..EnhancerBySpringCGLIB..b4a6713d;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.reflect.FastClass;
import org.springframework.core.io.ResourceLoader;
public class MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$b4a6713d$$FastClassBySpringCGLIB$$fa7b3520 extends FastClass {
public BeanFactory $$beanFactory;
public MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$b4a6713d$$FastClassBySpringCGLIB$$fa7b3520(Class var1) {
super(var1);
}
public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -1870561232:
if (var10000.equals("CGLIB$findMethodProxy(Lorg/springframework/cglib/core/Signature;)Lorg/springframework/cglib/proxy/MethodProxy;")) {
return 5;
}
break;
case -1851710780:
if (var10000.equals("CGLIB$sqlSessionFactory$1(Ljavax/sql/DataSource;)Lorg/apache/ibatis/session/SqlSessionFactory;")) {
return 7;
}
break;
case -1562512836:
if (var10000.equals("sqlSessionTemplate(Lorg/apache/ibatis/session/SqlSessionFactory;)Lorg/mybatis/spring/SqlSessionTemplate;")) {
return 2;
}
break;
case -1457356942:
if (var10000.equals("CGLIB$STATICHOOK7()V")) {
return 9;
}
break;
case -1457327151:
if (var10000.equals("CGLIB$STATICHOOK8()V")) {
return 8;
}
break;
case -1349483294:
if (var10000.equals("afterPropertiesSet()V")) {
return 12;
}
break;
case -1034266769:
if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
return 4;
}
break;
case -1025895669:
if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
return 3;
}
break;
case -346084839:
if (var10000.equals("access$000()Lorg/slf4j/Logger;")) {
return 11;
}
break;
case 47263949:
if (var10000.equals("CGLIB$sqlSessionTemplate$2(Lorg/apache/ibatis/session/SqlSessionFactory;)Lorg/mybatis/spring/SqlSessionTemplate;")) {
return 6;
}
break;
case 1184504558:
if (var10000.equals("sqlSessionFactory(Ljavax/sql/DataSource;)Lorg/apache/ibatis/session/SqlSessionFactory;")) {
return 1;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return 13;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return 14;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return 15;
}
break;
case 2095635076:
if (var10000.equals("setBeanFactory(Lorg/springframework/beans/factory/BeanFactory;)V")) {
return 0;
}
break;
case 2116294234:
if (var10000.equals("CGLIB$setBeanFactory$7(Lorg/springframework/beans/factory/BeanFactory;)V")) {
return 10;
}
}
return -1;
}
public int getIndex(String var1, Class[] var2) {
switch(var1.hashCode()) {
case -1776922004:
if (var1.equals("toString")) {
switch(var2.length) {
case 0:
return 14;
}
}
break;
case -1558799614:
if (var1.equals("sqlSessionFactory")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("javax.sql.DataSource")) {
return 1;
}
}
}
break;
case -1295482945:
if (var1.equals("equals")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 13;
}
}
}
break;
case -1253747277:
if (var1.equals("afterPropertiesSet")) {
switch(var2.length) {
case 0:
return 12;
}
}
break;
case -1143506192:
if (var1.equals("access$000")) {
switch(var2.length) {
case 0:
return 11;
}
}
break;
case -1013651080:
if (var1.equals("setBeanFactory")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.springframework.beans.factory.BeanFactory")) {
return 0;
}
}
}
break;
case -369371796:
if (var1.equals("CGLIB$sqlSessionFactory$1")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("javax.sql.DataSource")) {
return 7;
}
}
}
break;
case -60403779:
if (var1.equals("CGLIB$SET_STATIC_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 4;
}
}
}
break;
case 85179481:
if (var1.equals("CGLIB$SET_THREAD_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 3;
}
}
}
break;
case 147696667:
if (var1.equals("hashCode")) {
switch(var2.length) {
case 0:
return 15;
}
}
break;
case 161998115:
if (var1.equals("CGLIB$STATICHOOK7")) {
switch(var2.length) {
case 0:
return 9;
}
}
break;
case 161998116:
if (var1.equals("CGLIB$STATICHOOK8")) {
switch(var2.length) {
case 0:
return 8;
}
}
break;
case 934816467:
if (var1.equals("CGLIB$sqlSessionTemplate$2")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.apache.ibatis.session.SqlSessionFactory")) {
return 6;
}
}
}
break;
case 1154623345:
if (var1.equals("CGLIB$findMethodProxy")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.springframework.cglib.core.Signature")) {
return 5;
}
}
}
break;
case 1383899522:
if (var1.equals("sqlSessionTemplate")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.apache.ibatis.session.SqlSessionFactory")) {
return 2;
}
}
}
break;
case 1418553038:
if (var1.equals("CGLIB$setBeanFactory$7")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.springframework.beans.factory.BeanFactory")) {
return 10;
}
}
}
}
return -1;
}
public int getIndex(Class[] var1) {
switch(var1.length) {
case 8:
if (var1[0].getName().equals("org.mybatis.spring.boot.autoconfigure.MybatisProperties") && var1[1].getName().equals("org.springframework.beans.factory.ObjectProvider") && var1[2].getName().equals("org.springframework.beans.factory.ObjectProvider") && var1[3].getName().equals("org.springframework.beans.factory.ObjectProvider") && var1[4].getName().equals("org.springframework.core.io.ResourceLoader") && var1[5].getName().equals("org.springframework.beans.factory.ObjectProvider") && var1[6].getName().equals("org.springframework.beans.factory.ObjectProvider") && var1[7].getName().equals("org.springframework.beans.factory.ObjectProvider")) {
return 0;
}
default:
return -1;
}
}
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
b4a6713d var10000 = (b4a6713d)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
var10000.setBeanFactory((BeanFactory)var3[0]);
return null;
case 1:
return var10000.sqlSessionFactory((DataSource)var3[0]);
case 2:
return var10000.sqlSessionTemplate((SqlSessionFactory)var3[0]);
case 3:
b4a6713d.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
return null;
case 4:
b4a6713d.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
return null;
case 5:
return b4a6713d.CGLIB$findMethodProxy((Signature)var3[0]);
case 6:
return var10000.CGLIB$sqlSessionTemplate$2((SqlSessionFactory)var3[0]);
case 7:
return var10000.CGLIB$sqlSessionFactory$1((DataSource)var3[0]);
case 8:
b4a6713d.CGLIB$STATICHOOK8();
return null;
case 9:
b4a6713d.CGLIB$STATICHOOK7();
return null;
case 10:
var10000.CGLIB$setBeanFactory$7((BeanFactory)var3[0]);
return null;
case 11:
return MybatisAutoConfiguration.access$000();
case 12:
var10000.afterPropertiesSet();
return null;
case 13:
return new Boolean(var10000.equals(var3[0]));
case 14:
return var10000.toString();
case 15:
return new Integer(var10000.hashCode());
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
b4a6713d var10000 = new b4a6713d;
b4a6713d var10001 = var10000;
int var10002 = var1;
try {
switch(var10002) {
case 0:
var10001.<init>((MybatisProperties)var2[0], (ObjectProvider)var2[1], (ObjectProvider)var2[2], (ObjectProvider)var2[3], (ResourceLoader)var2[4], (ObjectProvider)var2[5], (ObjectProvider)var2[6], (ObjectProvider)var2[7]);
return var10000;
}
} catch (Throwable var3) {
throw new InvocationTargetException(var3);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 15;
}
}