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

网站方案书免费wordpress删除管理站点链接

网站方案书免费,wordpress删除管理站点链接,友链网站,长沙it公司框架中建立浮动框架自从引入Java注释以来#xff0c;它已成为大型应用程序框架API的组成部分。 此类API的很好示例是Spring或Hibernate的示例#xff0c;其中添加了几行注释代码可实现非常复杂的程序逻辑。 尽管人们可以争论这些特定API的缺点#xff0c;但大多数开发人员都… 框架中建立浮动框架 自从引入Java注释以来它已成为大型应用程序框架API的组成部分。 此类API的很好示例是Spring或Hibernate的示例其中添加了几行注释代码可实现非常复杂的程序逻辑。 尽管人们可以争论这些特定API的缺点但大多数开发人员都会同意这种使用正确的声明式编程形式具有很强的表现力。 但是只有很少的开发人员选择为其自己的框架或应用程序中间件实现基于注释的API主要是因为它们难以实现。 在下一篇文章中我想说服您相比之下此类API的实现非常简单并且使用正确的工具不需要任何有关Java内在函数的专门知识。 实施基于注释的API时一个非常明显的问题是正在执行的Java运行时未处理注释。 结果不可能为给定的用户注释分配特定的含义。 例如考虑我们想要定义一个Log批注该批注我们希望提供它用于简单地记录每次被注释方法的调用 class Service {Logvoid doSomething() { // do something ...} } 由于Log批注Log其Log就无法执行程序逻辑因此由批注的用户来执行请求的日志记录。 显然这使注释几乎无用因为我们无法调用doSomething方法并且期望在日志中观察到相应的语句。 到目前为止注释仅用作标记而没有贡献任何程序逻辑。 缩小差距 为了克服这种明显的局限性许多注释驱动的框架将子类与方法重写结合使用以实现与特定注释关联的逻辑。 这通常称为子类检测。 对于建议的Log注释子类检测将导致创建一个类似于以下LoggingService class LoggingService extends Service {Overridevoid doSomething() { Logger.log(doSomething() was called);super.doSomething();} } 当然上述类通常不需要显式实现。 相反一种流行的方法是仅在运行时使用诸如cglib或Javassist之类的代码生成库来生成此类。 这两个库均提供用于创建程序增强子类的简单API。 作为将类的创建延迟到运行时的一个很好的副作用建议的日志记录框架无需任何特殊的准备就可以使用并且始终与用户代码保持同步。 如果将以更明确的方式创建类例如通过在构建过程中编写Java源文件来创建类则情况并非如此。 但是它可扩展吗 然而该解决方案带来了另一个缺点。 通过将注释的逻辑放入生成的子类中必须不再通过其构造函数实例化示例Service类。 否则仍将不记录带注释的方法的调用显然调用构造函数不会创建所需子类的实例。 更糟糕的是当使用建议的运行时生成方法时由于Java编译器不知道运行时生成的类因此LoggingService无法直接实例化。 因此诸如Spring或Hibernate之类的框架使用对象工厂并且不允许直接实例化被视为其框架逻辑一部分的对象。 使用Spring由于工厂的所有对象都是已经由框架首先创建的托管bean因此自然可以通过工厂创建对象。 同样大多数Hibernate实体是作为查询结果创建的因此不会显式实例化。 但是例如当保存尚未在数据库中表示的实体实例时Hibernate的用户需要用存储后从Hibernate返回的实例替换最近保存的实例。 通过查看有关Hibernate的问题忽略这种替代已经构成了一个常见的初学者错误。 除此之外由于有了这些工厂子类​​检测对于框架用户来说几乎是透明的因为Java的类型系统暗示子类可以替代其任何超类。 因此 LoggingService的实例可以在用户期望用户定义的Service类的实例的任何地方使用。 不幸的是事实证明这种批准的实例工厂方法难以实现建议的Log注释因为这将需要对可能被注释的类的每个单个实例使用工厂。 显然这将增加大量的样板代码。 通过不将日志记录指令硬编码到方法中我们甚至可能创建比我们避免的样板更多的样板。 同样意外使用构造函数会给Java程序带来细微的错误因为此类实例上的注释将不再像我们期望的那样被对待。 另一个问题是工厂不容易构成。 如果我们想向已经是Hibernate bean的类添加Log注释怎么办 这听起来很琐碎但需要进行大量配置才能合并两个框架的工厂。 最后最终的工厂膨胀的代码看起来不会太漂亮以致于无法使用该框架进行迁移。 这是使用Java代理进行检测的地方。 这种低估的检测形式为讨论的子类检测提供了很好的选择。 一个简单的代理 Java代理由一个简单的jar文件表示。 与普通Java程序类似Java代理将某些类定义为入口点。 然后期望此类定义一个静态方法该方法在调用实际Java程序的main方法之前将被调用 class MyAgent {public static void premain(String args, Instrumentation inst) {// implement agent here ...} } 处理Java代理时最有趣的部分是premain方法的第二个参数它表示Instrumentation接口的实例。 通过定义ClassFileTransformer此接口提供了一种挂接到Java的类加载过程的方法。 使用此类转换器我们能够在Java程序首次使用之前对其进行增强。 乍一看使用此API听起来似乎很直接但它却带来了新的挑战。 通过更改已编译的Java类表示为Java字节码来执行类文件转换。 实际上Java虚拟机不知道编程语言是什么Java。 相反它仅处理此字节码。 还要感谢字节码抽象JVM能够轻松运行其他语言例如Scala或Groovy。 结果注册的类文件转换器仅提供将给定的字节代码数组转换为另一个数组的功能。 即使诸如ASM或BCEL之类的库提供了用于处理已编译Java类的简单API也只有很少的开发人员具有处理原始字节码的经验。 更糟糕的是正确执行字节码操作通常很麻烦甚至通过抛出令人讨厌且不可恢复的VerifierError来弥补虚拟机的小错误。 幸运的是有更好更轻松的方式来处理字节码。 我编写和维护的Byte Buddy库提供了一个简单的API用于处理已编译的Java类和创建Java代理。 在某些方面Byte Buddy是类似于cglib和Javassist的代码生成库。 但是除了那些库之外Byte Buddy还提供了一个统一的API用于实现子类和重新定义现有的类。 但是对于本文我们只希望研究使用Java代理重新定义类。 好奇的读者可以参考Byte Buddy的网页该网页提供了有关其完整功能集的详细教程 。 使用Byte Buddy作为简单代理 字节伙伴提供的一种定义工具的方法是使用依赖项注入。 这样做一个拦截器类由任何普通的旧Java对象表示都可以通过其参数的注释简单地请求任何必需的信息。 例如通过在“ Method类型的参数上使用Byte Buddy的Origin批注Byte Buddy可以Origin出拦截器想知道要拦截的方法。 这样我们可以定义一个通用拦截器该拦截器始终知道要拦截的方法 class LogInterceptor {static void log(Origin Method method) {Logger.log(method was called);} } 当然Byte Buddy附带了更多注释。 但是此拦截器如何表示我们打算用于拟议的日志记录框架的逻辑 到目前为止我们仅定义了一个记录方法调用的拦截器。 我们错过的是该方法的原始代码的后续调用。 幸运的是Byte Buddy的乐器是可以组合的。 首先我们为最近定义的LogInterceptor定义一个MethodDelegation 默认情况下该方法在每次调用方法时都会调用拦截器的静态方法。 从此开始我们可以随后以SuperMethodCall表示的原始方法代码的后续调用来组成委托 MethodDelegation.to(LogInterceptor.class).andThen(SuperMethodCall.INSTANCE) 最后我们需要告知Byte Buddy有关指定工具要拦截的方法的信息。 如前所述我们希望该工具适用于任何使用Log注释的方法。 在字节伙伴中可以使用类似于Java 8谓词的ElementMatcher来标识方法的这种属性。 在静态实用程序类ElementMatchers 我们已经可以找到合适的匹配器来标识带有给定注释的方法 ElementMatchers.isAnnotatedWith(Log.class) 。 有了这些我们现在可以定义一个实现建议的日志记录框架的代理。 对于Java代理Byte Buddy提供了一个实用程序API该API建立在我们刚刚讨论的类修改API的基础上。 与后一种API相似它被设计为领域特定的语言因此仅通过查看实现即可轻松理解其含义。 如我们所见定义这样的代理仅需要几行代码 class LogAgent {public static void premain(String args, Instrumentation inst) {new AgentBuilder.Default().rebase(ElementMatchers.any()).transform( builder - return builder.method(ElementMatchers.isAnnotatedWith(Log.class)).intercept(MethodDelegation.to(LogInterceptor.class).andThen(SuperMethodCall.INSTANCE)) ).installOn(inst);} } 请注意这种最小的Java代理不会干扰应用程序的其余部分因为任何执行代码都会观察所检测的Java类就像将日志记录语句硬编码到任何带注释的方法中一样。 现实生活如何 当然提出的基于代理的记录器是一个简单的例子。 通常情况下开箱即用的框架提供了类似的功能例如Spring或Dropwizard都是很棒的。 但是对于如何解决编程问题人们通常也对此类框架持意见。 对于大量的软件应用程序这可能不是问题。 但是有时这些意见会阻碍更大的发展。 然后围绕框架关于如何做事情的假设进行工作不仅会导致一些问题而且还会导致抽象的泄漏并可能导致软件维护成本激增。 尤其是当应用程序随着时间增长和变化并且其需求与基础框架所提供的需求有所不同时尤其如此。 相反当以图片混合的方式组成更专业的框架或库时一个简单地用另一个替换了有问题的组件。 如果这两种方法都不起作用甚至可以实施自定义解决方案而不会干扰应用程序的其余部分。 据我们了解这似乎很难在JVM上实现这主要是Java严格类型系统的结果。 但是使用Java代理很有可能克服这些类型限制。 我的观点是我认为至少所有跨领域的关注都应该由代理驱动的专用库来解决而不是由整体框架的内置模块来解决。 我真的希望更多的应用程序会考虑这种方法。 在最琐碎的情况下使用代理在感兴趣的方法上注册侦听器并将其从那里获取就足够了。 这种组成代码模块的间接方法避免了我在遇到的大部分Java应用程序中观察到的强大凝聚力。 作为一个很好的副作用它也使测试非常容易。 与运行测试类似在启动应用程序时不添加代理可以有针对性地禁用某些应用程序功能例如日志记录。 所有这些都无需更改代码行也不会使应用程序崩溃因为JVM只是忽略了它在运行时无法解析的注释。 安全性日志记录缓存有许多原因应以建议的方式处理这些主题甚至更多。 因此有时创建代理而不是框架。 翻译自: https://www.javacodegeeks.com/2015/01/make-agents-not-frameworks.html框架中建立浮动框架
http://www.zqtcl.cn/news/184531/

相关文章:

  • 如何做视频解析网站wordpress 关闭评论
  • 安福网站建设微信开发者工具怎么下载
  • 网罗设计网站威海网页设计制作公司
  • 网站用cmswordpress插件怎么做
  • 如何办好公司网站元器件网站搭建
  • 建设领域行政处罚查询网站wordpress数据库发文章
  • 怎么做网页的多开器宿迁seo优化
  • 别人帮做的网站怎么修改病句店铺引流的30种方法
  • 网站备案幕布怎么申请绍兴cms建站模板
  • 做网站熊掌号软件设计公司排名
  • 深圳 做网站学做西点的网站
  • 静态网站安全性百度服务平台
  • 网站vi设计公司网站建设app
  • 书店网站建设策划书总结每天看七个广告赚40元的app
  • 做网站的属于什么专业成都广告制作安装公司
  • 天津市网站建设公司网站制作费用
  • 网站制作公司 郑州wordpress图片中文不显示解决
  • 网站建设模式有哪些方面jquery做的装修网站
  • 佛山手机建网站企业网站公司单位有哪些
  • 给企业做网站的平台有没有专门做衣服搭配的网站
  • 青岛本地网站最近军事新闻大事
  • 潍坊哪里有做360网站的成都官微最新发布
  • 还有哪些网站可以做淘宝活动企业建设网站的方式
  • 上海技术公司做网站2022引流人脉推广软件
  • 网站排名优化技术安徽省城乡和建设厅网站
  • 平阴县建设工程网站英文网站模板制作
  • 网站制作超链接怎么做厦门公司建站
  • 阿里云做的网站怎么备份建筑设计网站issuu
  • 网上做设计网站广西做网站找谁
  • 网站优化成本建设项目网站备案申请表