Deep understanding of Java classloader, bytecode, ASM, cglib (II)

Source: Internet
Author: User

Iii. ASM 
We know that Java is a static language, while Python and Ruby are dynamic languages. Once a Java program is written, it is difficult to change the class behavior at runtime, while Python and Ruby can.
However, on the bytecode layer, we can do some work to make Java programs more flexible and magic. ASM is such an open-source library that is widely used.

ASM is a Java bytecode manipulation framework. It can be used to dynamically generate stub classes or other proxy classes,
Directly in binary form, or to dynamically modify classes at load time, I. e., just before they are loaded into the Java
Virtual Machine.

ASM completes the same functionality of bcel and serp, but ASM
Only over 30 K, and the latter two are 150 K and K respectively. Apache is becoming increasingly popular.

Let's take a look at a simple example of ASM helloworld. Java, which generates an example class and a main method. The main method prints "Hello world! "Statement:

Code
  1. Import java. Io. fileoutputstream;
  2. Import java. Io. printstream;
  3. Import org. objectweb. ASM. classwriter;
  4. Import org. objectweb. ASM. methodvisitor;
  5. Import org. objectweb. ASM. Opcodes;
  6. Import org. objectweb. ASM. type;
  7. Import org. objectweb. ASM. commons. generatoradapter;
  8. Import org. objectweb. ASM. commons. method;
  9. Public class helloworld extends classloader implements Opcodes {
  10. Public static void main (final string ARGs []) throws exception {
  11. // Creates a classwriter for the example public class,
  12. // Which inherits from object
  13. Classwriter CW = new classwriter (0 );
  14. CW. Visit (v1_1, acc_public, "example", null, "Java/lang/object", null );
  15. Methodvisitor Mw = CW. visitmethod (acc_public, "<init>", "() V", null,
  16. Null );
  17. MW. visitvarinsn (aload, 0 );
  18. MW. visitmethodinsn (invokespecial, "Java/lang/object", "<init>", "() V ");
  19. MW. visitinsn (return );
  20. MW. visitmaxs (1, 1 );
  21. MW. visitend ();
  22. Mw = CW. visitmethod (acc_public + acc_static, "Main ",
  23. "([Ljava/lang/string;) V", null, null );
  24. MW. visitfieldinsn (getstatic, "Java/lang/system", "out ",
  25. "Ljava/IO/printstream ;");
  26. MW. visitldcinsn ("Hello world! ");
  27. MW. visitmethodinsn (invokevirtual, "Java/IO/printstream", "println ",
  28. "(Ljava/lang/string;) V ");
  29. MW. visitinsn (return );
  30. MW. visitmaxs (2, 2 );
  31. MW. visitend ();
  32. Byte [] code = CW. tobytearray ();
  33. Fileoutputstream Fos = new fileoutputstream ("example. Class ");
  34. FOS. Write (CODE );
  35. FOS. Close ();
  36. Helloworld loader = new helloworld ();
  37. Class exampleclass = Loader
  38. . Defineclass ("example", code, 0, code. Length );
  39. Exampleclass. getmethods () [0]. Invoke (null, new object [] {null });
  40. //------------------------------------------------------------------------
  41. // Same example with a generatoradapter (more convenient but slower)
  42. //------------------------------------------------------------------------
  43. CW = new classwriter (classwriter. compute_maxs );
  44. CW. Visit (v1_1, acc_public, "example", null, "Java/lang/object", null );
  45. Method M = method. getmethod ("Void <init> ()");
  46. Generatoradapter Mg = new generatoradapter (acc_public, M, null, null,
  47. CW );
  48. MG. loadthis ();
  49. MG. invokeconstructor (type. GetType (object. Class), M );
  50. MG. returnvalue ();
  51. MG. endmethod ();
  52. M = method. getmethod ("Void main (string [])");
  53. Mg = new generatoradapter (acc_public + acc_static, M, null, null, Cw );
  54. MG. getstatic (type. GetType (system. Class), "out", Type
  55. . GetType (printstream. Class ));
  56. MG. Push ("Hello world! ");
  57. MG. invokevirtual (type. GetType (printstream. Class), Method
  58. . Getmethod ("Void println (string )"));
  59. MG. returnvalue ();
  60. MG. endmethod ();
  61. CW. visitend ();
  62. Code = CW. tobytearray ();
  63. Loader = new helloworld ();
  64. Exampleclass = loader. defineclass ("example", code, 0, code. Length );
  65. Exampleclass. getmethods () [0]. Invoke (null, new object [] {null });
  66. }
  67. }

We can see that the above example uses methods of ASM methodvisitor and generatoradapter to dynamically generate the example class and call the print statement.

Iv. cglib 
Cglib is a powerful, high performance and quality code generation library, it is used to extend Java classes and implements interfaces at runtime.
Cglib is the abbreviation of code generation library.
Cglib depends on the ASM library.
Hibernate uses cglib to generate pojo subclasses and override get to implement the lazy loading mechanism. Spring uses cglib to implement dynamic proxy.
The dynamic proxy mechanism of JDK requires an interface, which forces our pojo to implement an interface.

Here is an entry-level example of cglib:
Myclass. Java:

Code
  1. Public class myclass {
  2. Public void print (){
  3. System. Out. println ("I'm in myclass. Print! ");
  4. }
  5. }

Main. Java: Code

  1. Import java. Lang. Reflect. method;
  2. Import net. SF. cglib. Proxy. enhancer;
  3. Import net. SF. cglib. Proxy. methodinterceptor;
  4. Import net. SF. cglib. Proxy. methodproxy;
  5. Public class main {
  6. Public static void main (string [] ARGs ){
  7. Enhancer = new enhancer ();
  8. Enhancer. setsuperclass (myclass. Class );
  9. Enhancer. setcallback (New methodinterceptorimpl ());
  10. Myclass my = (myclass) enhancer. Create ();
  11. My. Print ();
  12. }
  13. Private Static class methodinterceptorimpl implements methodinterceptor {
  14. Public object intercept (Object OBJ, method, object [] ARGs,
  15. Methodproxy proxy) throws throwable {
  16. // Log something
  17. System. Out. println (method + "intercepted! ");
  18. Proxy. invokesuper (OBJ, argS );
  19. Return NULL;
  20. }
  21. }
  22. }

The printed result is: Code

  1. Public void myclass. Print () Intercepted!
  2. I'm in myclass. Print!

This example basically implements the log AOP function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.