Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wang2java
Spring Framework
提交
d32a77a5
S
Spring Framework
项目概览
wang2java
/
Spring Framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Spring Framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d32a77a5
编写于
8月 01, 2013
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimized TomcatInstrumentableClassLoader implementation
Issue: SPR-10788
上级
d8e3ef76
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
20 addition
and
63 deletion
+20
-63
spring-context/src/main/java/org/springframework/instrument/classloading/ReflectiveLoadTimeWeaver.java
...ork/instrument/classloading/ReflectiveLoadTimeWeaver.java
+6
-7
spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java
.../classloading/tomcat/TomcatInstrumentableClassLoader.java
+14
-56
未找到文件。
spring-context/src/main/java/org/springframework/instrument/classloading/ReflectiveLoadTimeWeaver.java
浏览文件 @
d32a77a5
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -98,15 +98,14 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
this
.
classLoader
=
classLoader
;
this
.
addTransformerMethod
=
ClassUtils
.
getMethodIfAvailable
(
this
.
classLoader
.
getClass
(),
ADD_TRANSFORMER_METHOD_NAME
,
new
Class
[]
{
ClassFileTransformer
.
class
});
new
Class
[]
{
ClassFileTransformer
.
class
});
if
(
this
.
addTransformerMethod
==
null
)
{
throw
new
IllegalStateException
(
"ClassLoader ["
+
classLoader
.
getClass
().
getName
()
+
"] does NOT provide an "
+
"'addTransformer(ClassFileTransformer)' method."
);
}
this
.
getThrowawayClassLoaderMethod
=
ClassUtils
.
getMethodIfAvailable
(
this
.
classLoader
.
getClass
(),
GET_THROWAWAY_CLASS_LOADER_METHOD_NAME
,
new
Class
[
0
]);
this
.
classLoader
.
getClass
(),
GET_THROWAWAY_CLASS_LOADER_METHOD_NAME
,
new
Class
[
0
]);
// getThrowawayClassLoader method is optional
if
(
this
.
getThrowawayClassLoaderMethod
==
null
)
{
if
(
logger
.
isInfoEnabled
())
{
...
...
@@ -119,7 +118,7 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
public
void
addTransformer
(
ClassFileTransformer
transformer
)
{
Assert
.
notNull
(
transformer
,
"Transformer must not be null"
);
ReflectionUtils
.
invokeMethod
(
this
.
addTransformerMethod
,
this
.
classLoader
,
new
Object
[]
{
transformer
}
);
ReflectionUtils
.
invokeMethod
(
this
.
addTransformerMethod
,
this
.
classLoader
,
transformer
);
}
public
ClassLoader
getInstrumentableClassLoader
()
{
...
...
@@ -128,11 +127,11 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
public
ClassLoader
getThrowawayClassLoader
()
{
if
(
this
.
getThrowawayClassLoaderMethod
!=
null
)
{
return
(
ClassLoader
)
ReflectionUtils
.
invokeMethod
(
this
.
getThrowawayClassLoaderMethod
,
this
.
classLoader
,
new
Object
[
0
]);
return
(
ClassLoader
)
ReflectionUtils
.
invokeMethod
(
this
.
getThrowawayClassLoaderMethod
,
this
.
classLoader
);
}
else
{
return
new
SimpleThrowawayClassLoader
(
this
.
classLoader
);
}
}
}
spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java
浏览文件 @
d32a77a5
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -22,6 +22,7 @@ import java.lang.reflect.Modifier;
import
org.apache.catalina.loader.ResourceEntry
;
import
org.apache.catalina.loader.WebappClassLoader
;
import
org.springframework.instrument.classloading.WeavingTransformer
;
/**
...
...
@@ -31,8 +32,8 @@ import org.springframework.instrument.classloading.WeavingTransformer;
* <p>To be registered using a
* {@code <a href="http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html">Loader</a>} tag
* in Tomcat's {@code <a href="http://tomcat.apache.org/tomcat-5.5-doc/config/context.html">Context</a>}
* definition in the {@code server.xml} file, with the Spring-provided
*
"spring-tomcat-weaver.jar"
file deployed into Tomcat's "server/lib" (for Tomcat 5.x) or "lib" (for Tomcat 6.x) directory.
* definition in the {@code server.xml} file, with the Spring-provided
"spring-instrument-tomcat.jar"
* file deployed into Tomcat's "server/lib" (for Tomcat 5.x) or "lib" (for Tomcat 6.x) directory.
* The required configuration tag looks as follows:
*
* <pre class="code"><Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/></pre>
...
...
@@ -58,6 +59,7 @@ import org.springframework.instrument.classloading.WeavingTransformer;
public
class
TomcatInstrumentableClassLoader
extends
WebappClassLoader
{
private
static
final
String
CLASS_SUFFIX
=
".class"
;
/** Use an internal WeavingTransformer */
private
final
WeavingTransformer
weavingTransformer
;
...
...
@@ -101,8 +103,7 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader {
*/
public
ClassLoader
getThrowawayClassLoader
()
{
WebappClassLoader
tempLoader
=
new
WebappClassLoader
();
// Use reflection to copy all the fields since most of them are private
// on pre-5.5 Tomcat.
// Use reflection to copy all the fields since most of them are private on pre-5.5 Tomcat.
shallowCopyFieldState
(
this
,
tempLoader
);
return
tempLoader
;
}
...
...
@@ -111,12 +112,9 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader {
@Override
protected
ResourceEntry
findResourceInternal
(
String
name
,
String
path
)
{
ResourceEntry
entry
=
super
.
findResourceInternal
(
name
,
path
);
// Postpone String parsing as much as possible (it is slow).
if
(
entry
!=
null
&&
entry
.
binaryContent
!=
null
&&
path
.
endsWith
(
CLASS_SUFFIX
))
{
String
className
=
(
name
.
endsWith
(
CLASS_SUFFIX
)
?
name
.
substring
(
0
,
name
.
length
()
-
CLASS_SUFFIX
.
length
())
:
name
);
byte
[]
transformed
=
this
.
weavingTransformer
.
transformIfNecessary
(
className
,
entry
.
binaryContent
);
entry
.
binaryContent
=
transformed
;
String
className
=
(
name
.
endsWith
(
CLASS_SUFFIX
)
?
name
.
substring
(
0
,
name
.
length
()
-
CLASS_SUFFIX
.
length
())
:
name
);
entry
.
binaryContent
=
this
.
weavingTransformer
.
transformIfNecessary
(
className
,
entry
.
binaryContent
);
}
return
entry
;
}
...
...
@@ -124,8 +122,7 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
(
getClass
().
getName
());
sb
.
append
(
"\r\n"
);
sb
.
append
(
super
.
toString
());
sb
.
append
(
"\r\n"
).
append
(
super
.
toString
());
return
sb
.
toString
();
}
...
...
@@ -133,43 +130,23 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader {
// The code below is originally taken from ReflectionUtils and optimized for
// local usage. There is no dependency on ReflectionUtils to keep this class
// self-contained (since it gets deployed into Tomcat's server class loader).
/**
* Given the source object and the destination, which must be the same class
* or a subclass, copy all fields, including inherited fields. Designed to
* work on objects with public no-arg constructors.
* @throws IllegalArgumentException if arguments are incompatible or either
* is {@code null}
*/
private
static
void
shallowCopyFieldState
(
final
Object
src
,
final
Object
dest
)
throws
IllegalArgumentException
{
if
(
src
==
null
)
{
throw
new
IllegalArgumentException
(
"Source for field copy cannot be null"
);
}
if
(
dest
==
null
)
{
throw
new
IllegalArgumentException
(
"Destination for field copy cannot be null"
);
}
Class
targetClass
=
findCommonAncestor
(
src
.
getClass
(),
dest
.
getClass
());
private
static
void
shallowCopyFieldState
(
final
WebappClassLoader
src
,
final
WebappClassLoader
dest
)
{
Class
<?>
targetClass
=
WebappClassLoader
.
class
;
// Keep backing up the inheritance hierarchy.
do
{
// Copy each field declared on this class unless it's static or
// file.
Field
[]
fields
=
targetClass
.
getDeclaredFields
();
for
(
int
i
=
0
;
i
<
fields
.
length
;
i
++)
{
Field
field
=
fields
[
i
];
// Skip static and final fields (the old FieldFilter)
// do not copy resourceEntries - it's a cache that holds class entries.
for
(
Field
field
:
fields
)
{
// Do not copy resourceEntries - it's a cache that holds class entries.
if
(!(
Modifier
.
isStatic
(
field
.
getModifiers
())
||
Modifier
.
isFinal
(
field
.
getModifiers
())
||
field
.
getName
().
equals
(
"resourceEntries"
)))
{
try
{
// copy the field (the old FieldCallback)
field
.
setAccessible
(
true
);
Object
srcValue
=
field
.
get
(
src
);
field
.
set
(
dest
,
srcValue
);
}
catch
(
IllegalAccessException
ex
)
{
throw
new
IllegalStateException
(
"Shouldn't be illegal to access field '"
+
field
s
[
i
]
.
getName
()
+
"': "
+
ex
);
"Shouldn't be illegal to access field '"
+
field
.
getName
()
+
"': "
+
ex
);
}
}
}
...
...
@@ -178,23 +155,4 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader {
while
(
targetClass
!=
null
&&
targetClass
!=
Object
.
class
);
}
private
static
Class
findCommonAncestor
(
Class
one
,
Class
two
)
throws
IllegalArgumentException
{
Class
ancestor
=
one
;
while
(
ancestor
!=
Object
.
class
||
ancestor
!=
null
)
{
if
(
ancestor
.
isAssignableFrom
(
two
))
{
return
ancestor
;
}
ancestor
=
ancestor
.
getSuperclass
();
}
// try the other class hierarchy
ancestor
=
two
;
while
(
ancestor
!=
Object
.
class
||
ancestor
!=
null
)
{
if
(
ancestor
.
isAssignableFrom
(
one
))
{
return
ancestor
;
}
ancestor
=
ancestor
.
getSuperclass
();
}
return
null
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录