Ok, so I ended up using Cage Captcha generator. It can be integrated with Maven and it's fairly easy to be implemented with a Spring MVC application with JQuery AJAX.
/**
 * Generates captcha as image and returns the image path
 * stores the captcha code in the http session
 * and deletes older, unused captcha images.
 */
@RequestMapping(value = "/captcha/generate", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public ResponseEntity<CaptchaRequestData> generateCaptcha(HttpSession session) {
    String captchaImageUploadDirectory = environment.getProperty("captcha_image_folder");
    String captchaWebAlias = environment.getProperty("captcha_web_alias");
    //Creating dir or making new one if it doesn't exist
    File file = new File(captchaImageUploadDirectory);
    if (!file.exists()) {
        try {
            file.mkdirs();
        } catch(Exception e){}
    }
    String timeSuffix = DBUtils.getDateTimeAsString();
    String fileName = CAPTCHA_IMAGE_PREFIX + timeSuffix + "." + CAPTCHA_IMAGE_EXTENSION;
    String fullFilename = captchaImageUploadDirectory + fileName;
    //Generating the captcha code and setting max length to 4 symbols
    Cage currGcage = new YCage();
    String captchaToken = currGcage.getTokenGenerator().next();
    if (captchaToken.length() > CAPTCHA_CODE_MAX_LENGTH) {
        captchaToken = captchaToken.substring(0, CAPTCHA_CODE_MAX_LENGTH).toUpperCase();
    }
    //Setting the captcha token in http session
    session.setAttribute("captchaToken", captchaToken);
    try {
        OutputStream os = new FileOutputStream(fullFilename, false);
        currGcage.draw(captchaToken, os);
        os.flush();
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    deleteFilesOlderThan(captchaImageUploadDirectory, CAPTCHA_IMAGE_LIFE_MILLISECONDS, CAPTCHA_IMAGE_EXTENSION);
    CaptchaRequestData data = new CaptchaRequestData(captchaWebAlias + fileName);
    return new ResponseEntity<>(data, HttpStatus.OK);
}
Then when I'm creating the object I check if the given code equals the one, stored in the session: 
 if (!httpSession.getAttribute("captchaToken").equals(bindingData.getCaptchaCode())) {
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
 }
Finally if the provided captcha is incorrect I generate a new one.