从3.1版开始, Spring框架提供了对几种不同来源的抽象,通过它们您可以轻松地配置应用程序: Environment
。
在这篇文章中,我描述了一个微基准测试,我可以证明该基准测试是一个方便的API(如果您在应用程序中使用Spring的话),但它可能会导致性能下降,因此您不应在初始化代码之外使用它。
怎么运行的
在获取数字之前,请先快速浏览一下对本帖子很重要的Environment
内部。
从文档中:
属性在几乎所有应用程序中都起着重要作用,并且可能源自各种来源:属性文件,JVM系统属性,系统环境变量,JNDI,Servlet上下文参数,临时属性对象,映射等。 环境对象与属性的关系是为用户提供方便的服务界面,以配置属性源并从中解析属性。
因此,您可以使用Environment
通过简单的getProperty
调用访问所需值,从而为不同策略提供的属性提供通用接口。 看下面的Groovy代码:
@Componentpublic class Greeter {private Environment environment@Autowiredpublic Greeter greeter(Environment environment){this.environment = environment}def nickName(user) {environment.getProperty("user") // here be magic}def greet(user) {def nick = nickName(user)if (name == null) println "Hi, ${user}!"else println "Hi, ${nick}!"}}
现在,我可以在属性文件中指定昵称,以便我可以用更熟悉的昵称向用户打招呼,同时仍然可以向没有昵称的用户致敬。 整洁,但是性能如何?
现在,我可以在属性文件中指定昵称,以便我可以用更熟悉的昵称向用户打招呼,同时仍然可以向没有昵称的用户致敬。 整洁,但是性能如何?
隐藏的异常
我在调试正在处理的网站中的几个慢页面时进行了此练习:KLM主站点的目标页面 。 尽管性能总体上令人满意,但有两页不断给出高于第二的响应时间。 绝对太多了 。
在我们的代码中,我们将一些国家/地区名称转换为可查询的外部服务密钥。 我们还需要覆盖该规则的非常特殊的例外情况,即本来简单的翻译算法。 实际的代码非常类似于上面的Greeter.greet(user)
,并且Flight Recorder会话最终为我们提供了性能瓶颈(单击以打开):
对于12页的刷新,我们无声地抛出140k +异常。 例外是sloooooow ,即使您只是创建它们。
查看引发的异常,实际上很容易理解发生的情况: Environment
检查所请求的属性是否在当前JNDI上下文中定义。 但是,如果找不到该名称,则会引发NameNotFoundException
。 在我们的特定情况下,我们对异常情况使用属性查找,这意味着绝大多数情况下都会引发异常。
微型基准
我汇总了一个微型基准测试,以评估原始属性查找策略与在类构建时加载相关属性的简单方法相比的潜在性能提升。 我使用了Java Microbenchmark Harness ,它在使JVM上的微基准测试变得容易方面做得了不可思议的工作:JIT,热身,类加载,所有这些都交给您了,您可以继续进行代码测试。 结果如下(数字越大越好):
[每次调用的属性查询]结果:28917.876?(99.9%)183.630 ops / s [平均]统计数据:(最小,平均,最大)=(25688.067,28917.876,30976.876),stdev = 777.500
置信区间(99.9%):[28734.246,29101.505]
[班级建设中的财产装载]结果:159062.900?(99.9%)1013.309 ops / s [平均值]统计信息:(最小值,平均值,最大值)=(138707.926,159062.900,177183.549),stdev = 4290.413
置信区间(99.9%):[158049.591,160076.209]
不出所料,速度快了五倍。
结论
我不是Spring的忠实拥护者,但是如果您使用Spring,则Environment
类是您的应用程序配置的简单接口。 但是,除非您将JNDI用作配置属性的主要存储,否则,只有当您在初始化代码中使用它,而不是在在线处理请求时,它的性能特性才能使其成为一个很好的工具。
翻译自: https://www.javacodegeeks.com/2016/12/spring-environment-initialization-code.html