- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个拦截器来限制对任意 API 的请求。我正在尝试编写一个支持插入 TPS 值的注释,以便任何方法都可以受到速率限制。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimitMethodAnnotation {
// Permissible transactions per second.
long tps() default Long.MAX_VALUE;
// The identifier for the rate limiter. A distinct token bucket is defined
// per id.
String id();
}
而Interceptor的实现如下:-
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.isomorphism.util.TokenBucket;
import org.isomorphism.util.TokenBuckets;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* Implementation of the rate limiter.
*/
public class RateLimitMethodAnnotationInterceptor implements MethodInterceptor {
private static final ConcurrentHashMap<String, TokenBucket>
TOKEN_BUCKET_MAP = new ConcurrentHashMap<String, TokenBucket>();
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
final RateLimitMethodAnnotation rateLimitMethod =
methodInvocation.getMethod().getAnnotation(RateLimitMethodAnnotation.class);
final String rateLimitId = rateLimitMethod.id();
final long tps = rateLimitMethod.tps();
boolean proceedMethodCall = tryProceed(rateLimitId, tps);
while(!proceedMethodCall) {
Thread.sleep(getDurationTillRefillInMilliSecond(rateLimitId, tps));
proceedMethodCall = tryProceed(rateLimitId, tps);
}
return methodInvocation.proceed();
}
private boolean tryProceed(final String tokenBucketId, final long tps) {
final TokenBucket tokenBucket = TOKEN_BUCKET_MAP.get(tokenBucketId);
if (tokenBucket == null) {
TOKEN_BUCKET_MAP.put(tokenBucketId, buildTokenBucket(tps));
}
return tokenBucket.tryConsume();
}
private long getDurationTillRefillInMilliSecond(final String tokenBucketId, long tps) {
final TokenBucket tokenBucket = TOKEN_BUCKET_MAP.get(tokenBucketId);
if (tokenBucket == null) {
TOKEN_BUCKET_MAP.put(tokenBucketId, buildTokenBucket(tps));
}
return tokenBucket.getDurationUntilNextRefill(TimeUnit.MILLISECONDS);
}
private TokenBucket buildTokenBucket(final long tps) {
return TokenBuckets.builder().withCapacity(tps)
.withFixedIntervalRefillStrategy(1, 1, TimeUnit.SECONDS)
.build();
}
}
现在为了定义绑定(bind),我使用了以下代码:-
import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;
/**
* Configuration for rate limiting.
*/
public class RateLimitConfig extends AbstractModule {
public void configure() {
bindInterceptor(Matchers.any(),
Matchers.annotatedWith(RateLimitMethodAnnotation.class),
new RateLimitMethodAnnotationInterceptor());
}
}
我编写了一个非常简单的健全性测试来证明注入(inject)配置的工作原理如下:-
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* Rate limit test class.
*/
public class TestRateLimit {
final int TEST_VAL = 1;
@Test
public void testRateLimitInterceptorSanityTest() {
final RateLimitConfig config = new RateLimitConfig();
config.configure();
int retVal = stubMethod();
assertTrue(retVal == TEST_VAL);
}
@RateLimitMethodAnnotation(tps = Long.MAX_VALUE, id="stubMethod")
public int stubMethod() {
return TEST_VAL;
}
}
我最终获得了 NPE
Running TestRateLimit
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.073 sec <<< FAILURE!
testRateLimitInterceptorSanityTest(TestRateLimit) Time elapsed: 0.013 sec <<< ERROR!
java.lang.NullPointerException
at com.google.inject.AbstractModule.bindInterceptor(AbstractModule.java:167)
at org.isomorphism.annotation.RateLimitConfig.configure(RateLimitConfig.java:12)
at org.isomorphism.annotation.TestRateLimit.testRateLimitInterceptorSanityTest(TestRateLimit.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
我查看了这里的代码 https://github.com/google/guice/blob/master/core/src/com/google/inject/AbstractModule.java但没有发现任何有用的东西。我调试了代码,但我无法理解数据结构(为了完全理解框架,我必须花几个小时,但我不想花几个小时来完成简单的任务)。
1. Even for a simple task like this, Guice should not throw an NPE even if 0 methods were annotated with the annotation I have in mind.
2. Is the configure method never supposed to be called directly in code? If so there is no API given in AbstractModule nor documentation how to configure bindInterceptors. Taking the code out of RateLimitConfig did not work (after putting it into the test suite).
有人可以帮我解决这个问题吗?
最佳答案
您没有在测试用例中创建任何注入(inject)器:
@Test
public void testRateLimitInterceptorSanityTest() {
final RateLimitConfig config = new RateLimitConfig();
Injector injector = Guice.createInjector(config);
TestRateLimit testInstance = injector.getInstance(TestRateLimit.class);
int retVal = testInstance.stubMethod();
assertTrue(retVal == TEST_VAL);
}
关于java - 无法掌握 Guice 方法拦截器的窍门(bindInterceptor 期间出现空指针异常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39553338/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在尝试理解 promise ,在本例中是在一个循环中。 我的场景基于将文件上传到 Google 云端硬盘。我的理解是,每个文件都应该上传,然后一旦 promise 得到解决,就上传下一个文件,依此
JDK 1.6 包括通过 JAX-WS API 使用 FastInfoset Web 服务的功能。这些的实现隐藏在 com.sun.xml.internal 的深处,包名旨在让任何明智的 Java 开
我正在学习 React 并思考组件的结构。以下内容让我有些困惑。 我们被告知应该有单一的真相来源。 所有者组件应将 props/状态传递给它的责任(有些人称为“ownee”)组件。 所以,如果我自己的
我刚刚开始使用 Google Guice 作为依赖项注入(inject)框架,并试图将其改造为我最近编写的中小型项目。我了解 Guice 工作原理的基础知识,但对一些方法细节有点模糊。例如: 1) 模
上周我们在上周左右的修补和测试后将 Omniture 的分析代码发布到大量网站上。 在我们几乎所有的网站模板上,它都运行良好。在一些零星的、不可预测的情况下,严重的浏览器崩溃体验可能会让一些用户望而却
我刚刚获得了一个 API,它似乎比我习惯的更上一层楼,因为一切似乎都是使用接口(interface)实现的,我正在努力理解它们。 public partial class Form1 : Form,
我的程序似乎很合我意。但是,当我编译它时,我收到了这条消息: Note: Program.java uses unchecked or unsafe operations. Note: Recompi
最近开始用story board、Xcode等学习Swift。我很难理解 ViewController 代码的原理,因为它似乎遗漏了很多基本要素——大概是为了尝试让事情变得更简单——但它不适合来自其他
我刚收到一些有关使用 wpf、c# 的 MVVM 的设计/实现问题。我只是想掌握 MVVM,如果有人能证实我的想法,我正在徘徊,在我的应用程序中,我需要一名员工、一个部门和一家公司。所以换句话说,我有
我在 gird View 中有一个 gridview 和 2 个链接按钮,编辑和删除,单击编辑按钮 s 时,该行的详细信息应显示在“detailsview”中。我的详细信息 View 在更新面板。 最
function def() { console.log(this.x) } var f = def.bind({ x:777 }) f() // prints 777 bind 创建了一个函
我尝试将谷歌地图(外部加载的脚本)添加到 meteor 应用程序,但没有成功,我注意到有两种问题: 如果我做简单的事情并将主要的 API 脚本添加到我的 ,然后它被呈现为last。 发生这种情况时,
如果我理解正确,Node JS 是非阻塞的......所以它不是等待来自数据库或其他进程的响应,而是转移到其他东西并稍后再检查。 它也是单线程的。 这是否意味着给定的 Node JS 进程可以充分有效
几周前,我开始了 Iphone 应用程序开发的研究,在不同设置中进行了大量的 hello world 应用程序之后,我现在已经准备好开发我的第一个基于 Cocoa 中使用的 MVC 设计模式的应用程序
这个问题和我之前的问题很相似。 大约 4 年前,我在 Visual Studio 2005 中使用过 ASP .Net。恢复最新版本需要多长时间? 最佳答案 这取决于您“使用”它的程度。有经验的开发人
如何让这个程序让用户一次输入 5 位数字,而不是每次都询问单独的数字?我知道我必须使用 string.split() 但我将在哪里放置代码并执行代码。 Heading from random impo
因此,根据我的理解,在 3nf 数据库中,主键值可用于确定表中的每个其他属性。 这是否意味着外键将专门用于创建复合实体?外键如何适合 3nf 数据库? 有哪些“迹象”表明我的数据库已标准化?数据库中的
如何解决以下 f(n)=n!据我所知不适用于主定理的任何情况。T(n) = 16T(n/4) + n! 最佳答案 David Eisenstat 部分正确。情况 3 确实适用,但 T(n) = the
在过去的 2.5 年里,我一直在研究 SAP 技术。由于技术概念太多,我无法找到一个可以了解与它相关的所有内容的单一来源。我没有掌握掌握所有技术概念的信心。 如果您遇到过这样的经历以及如何克服它,请帮
我是一名优秀的程序员,十分优秀!