Jay
Jay

Reputation: 25

how to implement play framework dependency injection as singleton like spring boot annotation with Configuration and Bean

I wanna create a RateLimiter instance as singleton in play framework. Here are the codes in Spring Boot.

@Configuration
public class RateLimiterConfig {

  @Bean
  public RateLimiter rateLimiter() {
     return RateLimiter.create(0.1d);
  }
}

and then autowire this bean in the service that I want to use.

private RateLimiter rateLimiter;

@Autowired
public void setRateLimiter(RateLimiter rateLimiter) {
    this.rateLimiter = rateLimiter;
}

but how can I acheive this in Play framework? I've created a class called RateLimitService and marked it as @Singleton. I want to prevent my api from duplicate requests and only allow 1 request in 100 seconds. (0.01 request per second)

@Singleton
public class RateLimitService {

  public RateLimiter getRateLimiter () {
      return RateLimiter.create(0.01d);
  }
}

and registered it in my application.conf and in a module class which extends AbstractModule class and bind my RateLimitService class as EagerSingleton in the configure method like below

@Override
protected void configure() {
     
  ...... // ignore other modules

  bind(RateLimitService.class).asEagerSingleton();
}

and injected the RateLimitService in my controller like this

@Inject
private RateLimitService rateLimitService;

However, when I run my application and call this method rateLimitService.getRateLimiter().tryAcquire(); it will return a boolean to check if the request is in the period I set before. But it always return a true for me and it seems that it always creates another rateLimitService instance whenever I call this api, because it does not block me. I can make sure codes are right since it works in spring boot app.

Please help me and thank you in advance.

Upvotes: 0

Views: 422

Answers (1)

You can do that using a provider

@Singleton
class RateLimitProvider @Inject() (configuration: Configuration) extends Provider[RateLimiter] {
  override def get(): RateLimiter = {
       // rate limit creation logic
    }
  }
}

in your binding do

bind[RateLimiter].toProvider(classOf[RateLimitProvider])

Upvotes: 0

Related Questions