当前位置: 首页 > news >正文

军事前沿最新消息流程优化的七个步骤

军事前沿最新消息,流程优化的七个步骤,网络广告的投放技巧,本地wordpress 慢目录 一、拦截方法及其优先级二、方法委托调用三、方法委托调用支持的注解 一、拦截方法及其优先级 class Foo {public String bar() { return null; }public String foo() { return null; }public String foo(Object o) { return null; } }Foo dynamicFoo new ByteBuddy().s…

目录

    • 一、拦截方法及其优先级
    • 二、方法委托调用
    • 三、方法委托调用支持的注解

一、拦截方法及其优先级

class Foo {public String bar() { return null; }public String foo() { return null; }public String foo(Object o) { return null; }
}Foo dynamicFoo = new ByteBuddy().subclass(Foo.class).method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!")).method(named("foo")).intercept(FixedValue.value("Two!")).method(named("foo").and(takesArguments(1))).intercept(FixedValue.value("Three!")).make().load(getClass().getClassLoader()).getLoaded().newInstance();

在上面的例子中,我们为重写方法定义了三个不同的规则:

  • 第一条规则涉及Foo类中定义的任何方法,即示例类中的所有三个方法。
  • 第二个规则匹配两个名为foo的方法,foo是前一个选择的子集。
  • 最后一个规则只匹配foo(Object)方法,这是对前一个选择的进一步简化。

但是考虑到这种选择重叠,Byte Buddy如何决定将哪个规则应用于哪个方法呢?
Byte Buddy以堆栈形式组织重写方法的规则。这意味着每当你注册一个新规则来覆盖一个方法时,都会被推到这个堆栈的顶部,并且总是首先应用(Last Win),直到添加了一个新的规则,这个规则的优先级更高。

对于上面的例子,这意味着:

  • bar()方法首先对named("foo").and(takesArguments(1))进行匹配,然后对named("foo")进行匹配,其中两次匹配尝试都是否定的。最后,isDeclaredBy(Foo.class匹配器允许重写bar()方法以返回"One!"
  • 类似地,foo()方法首先与named("foo").and(takesArguments(1))进行匹配,其中缺少的参数导致匹配不成功。在此之后,named("foo")匹配器确定一个正匹配,以便重写foo()方法以返回"Two!"
  • foo(Object)立即被named("foo").and(takesArguments(1))匹配器匹配,这样重写的实现返回"Three!"

由于这种组织方式,您应该总是最后注册更具体的方法匹配器。否则,之后注册的任何不太具体的方法匹配器可能会阻止应用之前定义的规则。注意,ByteBuddy配置允许定义一个ignoreMethod属性。与此方法匹配器成功匹配的方法永远不会被覆盖。默认情况下,Byte Buddy不覆盖任何合成方法。

二、方法委托调用

class Source {public String hello(String name) { return null; }
}class Target {public static String hello(String name) {return "Hello " + name + "!";}
}String helloWorld = new ByteBuddy().subclass(Source.class).method(named("hello")).intercept(MethodDelegation.to(Target.class)).make().load(getClass().getClassLoader()).getLoaded().newInstance().hello("World");

如上代码将Source.hello方法委托为Target.hello方法(Target中的方法需定义为static),
TargetSource间根据方法名、方法参数列表、返回值去进行匹配。


Target中的方法名也可以不一样,则会自动根据方法参数列表、返回值,如下Target定义效果相同:

class Target {public static String intercept(String name) {return "Hello " + name + "!";}
}

对于如下Target定义,更具体的参数类型(相较于Object)会优先生效,使用如下Target定义去代理Source,最终生效的是String intercept(String name)方法:

class Target {public static String intercept(String name) { return "Hello " + name + "!"; }public static String intercept(int i) { return Integer.toString(i); }public static String intercept(Object o) { return o.toString(); }
}

三、方法委托调用支持的注解

如上方法委托方式中,支持注解汇总如下表:

注解说明
@Argument(int)按源方法参数列表顺序提取并设置参数(从0开始),
例如:void foo(@Argument(0) Object o1, @Argument(1) Object o2)
@AllArguments从源方法中提取全部参数,
例如:void foo(@AllArgument Object[] params)
@This注入当前动态生成的对象实例,
允许在拦截器中调用当前实例的方法,
使用 @This 注解的一个典型原因是访问实例的字段。
@Super注入原来被覆盖的父类对象实例,
允许在拦截器中调用父类的方法,
可用于调用被重写的实现。
@SuperCall标注Callable、Runnable参数上,用于调用原实现,
例如:void foo(@SuperCall Callable<List<String> callable)
其中Callable的模版参数List<String>表示原方法返回值类型。
@DefaultCall类似@SuperCall,用于调用interface中的default方法实现。
@Default类似@Super,用于调用interface中的default方法实现。
@RuntimeType宽松的类型匹配(避免严格的类型匹配),
标注在方法上表示放宽返回类型检查,
标注在参数上表示放宽此参数类型检查。
@FieldValue将当前动态生成对象实例的field(属性值)注入到指定参数
@Origin
  • @Origin 注解的参数必须用于以下类型之一:MethodConstructorExecutableClassMethodHandleMethodTypeStringint
  • 根据参数的类型,它会被分配一个对原始方法或构造函数的 MethodConstructor 引用,或者一个对动态创建的 Class 的引用。在使用 Java 8 时,还可以通过在拦截器中使用 Executable 类型来接收方法或构造函数引用。
  • 如果注解参数是 String 类型,则该参数会被分配 MethodtoString 方法返回的值。一般来说,我们建议尽可能使用这些 String 值作为方法标识符,并不鼓励使用 Method 对象,因为它们的查找会引入显著的运行时开销。
  • 为了避免这种开销,@Origin 注解还提供了一个属性用于缓存这些实例以供重用。请注意,MethodHandleMethodType 存储在类的常量池中,因此使用这些常量的类至少必须是 Java 7 版本。
  • 为了避免使用反射在另一个对象上反射性地调用拦截的方法,我们进一步建议使用 @Pipe 注解。
  • 当在 int 类型的参数上使用 @Origin 注解时,它会被分配被拦截方法的修饰符。

@SuperCall示例:

class MemoryDatabase {public List<String> load(String info) {return Arrays.asList(info + ": foo", info + ": bar");}
}class LoggerInterceptor {public static List<String> log(@SuperCall Callable<List<String>> zuper)throws Exception {System.out.println("Calling database");try {return zuper.call();} finally {System.out.println("Returned from database");}}
}MemoryDatabase loggingDatabase = new ByteBuddy().subclass(MemoryDatabase.class).method(named("load")).intercept(MethodDelegation.to(LoggerInterceptor.class)).make().load(getClass().getClassLoader()).getLoaded().newInstance();

@Super示例:

class ChangingLoggerInterceptor {public static List<String> log(String info, @Super MemoryDatabase zuper) {System.out.println("Calling database");try {return zuper.load(info + " (logged access)");} finally {System.out.println("Returned from database");}}
}

@RuntimeType示例:

class Loop {public String loop(String value) { return value; }public int loop(int value) { return value; }
}//使用此Interceptor会同时匹配Loop中的2个方法
class Interceptor {@RuntimeTypepublic static Object intercept(@RuntimeType Object value) {System.out.println("Invoked method with: " + value);return value;}
}

@FieldValue示例:

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.bind.annotation.FieldValue;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;public class FieldValueExample {public static void main(String[] args) throws Exception {Class<?> dynamicType = new ByteBuddy().subclass(Person.class).method(ElementMatchers.named("printName")).intercept(MethodDelegation.to(PersonInterceptor.class)).make().load(FieldValueExample.class.getClassLoader()).getLoaded();Person person = (Person) dynamicType.getDeclaredConstructor().newInstance();person.setName("John Doe");person.printName();}public static class Person {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void printName() {System.out.println("Name: " + name);}}public static class PersonInterceptor {public static void intercept(@FieldValue("name") String name) {System.out.println("Intercepted name: " + name);}}
}

参考:
https://bytebuddy.net/#
Byte Buddy 教程 - https://notes.diguage.com/byte-buddy-tutorial/
Byte Buddy官方教程 - 中文翻译专栏
https://github.com/raphw/byte-buddy
https://www.baeldung.com/byte-buddy
简书Wpixel - ByteBuddy系列(一、二、… 十四)

http://www.dtcms.com/a/413928.html

相关文章:

  • 东营网站关键词商河网站建设
  • 上海做淘宝网站设计广州网站建设q.479185700強
  • 高端响应式网站建设仓山区城乡建设局网站
  • 电商网站前端制作分工cm在线设计平台
  • 上海的网站名wordpress还原旧版本
  • 网站开发付款好资源源码网站
  • 网站自己备案下载服务器安装
  • 做钓鱼网站的公司文创产品推广方案
  • 网站建设玖金手指谷哥二八对电子商务网站建设的感想
  • 视频收费网站怎么做东风多利卡道路清障车做网站
  • 专业网站设计公司推荐ps网页版在线使用最全版
  • 企业网站的网络营销功能包括设计师常用的图片网站
  • 网站设计模版个人备案网站可以做新闻站吗
  • 成都网站建设 seo软文模板
  • 建设部政务网站建设网站建设教程菜鸟物流
  • 建设银行注册网站登录建筑培训网
  • 一家只做正品的网站繁体企业网站源码
  • 如何建设网站服务器外贸行业前景怎么样
  • 网站建设公司宣传文案网页制作模板
  • 电商网站怎样做最近一星期的新闻
  • 旅游网站开发的意义相关资料沈阳网站建设哪里的公司比较好
  • 旅游网站建设受众分析做班级网站的详细计划书
  • 网站备案重要性温州市城乡建设职工中等专业学校官网
  • 在建设主题网站时dede 更新网站地图
  • html5个人网站源码wordpress themes
  • 网站优化方案基本流程青岛哪里做网站
  • 中国响应式网站建设seo的宗旨是
  • 网络彩票网站开发网站建设色系搭配
  • wap网站定位展示型装饰网站模板
  • .net网站程序千峰网课