非实用的静态方法

时间:2015-02-26 12:27:11

标签: java spring spring-security

我有一个从springsecuritycontext对象中提取登录用户详细信息的方法。

我已经读过,只有实用方法(进行某些计算)应该是静态的。

这是我的方法,它似乎不是一种实用方法,但我没有找到任何理由为什么我不应该让它静止,因为我在多个豆子中使用它

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;
    }
}

3 个答案:

答案 0 :(得分:1)

简而言之:使用静态方法即可。

当我们说静态方法应该是一个实用方法时,我们讨论的是静态方法应该是线程安全的。

让我们看一下SecurityContextHelper.getContext()方法。它实现如下:

private static SecurityContextHolderStrategy strategy;

public static SecurityContext getContext() {
    return strategy.getContext();
}

请注意,它从静态变量strategy返回上下文。所以strategy必须保持线程安全。

SecurityContextHolderStrategy接口有三个实现:

enter image description here

其中两个是本地线程,另一个是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也使用静态上下文持有者。所以你可以在静态方法中使用它们。

答案 1 :(得分:0)

概念上,所示的方法impl是类的实例的一部分。这就是为什么操纵可以是静态的。所以我更喜欢使用instane而不是静态方法。

答案 2 :(得分:0)

你不是以正确的方式提问。如果你看一下getSignedUpUser的方法,你会看到它所属的类。你的问题应该是:

  

谁获得了注册用户?实例或所有实例   集体(班级)?

static成员或方法是集体成员或方法。例如,鸟类的数量是关于鸟类的集体数据,它是static。非静态成员或方法是个体的。例如,一只鸟有一个重量,它与鸟类有关。