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

求大佬给个资源找累了东莞搜索网络优化

求大佬给个资源找累了,东莞搜索网络优化,门户网站简称,坪地网站制作目录 一、拦截方法及其优先级二、方法委托调用三、方法委托调用支持的注解 一、拦截方法及其优先级 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/wzjs/415348.html

相关文章:

  • 我的世界充值网站怎么做快速优化网站排名的方法
  • 邢台地区网站建设独立seo引擎搜索网站
  • 绵阳网站建设多少钱济南seo优化外包服务
  • golang网站开发教程秦皇岛seo优化
  • 网页设计工资2019青岛seo优化
  • 可以做淘宝推广的网站今天的国内新闻
  • 数据库网站开发教程推广产品的方式有哪些
  • 做网站需要了解的内容杭州优化外包
  • iapp如何用网站做软件谷歌搜索排名
  • 公司网站建设制作全网站排名优化培训电话
  • 网站建设就选广告软文外链平台
  • 手机网站微信链接怎么做深圳seo优化外包公司
  • 成都网站建设哪儿济南兴田德润怎么联系网络营销的主要推广方式
  • flask做的网站如何上传最大免费发布平台
  • 泉州app网站开发价格低网站目录
  • 如何做网站教程网络推广营销方法
  • 济南官网专业关键词排名优化软件
  • app和网站的区别是什么西安分类信息seo公司
  • 网站上的动态图怎么做百度关键词搜索查询
  • 设计师接单的网站官网seo优化
  • vc 做网站源码营销策划方案公司
  • 新浪网页版电脑版湖南好搜公司seo
  • 个人网站制作网站b2b商务平台
  • 石英石台面做网单有什么网站福州seo管理
  • 国家税务总局网站官网网址黄页88推广多少钱一年
  • 网站管理系统 免费衡水seo营销
  • 新野企业网站建设深圳疫情最新消息
  • 网站开发小程序开发百度高级搜索网址
  • 网页qq登陆保护杭州seo代理公司
  • 做网站怎么备案互联网营销推广