Backend Development 8 min read

Applying ASM Bytecode Manipulation in cglib and Fastjson

This article demonstrates how ASM is used to generate dynamic proxies with cglib and to create high‑performance JSON deserializers in Fastjson, providing code examples, explanation of the underlying bytecode generation, and practical tips for developers.

Top Architecture Tech Stack
Top Architecture Tech Stack
Top Architecture Tech Stack
Applying ASM Bytecode Manipulation in cglib and Fastjson

This article explains practical use cases of ASM bytecode manipulation in the Java libraries cglib and Fastjson.

Simple cglib Application

cglib, a powerful high‑performance code generation library, uses ASM to create proxy classes that enable method interception for frameworks such as Spring AOP, MyBatis, Hibernate, Guice, EasyMock, and jMock.

Given a Person class, we can generate a proxy that logs before and after the doJob method without requiring the target class to implement an interface.

public class Person {
    public void doJob(String jobName) {
        System.out.println("who is this class: " + getClass());
        System.out.println("doing job: " + jobName);
    }
}

The core of cglib proxy creation is the net.sf.cglib.proxy.MethodInterceptor interface, which defines a single intercept method. An Enhancer creates the proxy subclass:

public static void main(String[] _args) {
    MethodInterceptor interceptor = new MethodInterceptor() {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println(">>>>>before intercept");
            Object o = methodProxy.invokeSuper(obj, args);
            System.out.println(">>>>>end intercept");
            return o;
        }
    };
    Person person = (Person) Enhancer.create(Person.class, interceptor);
    person.doJob("coding");
}

Running the code prints the logging messages surrounding the original doJob execution. Setting the system property DebuggingClassWriter.DEBUG_LOCATION_PROPERTY allows cglib to write the generated class files for inspection.

Fastjson

Fastjson is a high‑performance JSON library that embeds ASM to generate bytecode for serialization and deserialization, eliminating reflection overhead and achieving up to 20% speed improvement.

A naive manual deserialization using reflection might look like this:

public static void main(String[] args) {
    String json = "{ \"id\": \"A10001\", \"name\": \"Arthur.Zhang\", \"score\": 100 }";
    String str = json.substring(1, json.length() - 1);
    String[] fieldStrArray = str.split(",");
    MyBean bean = new MyBean();
    for (String item : fieldStrArray) {
        String[] parts = item.split(":");
        String key = parts[0].replaceAll("\"", "").trim();
        String value = parts[1].replaceAll("\"", "").trim();
        Field field = MyBean.class.getDeclaredField(key);
        if (field.getType() == String.class) {
            field.set(bean, value);
        } else if (field.getType() == Integer.class) {
            field.set(bean, Integer.valueOf(value));
        }
    }
    System.out.println(bean);
}

Fastjson replaces this reflective approach with ASM‑generated deserializer classes that hard‑code field handling, removing reflection entirely. An example of the generated deserializer for MyBean is:

public class FastjsonASMDeserializer_1_MyBean extends JavaBeanDeserializer {
    public char[] id_asm_prefix__ = "\"id\":".toCharArray();
    public char[] name_asm_prefix__ = "\"name\":".toCharArray();
    public char[] score_asm_prefix__ = "\"score\":".toCharArray();

    @Override
    public Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, int features) {
        JSONLexerBase lexer = (JSONLexerBase) parser.lexer;
        MyTest.MyBean localMyBean = new MyTest.MyBean();
        String id = lexer.scanFieldString(this.id_asm_prefix__);
        if (lexer.matchStat > 0) {
            localMyBean.id = id;
        }
        String name = lexer.scanFieldString(this.name_asm_prefix__);
        if (lexer.matchStat > 0) {
            localMyBean.name = name;
        }
        Integer score = lexer.scanFieldInt(this.score_asm_prefix__);
        if (lexer.matchStat > 0) {
            localMyBean.score = score;
        }
        return localMyBean;
    }
}

These two examples illustrate how ASM empowers low‑level libraries to achieve dynamic proxying and high‑speed JSON processing, a technique worth mastering when building custom tools or studying open‑source frameworks.

Summary

cglib uses ASM to generate a subclass proxy that intercepts methods, requiring the target class not to be final .

Fastjson employs ASM to generate a dedicated deserializer for a bean, eliminating reflection and boosting performance.

JavaBytecodefastjsonDynamic ProxyASMCglib
Top Architecture Tech Stack
Written by

Top Architecture Tech Stack

Sharing Java and Python tech insights, with occasional practical development tool tips.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.