• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Rob Spoor
  • Junilu Lacar
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
  • Carey Brown
Bartenders:

use of @Value Spring annotation during Controller initialization issue

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Probably someone else might have asked something similar as well, but I couldn't find an answer that provides a solution that works...
I'm in the process of learning spring boot and while I was playing with guava RateLimiter during my experiments I hit the following problem:
RateLimiter needs to be created during the Controller initialization, but if I want to load the rate I have to hardcode it, since if I try to load it from props using attributes with @Value Spring annotations it doesn't work.
Is there any "trick" around this "limitation"?

see code below:

@RestController
public class LoggingController {
   private Logger logger = LoggerFactory.getLogger(LoggingController.class);

   @Value("${count}")
   private Double PERMITS_COUNT;
   @Value("${seconds}")
   private Double PERMITS_PER_SECONDS;
   @Value("${consumed}")
   private int PERMITS_CONSUMED;

//@ Value fails here with NullPointerException
   private RateLimiter rateLimiter = RateLimiter.create(PERMITS_COUNT / PERMITS_PER_SECONDS);
// This works file
private RateLimiter rateLimiter = RateLimiter.create(10d / 60d);

   private AtomicInteger index = new AtomicInteger(0);


   @GetMapping("/logging")
   @ResponseBody
   public String logging (@RequestParam(name="name", required=false, defaultValue="JavaBoss") String name) {

//@Value works fine if used here
       rateLimiter.setRate(PERMITS_COUNT / PERMITS_PER_SECONDS);
       rateLimiter.acquire(PERMITS_CONSUMED);
...
 
Sheriff
Posts: 22716
129
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your ordering is incorrect. The injection of these values occurs after the object has been created, but the failing uses of them occurs during object initialization.

An overview of what's happening:
  • Spring Boot creates an instance.
  • Fields with explicitly initialization values are assigned. This is where you get the exception.
  • The constructor is called. You don't have an explicit one, so the implicit default constructor is called.
  • After the constructor ends, Spring Boot auto-wires values and dependencies.


  • Since Spring Boot supports injecting values and dependencies in constructors, this is actually easy to fix:

    You can even omit the double and int fields if you don't need them but only the rate limiter.
    reply
      Bookmark Topic Watch Topic
    • New Topic