我有一个从springsecuritycontext对象中提取登录用户详细信息的方法。
我已经读过,只有实用程序方法(进行某些计算)才应该是static。
这是我的方法,它似乎不是实用程序方法,但是我找不到任何原因,因为我在多个bean中使用它时不应该使其变为静态
public static int getSignedUpUser()
{
final SecurityContext ctx = SecurityContextHolder.getContext();
if(ctx != null)
{
final Authentication auth = ctx.getAuthentication();
if(auth != null)
{
final Object principal = auth.getPrincipal();
if(principal instanceof AUser)
{
final AUser au = (AUser)principal;
return au.getId();
}
}
}
return 0;
}
}
最佳答案
简而言之:使用静态方法就可以了。
当我们说静态方法应该是一种实用方法时,我们在说静态方法应该是线程安全的。
让我们看看SecurityContextHelper.getContext()方法。它是这样实现的:
private static SecurityContextHolderStrategy strategy;
public static SecurityContext getContext() {
return strategy.getContext();
}
注意,它从静态变量
strategy
返回上下文。因此,strategy
必须保持线程安全。SecurityContextHolderStrategy
接口具有三种实现:其中两个是线程本地的,另一个是
private static SecurityContext contextHolder;
然后让我们看看SecurityContextHolder.initialize()方法:
private static void initialize() {
if ((strategyName == null) || "".equals(strategyName)) {
// Set default
strategyName = MODE_THREADLOCAL;
}
if (strategyName.equals(MODE_THREADLOCAL)) {
strategy = new ThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals(MODE_INHERITABLETHREADLOCAL)) {
strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals(MODE_GLOBAL)) {
strategy = new GlobalSecurityContextHolderStrategy();
} else {
// Try to load a custom strategy
try {
Class<?> clazz = Class.forName(strategyName);
Constructor<?> customStrategy = clazz.getConstructor();
strategy = (SecurityContextHolderStrategy) customStrategy.newInstance();
} catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
}
}
initializeCount++;
}
这表明MODE_THREADLOCAL是默认策略。甚至GlobalSecurityContextHolderStrategy也使用静态上下文持有者。因此,您可以在静态方法中使用它们。