Considering two and a half years have passed since I originally asked this question, I think it is time that I shared our solution for the benefit of anyone that might read this in the future.
We ended up writing a custom component that implements WebServerFactoryCustomizer. Spring Boot will scan for all beans before starting its embedded Tomcat server. If it detects a bean that implements this interface, it will invoke the customize() method and pass the server factory as an argument to the function.
From there, it was straightforward:
package your.pack.age.name;
import org.apache.catalina.core.StandardThreadExecutor;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class TomcatServerConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    private final StandardThreadExecutor customExecutor;
    public TomcatServerConfig() {
        this.customExecutor = YourExecutorImplementation();
    }
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        /*This web server is the Tomcat server embedded in Spring Boot*/
        TomcatWebServer webServer = (TomcatWebServer)factory.getWebServer()
        webServer.getTomcat().getService().addExecutor(this.customExecutor);
    }
}
(The actual code we used was simplified here, for the sake of a clear answer)
It is also worth noting that similar code needs to be written for the Tomcat Connectors, using TomcatConnectorCustomizer:
package your.pack.age.name;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.stereotype.Component;
@Component
public class TomcatConnectorConfig implements TomcatConnectorCustomizer {
    private final StandardThreadExecutor customExecutor;
    public TomcatConnectorConfig() {
        this.customExecutor = YourExecutorImplementation();
    }
    @Override
    public void customize(Connector connector) {
         connector.getProtocolHandler().setExecutor(this.customExecutor);
    }
}
For convenience, I am adding a skeletal custom implementation of a thread executor:
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardThreadExecutor;
public class HTTPThreadExecutor extends StandardThreadExecutor {
    public HTTPThreadExecutor() {
        super();
        /* Custom constructor code here */
    }
    @Override
    protected void startInternal() throws LifecycleException {
        super.startInternal();
        /* Any work you need done upon startup */
    }
}