I personally prefer the overloaded API as well (I don't mind lots of methods, as long as they all belong there and it's clear what's meant to be used when.)
Another thing I thought about was having the accessor/mutator for InvocationContext.setOptionOverrides() be static (or adding a static version), to at least get rid of the getCurrent() call. (The static method would do that for you). Similar to Thread.sleep() instead of Thread.currentThread().sleep().
But then I remember I'm always typing Thread.currentThread().sleep() and Thread.currentThread().setContextClassLoader() and having the IDE complain about the former and not the latter. That's always annoyed me.
InvocationContext has always been stored in ThreadLocal, except that this was always done by the TreeCache class when you called the overloaded method. This has always had invocation-level scope.
Now you'd do it explicitly and the reasons for this shift are:
1. Every time you use this, this is very explicit. Little chance of using the wrong overloaded method.
2. Cleaner interface API, since this is needed in Cache and not CacheSPI (form Hibernate, for example)
+1 on the accessors/mutators being static and handling the ThreadLocal business internally.