The company uses play2.26 to structure micro-services, and the bottom layer implements the authorization login control function of each interface check parameter
The interceptor is implemented by inheriting the following class
public abstract class Action<T> extends Results
{
public T configuration;
public Action<?> delegate;
public abstract F.Promise<SimpleResult> call(Http.Context paramContext)
throws Throwable;
public static abstract class Simple extends Action<Void>
{
}
}
@With(CheckAction.class)
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
String token() default "token";
/**
* The name of the interface parameter to be checked
* @return
*/
String[] args() default {};
/**
* Whether the interface needs to be checked for permissions
* @return
*/
boolean authCheck() default false;
boolean transactional() default false;
}
public class CheckAction extends Action<Check> {
private static ThreadLocal<UserToken> tl = new ThreadLocal<UserToken>();
private static ThreadLocal<String> tl2 = new ThreadLocal<String>();
@Override
public Promise<SimpleResult> call(Context ctx) throws Throwable {
String tokenParam = configuration.token();
String token = null;
String[] args = configuration.args(); //Note that the configuration here is the concurrency point, which leads to the wrong parameters on the annotation
return this.delegate.call(ctx); //Note that the delegate here is also a concurrent point, which leads to a direct request error, that is, the a request may have become the delegate of the b request at this time, such a callback causes the data to be returned directly to the b requested
The solution, first debug and find that there is always only one class, that is, the singleton mode
After investigation, it was found that in this global class
public class AppBootstrap extends GlobalSettings
@Override
public <A> A getControllerInstance(Class<A> clazz) throws Exception {
/*String name = clazz.getName();
Object o = map.get(name);
if(o==null){
o = clazz.newInstance();
map.put(name, o);
}
return (A) o;*/
//This thing is killing people, you can't use a singleton here, otherwise the configuration and delegate in CheckAction will be concurrent
return (A)clazz.newInstance();
}
With the above method debugging, it is found that a singleton is implemented with map here. . . . .
Removing the singleton pattern is the solution