Package cn.com.bricks.dynamic.weaving

Source Code of cn.com.bricks.dynamic.weaving.UnitTestTransformer

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cn.com.bricks.dynamic.weaving;

import cn.com.bricks.dynamic.loader.util.DynamicDeployUtil;
import cn.com.bricks.dynamic.weaving.utils.WeavingConfigUtil;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;

/**
*
* @author kete
*/
public class UnitTestTransformer implements ClassFileTransformer {

    private Log log = LogFactory.getLog(UnitTestTransformer.class);

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("javaagent start");
        inst.addTransformer(new UnitTestTransformer());

    }

    @Override
    public byte[] transform(ClassLoader loader, String className,
            Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
            byte[] classfileBuffer) throws IllegalClassFormatException {
        byte[] result = classfileBuffer; //定义新的字节码存储变量
        if (log.isTraceEnabled()) {
            log.trace("Loading " + className + " by " + loader.toString());
        }
        // 判断是否重新加载类文件,并实现动态部署
        if (DynamicDeployUtil.isReloadResource(className)) {
            if (log.isTraceEnabled()) {
                log.trace("Reloading " + className + " by " + loader.toString());
            }
            result = DynamicDeployUtil.findResource(className);
        }
        //在此通过修改类的字节码 classfileBuffer,来更改类。
        if (!WeavingConfigUtil.INSTANCE.isWeavingLoader(loader)) {
            return result;
        }
        boolean isWeavingClass = true;
        // 此处判断不需要修改的类将不进行修改
        if (WeavingConfigUtil.INSTANCE.isNoWeavingClassAndPkgs(className)) {
            isWeavingClass = false;
        }
        boolean isWeavingPkgs = false;
        // 处理包的weaving
        String jarName = (protectionDomain != null && protectionDomain.getCodeSource() != null && protectionDomain.getCodeSource().getLocation() != null) ? protectionDomain.getCodeSource().getLocation().getFile() : "";
        // 如果当前路径为classes下或为自定义的classloader(protectionDomain为NULL)需要weaving
        if ((isWeavingClass && WeavingConfigUtil.INSTANCE.isWeavingJar(jarName)) || protectionDomain == null) {
            isWeavingPkgs = true;
        }

        // weaving处理
        if (isWeavingClass && isWeavingPkgs || WeavingConfigUtil.INSTANCE.isReplaceClass(className)) {
            if (log.isTraceEnabled()) {
                log.trace("Weaving " + className + " by ASM4.1");
            }
            ClassReader reader = new ClassReader(result);
            ClassWriter writer = new ClassWriter(WeavingConfigUtil.INSTANCE.isDebug() ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS);
            ClassVisitor adapter = new UnitClassWeavingAdapter(writer, className);
            reader.accept(adapter, WeavingConfigUtil.INSTANCE.isDebug() ? ClassReader.SKIP_FRAMES : ClassReader.SKIP_DEBUG);

            result = writer.toByteArray();
        }

        return result; //返回新的字节码
    }
}
TOP

Related Classes of cn.com.bricks.dynamic.weaving.UnitTestTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.