在无状态会话bean之间传递对象



我有几个无状态和单身豆。

@Stateful
@Local(IMyService.class)
@LocalBean
public class MyService implements IMyService {
    private @EJB Singleton1 singleton1;
    private @EJB Singleton2 singleton2;
    public void doSomeStuff() {
        // construct shared object
        singleton1.doOtherStuff();
        singleton2.doOtherStuff();
    }
}
@Singleton
@LocalBean
public class Singleton1 extends MySingleton {
    @Override
    public void doOtherStuff() {
        // use shared object
    }
}
@Singleton
@LocalBean
public class Singleton2 extends MySingleton {
    @Override
    public void doOtherStuff() {
        // use shared object
    }
}
public abstract class MySingleton {
    public abstract void doOtherStuff();
}

现在,我想在所有这些豆之间共享一个对象,而不必将其作为参数传递。

我本可以使用状态的bean,但是在无状态豆类中注射状态的豆是行不通的。

我不是将其作为参数传递,因为我不想在仅在几种情况下需要将该参数传递到方法中。

是否有含义在客户端会话中注入对象,以便我可以在任何地方阅读它?

您可以使用contextholder模式以及螺纹网和拦截器。

threadlocal - 此类允许将变量存储在线程范围上。我无意进入使用螺纹插座的利弊。我只是简单地说它非常强大,必须非常仔细地使用。

EJB Interceptor - 用于拦截bean实例的商业方法和生命周期事件的调用。

现在让我们要在所有这些bean之间共享一个用户对象,而不必将其作为参数传递。

所以我们的AuditContexTholder是:

public class AuditContextHolder {
    private static final ThreadLocal<String> AUDIT_CONTEXT = new ThreadLocal<>();
    private AuditContextHolder() {
    }
    public static void put(String  auditUser) {
        AUDIT_CONTEXT.set(auditUser);
    }
    public static String get() {
        return AUDIT_CONTEXT.get();
    }
    public static void cleanup() {
        AUDIT_CONTEXT.remove();
    }
} 

和审计拦截器将是:

public class AuditInterceptor {
    @Resource
    private SessionContext sessionContext;
    @AroundInvoke
    public Object inject(InvocationContext ctx) throws Exception {
        String userName = sessionContext.getCallerPrincipal().toString();
        try {
            AuditContextHolder.put(userName);
            return ctx.proceed();
        } finally {
            // very important
            AuditContextHolder.cleanup();
        }
    }
}

现在,您可以在呼叫链中首先使用无状态会话bean中使用@Interceptors(AuditInterceptor.class)。呼叫链中的任何地方都可以通过拨打AuditContextHolder.get()

获得审计用户

参考:

  1. http://www.adam-bien.com/roller/abien/entry/how_to_pass_context_with
  2. https://www.captechconsulting.com/blogs/a-persistence-pattern-using-threadlocal-and-ejb-interceptors

最新更新