bytebuddy实现原理分析 &源码分析 (三)- advice 详解

本文深入探讨了ByteBuddy的advice机制,包括AsmVisitorWrapper的使用,如ForDeclareFields和ForDeclaredMethods,以及Advice的核心类和其实现,如ArgumentHandler、MethodSizeHandler和OffsetMapping。讲解了如何通过ASM进行字节码增强,实现切面编程。
摘要由CSDN通过智能技术生成

bytebuddy实现原理分析 &源码分析(一)
bytebuddy实现原理分析 &源码分析 (二)
bytebuddy实现原理分析 &源码分析 (三)
bytebuddy实现原理分析 &源码分析 (四)

八、advice

增强,切面编程。
asm入门
asm手册
大致了解了asm,就可以知道Visitor是asm进行读写解析.class字节码文件的核心api。切面的原理就是匹配所有的方法,在方法前后加入额外的方法,AdviceAdapter类提供了onMethodEnteronMethodExit两个方法,实现就可以做到简单的切面。

bytebuddy 的增强就是基于 asm的core API然后提供了一些列注解,方法用户使用。
在这里插入图片描述

8.1 AsmVisitorWrapper

就是对visitor的一个封装。
visitor以分为 ClassReaderClassWriter

首先 提供了一个字段 flags:代表了标志。
在这里插入图片描述

核心方法

  • int mergeWriter(int flags); 合并写标记 flags|foo
  • int mergeReader(int flags); 合并读标记
  • ClassVisitor wrap(TypeDescription instrumentedType,
    ClassVisitor classVisitor,
    Implementation.Context implementationContext,
    TypePool typePool,
    FieldList<FieldDescription.InDefinedShape> fields,
    MethodList<?> methods,
    int writerFlags,
    intreaderFlags);
    把一个DynamicType定义的类,使用ClassVisitor生成字节码。
    instrumentedType ,被修改的类型;implementationContext,就是定义了改动的字节码实现;TypePool 缓存池;MethodList 方法列表;

8.1.1 ForDeclareFields

在这里插入图片描述

8.1.1.1 Entry
  • matcher 用来命中的对象
  • FieldVisitorWrapper 的 封装了要被修改filed对应的Vistor。

这个类的作用是报存 matcher和visitor的对应关系。使用matcher命中被修改的区域,visitor来应用修改逻辑。

        protected static class Entry implements ElementMatcher<FieldDescription.InDefinedShape>, FieldVisitorWrapper {
   

            /**
             * The matcher to identify fields to be wrapped.
             */
            private final ElementMatcher<? super FieldDescription.InDefinedShape> matcher;

            /**
             * The field visitor wrapper to be applied if the given matcher is matched.
             */
            private final List<? extends FieldVisitorWrapper> fieldVisitorWrappers;

            /**
             * Creates a new entry.
             *
             * @param matcher              The matcher to identify fields to be wrapped.
             * @param fieldVisitorWrappers The field visitor wrapper to be applied if the given matcher is matched.
             */
            protected Entry(ElementMatcher<? super FieldDescription.InDefinedShape> matcher, List<? extends FieldVisitorWrapper> fieldVisitorWrappers) {
   
                this.matcher = matcher;
                this.fieldVisitorWrappers = fieldVisitorWrappers;
            }

            /**
             * {@inheritDoc}
             */
            public boolean matches(FieldDescription.InDefinedShape target) {
   
                return target != null && matcher.matches(target);
            }

            /**
             * {@inheritDoc}
             */
            public FieldVisitor wrap(TypeDescription instrumentedType, FieldDescription.InDefinedShape fieldDescription, FieldVisitor fieldVisitor) {
   
                for (FieldVisitorWrapper fieldVisitorWrapper : fieldVisitorWrappers) {
   
                    fieldVisitor = fieldVisitorWrapper.wrap(instrumentedType, fieldDescription, fieldVisitor);
                }
                return fieldVisitor;
            }
        }
8.1.1.2 DispatchingVisitor

继承ClassVisitor方法

  protected class DispatchingVisitor extends ClassVisitor {
   

            /**
             * The instrumented type.
             */
            private final TypeDescription instrumentedType;

            /**
             * A mapping of fields by their name and descriptor key-combination.
             */
            private final Map<String, FieldDescription.InDefinedShape> fields;

            /**
             * Creates a new dispatching visitor.
             */
            protected DispatchingVisitor(ClassVisitor classVisitor, TypeDescription instrumentedType, Map<String, FieldDescription.InDefinedShape> fields) {
   
                super(OpenedClassReader.ASM_API, classVisitor);
                this.instrumentedType = instrumentedType;
                this.fields = fields;
            }

            @Override
            public FieldVisitor visitField(int modifiers, String internalName, String descriptor, String signature, Object defaultValue) {
   
                FieldVisitor fieldVisitor = super.visitField(modifiers, internalName, descriptor, signature, defaultValue);
                FieldDescription.InDefinedShape fieldDescription = fields.get(internalName + descriptor);
                if (fieldVisitor != null && fieldDescription != null) {
   
                    for (Entry entry : entries) {
   
                        if (entry.matches(fieldDescription)) {
   
                            fieldVisitor = entry.wrap(instrumentedType, fieldDescription, fieldVisitor);
                        }
                    }
                }
                return fieldVisitor;
            }
        }
  • instrumentedType ,是被修改的类。
  • fields, 一个map结构,一个fields。
  • visitField,使用entry.wrap最终将fieldVisitor 委托给FieldVisitorWrapper接口。所以FieldVisitorWrapper的子类只要实现FieldVisitorWrapperwrap方法,在其中定义具体的修改逻辑。
  public interface FieldVisitorWrapper {
   

            /**
             * Wraps a field visitor.
             *
             * @param instrumentedType The instrumented type.
             * @param fieldDescription The field that is currently being defined.
             * @param fieldVisitor     The original field visitor that defines the given field.
             * @return The wrapped field visitor.
             */
            FieldVisitor wrap(TypeDescription instrumentedType, FieldDescription.InDefinedShape fieldDescription, FieldVisitor fieldVisitor);
        }
8.1.1.3 ForDeclaredField 的内部实现

也是封装了上面提到的类

   class ForDeclaredFields extends AbstractBase {
   

        /**
         * The list of entries that describe matched fields in their application order.
         */
        private final List<Entry> entries;

        /**
         * Creates a new visitor wrapper for declared fields.
         */
        public ForDeclaredFields() {
   
            this(Collections.<Entry>emptyList());
        }

        /**
         * Creates a new visitor wrapper for declared fields.
         *
         * @param entries The list of entries that describe matched fields in their application order.
         */
        protected ForDeclaredFields(List<Entry> entries) {
   
            this.entries = entries;
        }

        /**
         * Defines a new field visitor wrapper to be applied if the given field matcher is matched. Previously defined
         * entries are applied before the given matcher is applied.
         *
         * @param matcher             The matcher to identify fields to be wrapped.
         * @param fieldVisitorWrapper The field visitor wrapper to be applied if the given matcher is matched.
         * @return A new ASM visitor wrapper that applied the given field visitor wrapper if the supplied matcher is matched.
         */
        public ForDeclaredFields field(ElementMatcher<? super FieldDescription.InDefinedShape> matcher, FieldVisitorWrapper... fieldVisitorWrapper) {
   
            return field(matcher, Arrays.asList(fieldVisitorWrapper));
        }

        /**
         * Defines a new field visitor wrapper to be applied if the given field matcher is matched. Previously defined
         * entries are applied before the given matcher is applied.
         *
         * @param matcher              The matcher to identify fields to be wrapped.
         * @param fieldVisitorWrappers The field visitor wrapper to be applied if the given matcher is matched.
         * @return A new ASM visitor wrapper that applied the given field visitor wrapper if the supplied matcher is matched.
         */
        public ForDeclaredFields field(ElementMatcher<? super FieldDescription.InDefinedShape> matcher, List<? extends FieldVisitorWrapper> fieldVisitorWrappers) {
   
            return new ForDeclaredFields(CompoundList.of(entries, new Entry(matcher, fieldVisitorWrappers)));
        }

        /**
         * {@inheritDoc}
         */
        public ClassVisitor wrap<
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值