ÔÚ·ÉÏ

 ÕÒ»ØÃÜÂë
 Á¢¼´×¢²á
ÔÚ·ÉÏ Õ¾µãÊ×Ò³ ѧϰ ²é¿´ÄÚÈÝ

ClassLoader, JavaAgent, Aspectj WeavingһվʽɨäÌû

2017-2-7 13:39| ·¢²¼Õß: zhangjf| ²é¿´: 542| ÆÀÂÛ: 0

ÕªÒª: Ô­ÎÄ http://calvin1978.blogcn.com/articles/classloader-javaagent.html ×î½ü¹¤×÷À︴ϰµÄClass Loader»ù´¡ÖªÊ¶¼¯½õ£¬Ð´ÏÂÀ´Ï£Íû¶Ô±ðÈËÓаïÖú£¬¶øÇÒ²»Ö¹ÊÇΪÁËÁ̵¹ÃæÊÔ¹Ù¡£ ΪÁ˾¡Á¿¼òµ¥Ã÷ÁËÈÝÒ×±³£¬ ...
Ô­ÎÄ http://calvin1978.blogcn.com/articles/classloader-javaagent.html

×î½ü¹¤×÷À︴ϰµÄClass Loader»ù´¡ÖªÊ¶¼¯½õ£¬Ð´ÏÂÀ´Ï£Íû¶Ô±ðÈËÓаïÖú£¬¶øÇÒ²»Ö¹ÊÇΪÁËÁ̵¹ÃæÊÔ¹Ù¡£

ΪÁ˾¡Á¿¼òµ¥Ã÷ÁËÈÝÒ×±³£¬ÓÐЩ²¿·ÖдµÃ±È½Ï¸É¡£

0. ²Î¿¼×ÊÁÏ£º Ê飺¡¶ÉîÈëÁ˽âJavaÐéÄâ»ú¡·¡¢¡¶ÊµÕ½JavaÐéÄâ»ú¡· ¹æ·¶£º javaÓïÑԹ淶 µÚ12Õ ԴÂ룺 OpenJDK 7 µÄJava¼°C´úÂë( class.c , classloader.c£¬jvm.cpp) 1. Class×°ÔØµÄÈý¸ö½×¶Î 1.1 ÔØÈë (Load)

´ÓClassÎļþ»ò±ðµÄʲôµØ·½ÔØÈëÒ»¶Î¶þ½øÖÆÁ÷×Ö½ÚÁ÷£¬°ÑËü½âÊͳÉÓÀ¾Ã´úÀïµÄÔËÐÐʱÊý¾Ý½á¹¹£¬Éú³ÉÒ»¸öClass¶ÔÏó¡£

1.2 Á´½Ó (Resolve)

½«Ö®Ç°ÔØÈëµÄÊý¾Ý½á¹¹ÀïµÄ·ûºÅÒýÓÃ±í£¬½âÎö³ÉÖ±½ÓÒýÓá£

ÖмäÈç¹ûÓöµ½ÒýÓõÄÀ໹û±»¼ÓÔØ£¬¾Í»á´¥·¢¸ÃÀàµÄ¼ÓÔØ¡£

¿ÉÄÜJDK»áºÜÀÁ¶èµÄÔÚÔËÐÐij¸öº¯Êýʵ¼ÊʹÓõ½¸ÃÒýÓÃʱ²Å·¢ÉúÁ´½Ó£¬Ò²¿ÉÄÜÔÚÀà¼ÓÔØÊ±¾Í½âÎöÈ«²¿ÒýÓá£

1.3 ³õʼ»¯ (Initniazle)

³õʼ»¯¾²Ì¬±äÁ¿£¬²¢Ö´Ðо²Ì¬³õʼ»¯Óï¾ä¡£

2. Class×°ÔØµÄʱ»ú ClassLoader.loadClass() ǰÎÄËù˵µÄÁ´½Óʱ´¥·¢µÄ×°ÔØ Class.forName() µÈjava.lang.reflect·´Éä°ü new ¹¹Ôì¶ÔÏó ³õʼ»¯×ÓÀàʱ£¬»áͬʱ³õʼ»¯¸¸Àà ·ÃÎÊÀàµÄ¾²Ì¬±äÁ¿»ò¾²Ì¬·½·¨£¨µ«static finalµÄ³£Á¿³ýÍ⣬´Ë¾ýÔÚ³£Á¿³ØÀï)

±¾ÖÊÉÏ£¬Ò²ÊǺÜÀÁ¶èµÄ°´Ðè¼ÓÔØµÄ£¬ÓÉÓÚÀà×°ÔØµÄLazyºÍÇ°Ãæ½âÊÍÒýÓõÄLazy£¬ËùÒÔJar°üÀïÓÐʱºòÓÐЩÀàÓõ½µÄÁËûÔÚClass PathÀïµÄÆäËûÀ࣬ҲÄÜÈËÆ·±¬·¢µÄÕÕÅܲ»Îó¡£

³ýÁË1£¬ÆäËû¼¸ÖÖ·½Ê½Ä¬È϶¼µ½´ïÀà×°ÔØµÄ³õʼ»¯½×¶Î¡£

3. ClassLoader.loadClass() Óë Class.forName()

ClassLoader.loadClass(String name, boolean resolve)£¬ÆäÖÐresolveĬÈÏΪfalse£¬¼´Ö»Ö´ÐÐÀà×°ÔØµÄµÚÒ»¸ö½×¶Î¡£

Class.forName(String name, boolean initialize, ClassLoader loader)£¬ ÆäÖÐinitializeĬÈÏΪtrue£¬¼´Ö´Ðе½Àà×°ÔØµÄµÚÈý¸ö½×¶Î¡£

4. ClassNotFoundException ºÍ NoClassDefFoundError

ClassLoader.loadClass() Óë Class.forName() ÕÒ²»µ½ÀඨÒåµÄ¶þ½øÖÆÁ÷ʱÅ׳öClassNotFoundException¡£

Á´½Ó½×¶Î½âÊÍÒýÓÃʧ°Ü£¬ÕÒ²»µ½ÒýÓõÄÀàʱÅ׳öNoClassDefFoundError¡£

5. ClassLoader¼°Ë«Ç×ίÅÉ»úÖÆ

ClassLoader.loadClass()µÄ±ê×¼Á÷³Ì:

findLoadedClass() ²é¿´ÀàÊÇ·ñÒѼÓÔØ Èç¹û²»´æÔÚ£¬Ôòµ÷ÓÃparent loaderµÄloadClass() Èç¹û²»´æÔÚ£¬µ÷ÓÃfindClass() ÔÚ±¾ClassLoaderµÄClassPathÀï¼ÓÔØ¸ÃÀà

Ëùν˫Ç×ίÅÉ»úÖÆ£¬¾ÍÊÇÏÈ´Óparent loader¿ªÊ¼²éÕÒ£¬ÕÒ²»µ½Á˲ÅÓÃ×Ô¼ºµÄfindClass()º¯ÊýÈ¥²éÕÒ£¬¼æ¹ËÁËЧÂÊ£º±ÜÃâÖØ¸´¼ÓÔØ£¬µ±¸¸Ç×ÒѾ­¼ÓÔØÁ˸ÃÀàµÄʱºò£¬¾ÍûÓбØÒª×ÓClassLoaderÔÙ¼ÓÔØÒ»´Î£¬ºÍ°²È«£¬±ÜÃâ×ÓÀàÂÒ¼ÓÔØ¡£

¶øOSGI»òSPI»òÈÈÌæ»»·½°¸£¬ÔòÐè񻮮»µÕâ¸öË«Ç×ίÍУ¬Ïȵ÷ÓÃ×Ô¼ºµÄfindClass()¡£

findClass() ÊǸ÷¸öClassLoader¸÷×ÔʵÏÖ£¬¸÷ÏÔÉñͨµÄµØ·½£¬´Ó¸÷ÖÖÆæÝâµØ·½ÔØÈëClass¶þ½øÖÆ×Ö½ÚÁ÷¡£

µ«×îºó¶¼»áµ÷ÓÃdefineClass()£¬´«Èë¶þ½øÖÆ×Ö½ÚÁ÷£¬·µ»ØClass¶ÔÏó¡£ÁôÒâ´Ë´¦£¬´ô»áAspectJµÄʱºò»á»Øµ½ÕâÀï¡£

ÔÚJDK6£¬loadClass()ºÜ¹ý·ÖµÄ¶¨ÒåÁË·½·¨¼¶µÄsynchronized £¬ÔÚJDK7¸Ä³ÉÒ»¸öÒÔClass Name×÷KeyµÄ parallelLockMap£¬ÔöÇ¿Á˲¢ÐмÓÔØ²»Í¬ClassµÄÄÜÁ¦¡£

6. System ClassLoader Óë Thread Context Classloader

ÓÐʱºò£¬¿´µ½´íÎóÈÕ־˵ÕÅÈý²»ÊÇÕÅÈý£¬°üÃûÀàÃûÒ»Ñùµ«instanceof ËÀ»î·µ»Ø false£¬Î¨Ò»Ô­ÒòÊÇËüÃÇÓÉÁ½¸ö²»Í¬µÄClassLoader¼ÓÔØ¡£

ĬÈϵÄBootstrap(¼ÓÔØjdkµÄlibĿ¼)£¬Extension(¼ÓÔØjdkµÄlib/extĿ¼)£¬Application(¼ÓÔØÆô¶¯Ê±¶¨ÒåµÄclasspath)Èý²ãClassLoader»úÖÆ²»ÔÙÖØ¸´¡£

ƽʱÓÃClassLoader.getSystemClassLoader()¾Í¿ÉÒԵõ½sun.misc.Launcher$ApplicationClassLoader Õâ¸öApplication ClassLoader¡£

ÔÚÀàAÀï¼ÓÔØÀàB£¬Ä¬ÈÏʹÓüÓÔØÁËÀàAµÄLoader¡£µ«£¬Ò²ÓÐÌØÊâÇé¿ö£¬±ÈÈçJDBC¼ÓÔØdriverʱµÄ»úÖÆ£¬ÐèÒªÔÚ¸¸ ClassLoader£¨JDBCÊôÓÚJDKÒ»²¿·Ö£©Àï¸ù¾ÝÅäÖ÷´Éä´´½¨jdbc driverµÄÊý¾ÝʵÏÖÀ࣬SunÉè¼ÆÁËÒ»¸öÌØÊâ·½°¸ £­£­Thread Context Class Loader¡£

JAXB(±ÈÈçÒªÔÚJar°üÀïÕÒxsd schemaÎļþµÄʱºò)ҲʹÓÃÁËËü£¬ËùÒÔÓõ½ËüÃÇʱ¾ÍҪעÒâThread Context ClassLoaderµÄÉèÖ㬿ÉÒÔÓôúÂëËæÊ±ÉèÖÃcurrent threadµÄloader£¬Ò²¿ÉÒÔÓÃ×Ô¶¨ÒåµÄThreadFactoryÔÚ´´½¨Ïß³ÌʱÉèÖã¬ËüĬÈÏÊǸ¸Ï̵߳Äloader£¬Èç¹û¶¼Ã»ÉèÖþÍÊÇ System ClassLoader¡£

7. Java Agent»úÖÆÓëAspectJµÄLoadTime Weaving

ÔÚJDK5¿ªÊ¼£¬ÔÚÆô¶¯JVMʱ¿ÉÔö¼Ó-javaagent²ÎÊý£¬ÔÚ×°ÔØClassʱ¶ÔÀà½øÐж¯Ì¬µÄÐ޸ġ£

AspectJµÄLoad Time Weaving»úÖÆ£¬ÐèÒªÅäÖà -javaagent: [path to aspectj-weaver.jar] ¡£

´ò¿ªaspectj-weaver.jar£¬¿ÉÒÔ¿´µ½META-INF/MANIFESTÀﶨÒåÁË Premain-Class: org.aspectj.weaver.loadtime.Agent

ÔÙ´ò¿ªÕâ¸öAgentÀ࣬¼ò»¯ºóµÄ´úÂë´ó¸ÅÕâ¸öÑù×Ó£º

ClassFileTransformer s_transformer = new ClassPreProcessorAgentAdapter();

public static void premain(String options, Instrumentation instrumentation) {

instrumentation.addTransformer(s_transformer);

}

¿É¼ûËüµÄÖ÷Òª×÷ÓÃÊǽ«×Ô¼ºµÄÀàת»»Æ÷×¢²áµ½JDKËù´«ÈëµÄInstrumentation¡£

ÔÙ¿´ClassFileTransformerµÄ¶¨Ò壺ClassLoader»áÔÚÇ°ÃædefineClass()µÄ¹ý³ÌÖУ¬ÔڰѶþ½øÖÆ×Ö½ÚÁ÷ת»»ÎªClass¶ÔÏó֮ǰ£¬ÏȰѶþ½øÖÆÁ÷ºÍµ±Ç°ClassLoader´«¸øTransformer£¬ÓÉTransformer¼Ó¹¤ÎªÁíÒ»¶Î¶þ½øÖÆ×Ö½ÚÁ÷·µ»Ø¡£

AspectJ¾ÍÊÇÀûÓô«ÈëµÄClassLoader£¬ÕÒ³öÆäClass PathÀïµÄMETA-INF/aop.xml£¬È»ºó¸ù¾Ýaop.xmlÀïµÄÅäÖýøÐдúÂëÖ²Èë¡£

²âÊÔÏÔʾ£¬¼ÓÁËLoadTime Weaving£¬Àà¼ÓÔØµÄËÙ¶ÈÃ÷ÏÔ±äÂý£¬Èç¹ûÊÇ100ms¾Íµ÷Óó¬Ê±µÄ·þÎñ£¬ÐèÒª×öÀàµÄÔ¤¼ÓÔØ¡£

8. Jar°üµÄÔ¤¼ÓÔØ

±ÈÈçÓиöÓÐȤµÄÐèÇóÊǼÓÔØÄ³¸öClass AËùÔÚµÄJarÀïµÄÈ«²¿µÄClass £¨ÔõôºÃÏñÒ»µã¶¼²»ÓÐȤ£©

URL jarUrl = ClassA.getProtectionDomain().getCodeSource().getLocation();

JarFile jarfile = new JarFile(jarUrl.getPath());

Enumeration entries = jarfile.entries();

È»ºó±éÀúJarEntry£¬¹ýÂ˳öºó׺Ϊ.classµÄÎļþ£¬°´ÀàÃû½øÐÐ×°ÔØ¾Í¿ÉÒÔÁË¡£

9.ClassµÄ¶þ½øÖƼæÈÝÐÔ

Èç¹ûClass A ÒÀÀµ spring-1.0.jar±àÒ룬µ±springÉý¼¶µ½spring-2.0.jar£¬Class A²»ÐèÒªÐ޸ĴúÂëÒ²²»ÐèÒªÖØÐ±àÒ룬¿ÉÒÔÖ±½ÓÔËÐеģ¬spring-2.0.jar¾ÍÂú×ã¶þ½øÖƼæÈÝÐÔ¡£

ÔÚ JavaÓïÑԹ淶µÄµÚ13Õ ÓÐÏêϸµÄÃèÊö £¬²»ÏëÖ±½Ó˯×Å×îºÃ¿ÉÒÔÕÒ¸öÖÐÎİæÀ´¿´£¬¸ÐлÄÇЩ·­ÒëµÄͬѧ¡£

ËäÈ»¹æ·¶µÄÕâÕ¿´×űȽϳ¤±È½ÏÏÅÈË£¬µ«Æäʵ¶þ½øÖƼæÈÝÐÔ»¹ÊǺÜÈÝÒ××öµ½µÄ£¬Ö»ÒªÄã²»×ö°Ñ½Ó¿Ú¸ÄΪ³éÏóÀàÖ®ÀàÆæ¹ÖµÄÊÂÇ飬ÆäËûһЩ¿´ÆðÀ´ºÜ´óµÄ¸Ä¶¯£¬±ÈÈç¸Äthrows¶¨Ò壬Æäʵ¶¼Ã»ÓÐÎÊÌâ¡£

ÕæµÄÓöµ½ÎÊÌ⣬ÉèÉí´¦µØÏëÏë×Ô¼ºÊÇÄǶÎClass AµÄ×Ö½ÚÂ룬ÏÖÔÚ»¹Äܲ»ÄÜÅܾÍÐС£

¸ÐлÄã¿´µ½ÕâÀϣÍûÄãÖ»ÔÚ¹¤×÷ÀïÓõ½ÕâЩ֪ʶ£¬×£¹¤×÷Óä¿ì¡£

×îÐÂÆÀÂÛ

СºÚÎÝ|ÔÚ·ÉÏ ( ÊñICP±¸15035742ºÅ-1 

;

GMT+8, 2025-7-9 01:39

Copyright 2015-2025 djqfx

·µ»Ø¶¥²¿