Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
阿啄debugIT
transmittable-thread-local
提交
92370c53
T
transmittable-thread-local
项目概览
阿啄debugIT
/
transmittable-thread-local
与 Fork 源项目一致
从无法访问的项目Fork
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
transmittable-thread-local
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
92370c53
编写于
6月 18, 2018
作者:
oldratlee
🔥
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
split TtlTransformer to JavassistTransformlet
上级
acae77ef
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
215 addition
and
128 deletion
+215
-128
src/main/java/com/alibaba/ttl/threadpool/agent/JavassistTransformlet.java
...m/alibaba/ttl/threadpool/agent/JavassistTransformlet.java
+19
-0
src/main/java/com/alibaba/ttl/threadpool/agent/TtlAgent.java
src/main/java/com/alibaba/ttl/threadpool/agent/TtlAgent.java
+19
-6
src/main/java/com/alibaba/ttl/threadpool/agent/TtlTransformer.java
...java/com/alibaba/ttl/threadpool/agent/TtlTransformer.java
+26
-122
src/main/java/com/alibaba/ttl/threadpool/agent/transformlet/TtlExecutorTransformlet.java
...hreadpool/agent/transformlet/TtlExecutorTransformlet.java
+82
-0
src/main/java/com/alibaba/ttl/threadpool/agent/transformlet/TtlForkJoinTransformlet.java
...hreadpool/agent/transformlet/TtlForkJoinTransformlet.java
+69
-0
未找到文件。
src/main/java/com/alibaba/ttl/threadpool/agent/JavassistTransformlet.java
0 → 100644
浏览文件 @
92370c53
package
com.alibaba.ttl.threadpool.agent
;
import
javassist.CannotCompileException
;
import
javassist.CtClass
;
import
javassist.NotFoundException
;
import
java.io.IOException
;
/**
* TTL {@code Transformlet} by {@code Javassist}.
*
* @author Jerry Lee (oldratlee at gmail dot com)
* @since 2.5.1
*/
public
interface
JavassistTransformlet
{
boolean
needTransform
(
String
className
);
void
doTransform
(
CtClass
clazz
)
throws
NotFoundException
,
CannotCompileException
,
IOException
;
}
src/main/java/com/alibaba/ttl/threadpool/agent/TtlAgent.java
浏览文件 @
92370c53
package
com.alibaba.ttl.threadpool.agent
;
import
com.alibaba.ttl.threadpool.agent.transformlet.TtlExecutorTransformlet
;
import
com.alibaba.ttl.threadpool.agent.transformlet.TtlForkJoinTransformlet
;
import
java.lang.instrument.ClassFileTransformer
;
import
java.lang.instrument.Instrumentation
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
...
...
@@ -21,13 +25,22 @@ public final class TtlAgent {
}
public
static
void
premain
(
String
agentArgs
,
Instrumentation
inst
)
{
logger
.
info
(
"[TtlAgent.premain] begin, agentArgs: "
+
agentArgs
+
", Instrumentation: "
+
inst
);
try
{
ClassFileTransformer
transformer
=
new
TtlTransformer
();
inst
.
addTransformer
(
transformer
,
true
);
logger
.
info
(
"[TtlAgent.premain] addTransformer "
+
transformer
.
getClass
()
+
" success"
);
logger
.
info
(
"[TtlAgent.premain] begin, agentArgs: "
+
agentArgs
+
", Instrumentation: "
+
inst
);
logger
.
info
(
"[TtlAgent.premain] end"
);
}
@SuppressWarnings
(
"unchecked"
)
ClassFileTransformer
transformer
=
new
TtlTransformer
(
TtlExecutorTransformlet
.
class
,
TtlForkJoinTransformlet
.
class
);
inst
.
addTransformer
(
transformer
,
true
);
logger
.
info
(
"[TtlAgent.premain] addTransformer "
+
transformer
.
getClass
()
+
" success"
);
logger
.
info
(
"[TtlAgent.premain] end"
);
}
catch
(
Exception
e
)
{
String
msg
=
"Fail to load TtlAgent , cause: "
+
e
.
toString
();
if
(
logger
.
isLoggable
(
Level
.
SEVERE
))
{
logger
.
log
(
Level
.
SEVERE
,
msg
,
e
);
}
throw
new
IllegalStateException
(
msg
,
e
);
}
}
}
src/main/java/com/alibaba/ttl/threadpool/agent/TtlTransformer.java
浏览文件 @
92370c53
package
com.alibaba.ttl.threadpool.agent
;
import
com.alibaba.ttl.TtlCallable
;
import
com.alibaba.ttl.TtlRunnable
;
import
javassist.
*
;
import
javassist.ClassPool
;
import
javassist.CtClass
;
import
javassist.
LoaderClassPath
;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.lang.instrument.ClassFileTransformer
;
import
java.lang.reflect.Modifier
;
import
java.security.ProtectionDomain
;
import
java.util.
HashSe
t
;
import
java.util.
Se
t
;
import
java.util.
ArrayLis
t
;
import
java.util.
Lis
t
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
...
...
@@ -18,40 +17,29 @@ import java.util.logging.Logger;
* TTL {@link ClassFileTransformer} of Java Agent
*
* @author Jerry Lee (oldratlee at gmail dot com)
* @author wuwen5 (wuwen.55 at aliyun dot com)
* @see java.util.concurrent.Executor
* @see java.util.concurrent.ExecutorService
* @see java.util.concurrent.ThreadPoolExecutor
* @see java.util.concurrent.ScheduledThreadPoolExecutor
* @see java.util.concurrent.Executors
* @since 0.9.0
*/
public
class
TtlTransformer
implements
ClassFileTransformer
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
TtlTransformer
.
class
.
getName
());
private
static
final
String
TTL_RUNNABLE_CLASS_NAME
=
TtlRunnable
.
class
.
getName
();
private
static
final
String
TTL_CALLABLE_CLASS_NAME
=
TtlCallable
.
class
.
getName
();
private
static
final
byte
[]
EMPTY_BYTE_ARRAY
=
{};
private
static
final
String
RUNNABLE_CLASS_NAME
=
"java.lang.Runnable"
;
private
static
final
String
CALLABLE_CLASS_NAME
=
"java.util.concurrent.Callable"
;
private
static
final
String
TIMER_TASK_CLASS_NAME
=
"java.util.TimerTask"
;
@SuppressWarnings
(
"unchecked"
)
final
List
<
JavassistTransformlet
>
transformletList
=
new
ArrayList
();
private
static
Set
<
String
>
EXECUTOR_CLASS_NAMES
=
new
HashSet
<
String
>();
@SuppressWarnings
(
"unchecked"
)
public
TtlTransformer
(
Class
<?
extends
JavassistTransformlet
>...
transformletClasses
)
throws
Exception
{
for
(
Class
<?
extends
JavassistTransformlet
>
transformletClass
:
transformletClasses
)
{
final
JavassistTransformlet
transformlet
=
transformletClass
.
getConstructor
().
newInstance
();
transformletList
.
add
(
transformlet
);
static
{
EXECUTOR_CLASS_NAMES
.
add
(
"java.util.concurrent.ThreadPoolExecutor"
);
EXECUTOR_CLASS_NAMES
.
add
(
"java.util.concurrent.ScheduledThreadPoolExecutor"
);
logger
.
info
(
"[TtlTransformer] add Transformlet "
+
transformletClass
+
" success"
);
}
}
private
static
final
String
FORK_JOIN_TASK_CLASS_NAME
=
"java.util.concurrent.ForkJoinTask"
;
private
static
final
String
TTL_RECURSIVE_ACTION_CLASS_NAME
=
"com.alibaba.ttl.TtlRecursiveAction"
;
private
static
final
String
TTL_RECURSIVE_TASK_CLASS_NAME
=
"com.alibaba.ttl.TtlRecursiveTask"
;
private
static
final
byte
[]
EMPTY_BYTE_ARRAY
=
{};
@Override
public
byte
[]
transform
(
final
ClassLoader
loader
,
final
String
classFile
,
final
Class
<?>
classBeingRedefined
,
final
ProtectionDomain
protectionDomain
,
final
byte
[]
classFileBuffer
)
{
public
final
byte
[]
transform
(
final
ClassLoader
loader
,
final
String
classFile
,
final
Class
<?>
classBeingRedefined
,
final
ProtectionDomain
protectionDomain
,
final
byte
[]
classFileBuffer
)
{
try
{
// Lambda has no class file, no need to transform, just return.
if
(
classFile
==
null
)
{
...
...
@@ -59,36 +47,12 @@ public class TtlTransformer implements ClassFileTransformer {
}
final
String
className
=
toClassName
(
classFile
);
if
(
EXECUTOR_CLASS_NAMES
.
contains
(
className
))
{
logger
.
info
(
"Transforming class "
+
className
);
final
CtClass
clazz
=
getCtClass
(
classFileBuffer
,
loader
);
for
(
CtMethod
method
:
clazz
.
getDeclaredMethods
())
{
updateMethodOfExecutorClass
(
clazz
,
method
);
}
return
clazz
.
toBytecode
();
}
else
if
(
FORK_JOIN_TASK_CLASS_NAME
.
equals
(
className
))
{
logger
.
info
(
"Transforming class "
+
className
);
final
CtClass
clazz
=
getCtClass
(
classFileBuffer
,
loader
);
updateForkJoinTaskClass
(
className
,
clazz
);
return
clazz
.
toBytecode
();
}
else
if
(
TIMER_TASK_CLASS_NAME
.
equals
(
className
))
{
final
CtClass
clazz
=
getCtClass
(
classFileBuffer
,
loader
);
while
(
true
)
{
String
name
=
clazz
.
getSuperclass
().
getName
();
if
(
Object
.
class
.
getName
().
equals
(
name
))
{
break
;
}
if
(
TIMER_TASK_CLASS_NAME
.
equals
(
name
))
{
logger
.
info
(
"Transforming class "
+
className
);
// FIXME add code here
return
EMPTY_BYTE_ARRAY
;
}
for
(
JavassistTransformlet
transformlet
:
transformletList
)
{
if
(
transformlet
.
needTransform
(
className
))
{
logger
.
info
(
"Transforming class "
+
className
);
final
CtClass
clazz
=
getCtClass
(
classFileBuffer
,
loader
);
transformlet
.
doTransform
(
clazz
);
return
clazz
.
toBytecode
();
}
}
}
catch
(
Throwable
t
)
{
...
...
@@ -98,6 +62,7 @@ public class TtlTransformer implements ClassFileTransformer {
}
throw
new
IllegalStateException
(
msg
,
t
);
}
return
EMPTY_BYTE_ARRAY
;
}
...
...
@@ -106,76 +71,15 @@ public class TtlTransformer implements ClassFileTransformer {
}
private
static
CtClass
getCtClass
(
final
byte
[]
classFileBuffer
,
final
ClassLoader
classLoader
)
throws
IOException
{
ClassPool
classPool
=
new
ClassPool
(
true
);
final
ClassPool
classPool
=
new
ClassPool
(
true
);
if
(
classLoader
==
null
)
{
classPool
.
appendClassPath
(
new
LoaderClassPath
(
ClassLoader
.
getSystemClassLoader
()));
}
else
{
classPool
.
appendClassPath
(
new
LoaderClassPath
(
classLoader
));
}
CtClass
clazz
=
classPool
.
makeClass
(
new
ByteArrayInputStream
(
classFileBuffer
),
false
);
final
CtClass
clazz
=
classPool
.
makeClass
(
new
ByteArrayInputStream
(
classFileBuffer
),
false
);
clazz
.
defrost
();
return
clazz
;
}
private
static
void
updateMethodOfExecutorClass
(
final
CtClass
clazz
,
final
CtMethod
method
)
throws
NotFoundException
,
CannotCompileException
{
if
(
method
.
getDeclaringClass
()
!=
clazz
)
{
return
;
}
final
int
modifiers
=
method
.
getModifiers
();
if
(!
Modifier
.
isPublic
(
modifiers
)
||
Modifier
.
isStatic
(
modifiers
))
{
return
;
}
CtClass
[]
parameterTypes
=
method
.
getParameterTypes
();
StringBuilder
insertCode
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
parameterTypes
.
length
;
i
++)
{
CtClass
paraType
=
parameterTypes
[
i
];
if
(
RUNNABLE_CLASS_NAME
.
equals
(
paraType
.
getName
()))
{
String
code
=
String
.
format
(
"$%d = %s.get($%d, false, true);"
,
i
+
1
,
TTL_RUNNABLE_CLASS_NAME
,
i
+
1
);
logger
.
info
(
"insert code before method "
+
method
+
" of class "
+
method
.
getDeclaringClass
().
getName
()
+
": "
+
code
);
insertCode
.
append
(
code
);
}
else
if
(
CALLABLE_CLASS_NAME
.
equals
(
paraType
.
getName
()))
{
String
code
=
String
.
format
(
"$%d = %s.get($%d, false, true);"
,
i
+
1
,
TTL_CALLABLE_CLASS_NAME
,
i
+
1
);
logger
.
info
(
"insert code before method "
+
method
+
" of class "
+
method
.
getDeclaringClass
().
getName
()
+
": "
+
code
);
insertCode
.
append
(
code
);
}
}
if
(
insertCode
.
length
()
>
0
)
{
method
.
insertBefore
(
insertCode
.
toString
());
}
}
private
static
void
updateForkJoinTaskClass
(
final
String
className
,
final
CtClass
clazz
)
throws
CannotCompileException
,
NotFoundException
{
// add new field
final
String
capturedFieldName
=
"captured$field$add$by$ttl"
;
final
CtField
capturedField
=
CtField
.
make
(
"private final java.lang.Object "
+
capturedFieldName
+
";"
,
clazz
);
clazz
.
addField
(
capturedField
,
"com.alibaba.ttl.TransmittableThreadLocal.Transmitter.capture();"
);
logger
.
info
(
"add new field "
+
capturedFieldName
+
" to class "
+
className
);
final
String
doExec_methodName
=
"doExec"
;
final
CtMethod
doExecMethod
=
clazz
.
getDeclaredMethod
(
doExec_methodName
);
final
CtMethod
new_doExecMethod
=
CtNewMethod
.
copy
(
doExecMethod
,
doExec_methodName
,
clazz
,
null
);
// rename original doExec method, and set to private method(avoid reflect out renamed method unexpectedly)
final
String
original_doExec_method_rename
=
"original$doExec$method$renamed$by$ttl"
;
doExecMethod
.
setName
(
original_doExec_method_rename
);
doExecMethod
.
setModifiers
(
doExecMethod
.
getModifiers
()
&
~
Modifier
.
PUBLIC
/* remove public */
|
Modifier
.
PRIVATE
/* add private */
);
// set new doExec method implementation
final
String
code
=
"{\n"
+
// do nothing/directly return, if is TTL ForkJoinTask instance
"if (this instanceof "
+
TTL_RECURSIVE_ACTION_CLASS_NAME
+
" || this instanceof "
+
TTL_RECURSIVE_TASK_CLASS_NAME
+
") {\n"
+
" return "
+
original_doExec_method_rename
+
"($$);\n"
+
"}\n"
+
"java.lang.Object backup = com.alibaba.ttl.TransmittableThreadLocal.Transmitter.replay("
+
capturedFieldName
+
");\n"
+
"try {\n"
+
" return "
+
original_doExec_method_rename
+
"($$);\n"
+
"} finally {\n"
+
" com.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore(backup);\n"
+
"}\n"
+
"}"
;
new_doExecMethod
.
setBody
(
code
);
clazz
.
addMethod
(
new_doExecMethod
);
logger
.
info
(
"insert code around method "
+
doExecMethod
+
" of class "
+
className
+
": "
+
code
);
}
}
src/main/java/com/alibaba/ttl/threadpool/agent/transformlet/TtlExecutorTransformlet.java
0 → 100644
浏览文件 @
92370c53
package
com.alibaba.ttl.threadpool.agent.transformlet
;
import
com.alibaba.ttl.threadpool.agent.JavassistTransformlet
;
import
javassist.CannotCompileException
;
import
javassist.CtClass
;
import
javassist.CtMethod
;
import
javassist.NotFoundException
;
import
java.io.IOException
;
import
java.lang.reflect.Modifier
;
import
java.util.HashSet
;
import
java.util.Set
;
import
java.util.logging.Logger
;
/**
* TTL {@link JavassistTransformlet} for {@link java.util.concurrent.Executor}.
*
* @author Jerry Lee (oldratlee at gmail dot com)
* @author wuwen5 (wuwen.55 at aliyun dot com)
* @see java.util.concurrent.Executor
* @see java.util.concurrent.ExecutorService
* @see java.util.concurrent.ThreadPoolExecutor
* @see java.util.concurrent.ScheduledThreadPoolExecutor
* @see java.util.concurrent.Executors
* @since 2.5.1
*/
public
class
TtlExecutorTransformlet
implements
JavassistTransformlet
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
TtlExecutorTransformlet
.
class
.
getName
());
private
static
final
String
TTL_RUNNABLE_CLASS_NAME
=
"com.alibaba.ttl.TtlRunnable"
;
private
static
final
String
TTL_CALLABLE_CLASS_NAME
=
"com.alibaba.ttl.TtlCallable"
;
private
static
final
String
RUNNABLE_CLASS_NAME
=
"java.lang.Runnable"
;
private
static
final
String
CALLABLE_CLASS_NAME
=
"java.util.concurrent.Callable"
;
private
static
Set
<
String
>
EXECUTOR_CLASS_NAMES
=
new
HashSet
<
String
>();
static
{
EXECUTOR_CLASS_NAMES
.
add
(
"java.util.concurrent.ThreadPoolExecutor"
);
EXECUTOR_CLASS_NAMES
.
add
(
"java.util.concurrent.ScheduledThreadPoolExecutor"
);
}
@Override
public
boolean
needTransform
(
String
className
)
{
return
EXECUTOR_CLASS_NAMES
.
contains
(
className
);
}
@Override
public
void
doTransform
(
CtClass
clazz
)
throws
NotFoundException
,
CannotCompileException
,
IOException
{
for
(
CtMethod
method
:
clazz
.
getDeclaredMethods
())
{
updateMethodOfExecutorClass
(
clazz
,
method
);
}
}
private
void
updateMethodOfExecutorClass
(
final
CtClass
clazz
,
final
CtMethod
method
)
throws
NotFoundException
,
CannotCompileException
{
if
(
method
.
getDeclaringClass
()
!=
clazz
)
{
return
;
}
final
int
modifiers
=
method
.
getModifiers
();
if
(!
Modifier
.
isPublic
(
modifiers
)
||
Modifier
.
isStatic
(
modifiers
))
{
return
;
}
CtClass
[]
parameterTypes
=
method
.
getParameterTypes
();
StringBuilder
insertCode
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
parameterTypes
.
length
;
i
++)
{
CtClass
paraType
=
parameterTypes
[
i
];
if
(
RUNNABLE_CLASS_NAME
.
equals
(
paraType
.
getName
()))
{
String
code
=
String
.
format
(
"$%d = %s.get($%d, false, true);"
,
i
+
1
,
TTL_RUNNABLE_CLASS_NAME
,
i
+
1
);
logger
.
info
(
"insert code before method "
+
method
+
" of class "
+
method
.
getDeclaringClass
().
getName
()
+
": "
+
code
);
insertCode
.
append
(
code
);
}
else
if
(
CALLABLE_CLASS_NAME
.
equals
(
paraType
.
getName
()))
{
String
code
=
String
.
format
(
"$%d = %s.get($%d, false, true);"
,
i
+
1
,
TTL_CALLABLE_CLASS_NAME
,
i
+
1
);
logger
.
info
(
"insert code before method "
+
method
+
" of class "
+
method
.
getDeclaringClass
().
getName
()
+
": "
+
code
);
insertCode
.
append
(
code
);
}
}
if
(
insertCode
.
length
()
>
0
)
{
method
.
insertBefore
(
insertCode
.
toString
());
}
}
}
src/main/java/com/alibaba/ttl/threadpool/agent/transformlet/TtlForkJoinTransformlet.java
0 → 100644
浏览文件 @
92370c53
package
com.alibaba.ttl.threadpool.agent.transformlet
;
import
com.alibaba.ttl.threadpool.agent.JavassistTransformlet
;
import
javassist.*
;
import
java.io.IOException
;
import
java.lang.reflect.Modifier
;
import
java.util.logging.Logger
;
/**
* TTL {@link JavassistTransformlet} for {@link java.util.concurrent.ForkJoinTask}.
*
* @author Jerry Lee (oldratlee at gmail dot com)
* @author wuwen5 (wuwen.55 at aliyun dot com)
* @see java.util.concurrent.ForkJoinPool
* @see java.util.concurrent.ForkJoinTask
* @since 2.5.1
*/
public
class
TtlForkJoinTransformlet
implements
JavassistTransformlet
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
TtlForkJoinTransformlet
.
class
.
getName
());
private
static
final
String
FORK_JOIN_TASK_CLASS_NAME
=
"java.util.concurrent.ForkJoinTask"
;
private
static
final
String
TTL_RECURSIVE_ACTION_CLASS_NAME
=
"com.alibaba.ttl.TtlRecursiveAction"
;
private
static
final
String
TTL_RECURSIVE_TASK_CLASS_NAME
=
"com.alibaba.ttl.TtlRecursiveTask"
;
@Override
public
boolean
needTransform
(
String
className
)
{
return
FORK_JOIN_TASK_CLASS_NAME
.
equals
(
className
);
}
@Override
public
void
doTransform
(
CtClass
clazz
)
throws
NotFoundException
,
CannotCompileException
,
IOException
{
updateForkJoinTaskClass
(
clazz
);
}
private
void
updateForkJoinTaskClass
(
final
CtClass
clazz
)
throws
CannotCompileException
,
NotFoundException
{
// add new field
final
String
className
=
clazz
.
getName
();
final
String
capturedFieldName
=
"captured$field$add$by$ttl"
;
final
CtField
capturedField
=
CtField
.
make
(
"private final java.lang.Object "
+
capturedFieldName
+
";"
,
clazz
);
clazz
.
addField
(
capturedField
,
"com.alibaba.ttl.TransmittableThreadLocal.Transmitter.capture();"
);
logger
.
info
(
"add new field "
+
capturedFieldName
+
" to class "
+
className
);
final
String
doExec_methodName
=
"doExec"
;
final
CtMethod
doExecMethod
=
clazz
.
getDeclaredMethod
(
doExec_methodName
);
final
CtMethod
new_doExecMethod
=
CtNewMethod
.
copy
(
doExecMethod
,
doExec_methodName
,
clazz
,
null
);
// rename original doExec method, and set to private method(avoid reflect out renamed method unexpectedly)
final
String
original_doExec_method_rename
=
"original$doExec$method$renamed$by$ttl"
;
doExecMethod
.
setName
(
original_doExec_method_rename
);
doExecMethod
.
setModifiers
(
doExecMethod
.
getModifiers
()
&
~
Modifier
.
PUBLIC
/* remove public */
|
Modifier
.
PRIVATE
/* add private */
);
// set new doExec method implementation
final
String
code
=
"{\n"
+
// do nothing/directly return, if is TTL ForkJoinTask instance
"if (this instanceof "
+
TTL_RECURSIVE_ACTION_CLASS_NAME
+
" || this instanceof "
+
TTL_RECURSIVE_TASK_CLASS_NAME
+
") {\n"
+
" return "
+
original_doExec_method_rename
+
"($$);\n"
+
"}\n"
+
"java.lang.Object backup = com.alibaba.ttl.TransmittableThreadLocal.Transmitter.replay("
+
capturedFieldName
+
");\n"
+
"try {\n"
+
" return "
+
original_doExec_method_rename
+
"($$);\n"
+
"} finally {\n"
+
" com.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore(backup);\n"
+
"}\n"
+
"}"
;
new_doExecMethod
.
setBody
(
code
);
clazz
.
addMethod
(
new_doExecMethod
);
logger
.
info
(
"insert code around method "
+
doExecMethod
+
" of class "
+
className
+
": "
+
code
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录