Byte buddy 使用记录

引入maven包

           <!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
            <dependency>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy</artifactId>
                <version>1.14.5</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy-agent -->
            <dependency>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy-agent</artifactId>
                <version>1.14.5</version>
            </dependency>

## LogAgent

```bash
public class LogAgent {


    private static LogAgent instance = new LogAgent();

    private LogAgent() {
    }

    public static LogAgent getInstance() {
        return instance;
    }

    public void install() {
        synchronized (LogAgent.class) {
            ByteBuddyAgent.install();
            new AgentBuilder.Default().ignore( //忽略的包,这些包不会注入
                            nameStartsWith("org.aspectj."))
                    .or(nameStartsWith("org.groovy."))
                    .or(nameStartsWith("com.sun."))
                    .or(nameStartsWith("sun."))
                    .or(nameStartsWith("jdk."))
                    .or(nameStartsWith("org.springframework.asm."))
                    .or(nameStartsWith("com.p6spy."))
                    .or(nameStartsWith("net.bytebuddy."))
                    .type(nameStartsWith("com.xxx.")) //以com.xxx. 开头的包会注入
                    //定义规则,将TimeLogAdvice和注解TimeLog绑定
                    .transform((builder, type, classLoader, module,domain) ->
                            builder.visit(Advice.to(TimeLogAdvice.class)
                                    .on(ElementMatchers.named("org.springframework.web.bind.annotation.RestController")
                                            .and(ElementMatchers.named("org.springframework.stereotype.Controller")))

//                                    .on(ElementMatchers.isAnnotatedWith(named("org.springframework.web.bind.annotation.RestController")))

                            ))
                    .with(new AgentBuilder.Listener() {
                        @Override
                        public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
                        }

                        @Override
                        public void onTransformation(net.bytebuddy.description.type.TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {

                        }

                        @Override
                        public void onIgnored(net.bytebuddy.description.type.TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {

                        }

                        @Override
                        public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
                            LoggingUtils.error(LogAgent.class, typeName, throwable);
                        }

                        @Override
                        public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
                        }
                    })
                    .installOnByteBuddyAgent();
            LoggingUtils.info(LogAgent.class, "agent install finished");
        }
    }
}

定义切面方法

public class TimeLogAdvice {

    @Advice.OnMethodEnter //方法进入前记录开始时间
    static long enter(@Advice.AllArguments Object args[], @Advice.Origin Method method) {
        return System.currentTimeMillis();
    }

    @Advice.OnMethodExit(onThrowable = Exception.class)
    static void exit(@Advice.Enter long startTime,
                     @Advice.Return(typing= Assigner.Typing.DYNAMIC) Object result,
                     @Advice.Origin Method method,
                     @Advice.Thrown Throwable t
    ) {
        if(t!=null){
            LoggingUtils.error(method.getDeclaringClass(), method.getName(),t);
        }else{
            LoggingUtils.info(method.getDeclaringClass(), "[TIMELOG][{}.{}()]: {} ms", method.getDeclaringClass(),
                    method.getName(), (System.currentTimeMillis() - startTime));
        }
    }
}

LogUtil

public class LoggingUtils {
    private static Logger logger = LoggerFactory.getLogger(LoggingUtils.class);

    public static boolean isDebugEnabled(){
        return logger.isDebugEnabled();
    }

    public static boolean isInfoEnabled(){
        return logger.isInfoEnabled();
    }

    public static boolean isErrorEnabled(){
        return logger.isErrorEnabled();
    }

    public static void debug(Class clazz, String msg, Object... args) {
        if (clazz != null) {
            logger = LoggerFactory.getLogger(clazz);
        }
        logger.debug(msg, args);
    }

    public static void info(Class clazz, String msg, Object... args) {
        if (clazz != null) {
            logger = LoggerFactory.getLogger(clazz);
        }
        logger.info(msg, args);
    }
    public static void error(Class clazz,String msg,Throwable throwable) {
        if (clazz != null) {
            logger = LoggerFactory.getLogger(clazz);
        }
        logger.error(msg, throwable);
    }
}

定义加载点

public class AppEnvListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
        LogAgent.getInstance().install();  //监听程序准备事件,注入
    }
}

定义 resources/META-INF/spring.factories


org.springframework.context.ApplicationListener=\
com.xxx.xxx.common.service.bytebuddy.AppEnvListener

运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值