When subclassing RequestContext, providing a custom MessageSource to be used by all getMessage methods should be as easy as overriding getMessageSource:

class CustomRequestContext extends RequestContext {

    private MessageSource messageSource;

    CustomRequestContext(HttpServletRequest request, MessageSource messageSource) {
        super(request);

        this.messageSource = messageSource;
    }

    @Override
    public MessageSource getMessageSource() {
        return messageSource;
    }
}

Unfortunately, the RequestContext.getMessage methods internally use this.webApplicationContext instead of getMessageSource() which hurts the extensibility of the class. Thus in order to provide a custom MessageSource, three additional getMessage methods must be overridden, duplicating functionality from the super methods:

class CustomRequestContext extends RequestContext {

    private MessageSource messageSource;

    CustomRequestContext(HttpServletRequest request, MessageSource messageSource) {
        super(request);

        this.messageSource = messageSource;
    }

    @Override
    public MessageSource getMessageSource() {
        return messageSource;
    }

    @Override
    public String getMessage(String code, @Nullable Object[] args, String defaultMessage, boolean htmlEscape) {
    String msg = getMessageSource().getMessage(code, args, defaultMessage, getLocale());
    if (msg == null) {
        return "";
    }
    return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
    }

    @Override
    public String getMessage(String code, @Nullable Object[] args, boolean htmlEscape) {
    String msg = getMessageSource().getMessage(code, args, getLocale());
    return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
    }

    @Override
    public String getMessage(MessageSourceResolvable resolvable, boolean htmlEscape) {
    String msg = getMessageSource().getMessage(resolvable, getLocale());
    return (htmlEscape ? HtmlUtils.htmlEscape(msg) : msg);
    }
}

This PR changes those three RequestContext.getMessage methods to use getMessageSource() internally (defaulting to this.webApplicationContext unless overridden) to allow providing a custom MessageSource more easily.

Comment From: snicoll

@pivotal-cla This is an Obvious Fix

Sorry, but it isn't. That is code change that requires the CLA to be signed. Please move forward before we can consider reviewing this.

Comment From: andreblanke

Sorry about that. I thought it wasn't necessary due to the simplicity of the changes, but I've signed the CLA.

Comment From: jhoeller

This generally makes sense, it just needs another change to go with it: namely removing the final declaration from getMessageSource() to make it actually overridable. At the opportunity, I've also removed final from getLocale() for consistency, as well as checking the Servlet 3.0+ ServletRequest.getServletContext() method in the request-only constructors (being able to fall back to the root WebApplicationContext even without an explicit ServletContext reference provided).