如何使用静态方法为类提供参数而不更改静态限定符?

时间:2016-12-16 09:33:02

标签: java dependency-injection static-methods

我有一个静态方法的类:

public class CompletelyStatic {

    public final static String PARAM = "abc";

    public static String doSomethingSpecial() {
        return "qqq" + PARAM;
    }

}

这些方法在整个代码中都被使用。新要求是从外部配置加载PARAM值。该配置通过Config对象通过依赖注入提供,即

public class CompletelyStatic {

    @Inject
    private Config configProvider;

    public final static String DEFAULT_PARAM = "abc";

    public String doSomethingSpecial() {
        return "qqq" + configProvider.getSpecialParam(DEFAULT_PARAM);
    }

}

不幸的是,在这里我必须在doSomethingSpecial上更改静态限定符,所以在我使用它的任何地方,我都必须注入一个CompletelyStatic实例。我宁愿避免这样做。我可能会做那样的事情:

public class CompletelyStatic {

    public final static String DEFAULT_PARAM = "abc";

    public static String doSomethingSpecial(Config configProvider) {
        return "qqq" + configProvider.getSpecialParam(DEFAULT_PARAM);
    }

}

但是如果doSomethingSpecial在下面调用了一些私有方法,我将不得不传播configProvider。有更好的解决方案吗?

编辑。如果CompletelyStatic有一些内部私有方法,那么我应该将configProvider传播给它们:

public class CompletelyStatic {

    public final static String DEFAULT_PARAM = "abc";

    public static String doSomethingSpecial(Config configProvider) {
        return "qqq" + otherMethod(configProvider);
    }

    private static String otherMmethod(Config configProvider) {
        return "more logic " + configProvider.getSpecialParam(DEFAULT_PARAM);
    }
}

编辑2.为了澄清,我对Config对象没有任何影响。我知道如果它有静态方法会很好,但事实并非如此。

3 个答案:

答案 0 :(得分:2)

您可能需要执行以下操作:

public class CompletelyStatic {

    @Inject
    private Config configProvider;

    // Keep a static private instance of your Static class
    private static CompletelyStatic cs = new CompletelyStatic();

    //If needed, make the constructor of your class private
    private CompletelyStatic(){
    }

    public final static String DEFAULT_PARAM = "abc";

    public static String doSomethingSpecial() {
        return "qqq" + cs.getConfigProvider().getSpecialParam(DEFAULT_PARAM);
    }

    public Config getConfigProvider(){
        return configProvider;
    }
}

您的其他私有方法将能够以类似的方式使用configProvider对象:cs.getConfigProvider()

  

<强>更新

public class CompletelyStatic {

    public final static String DEFAULT_PARAM = "abc";

    //Keep a static reference to the ConfigProvider object.
    private static Config configProvider;

    public static String doSomethingSpecial(Config configProvider) {
        CompletelyStatic.configProvider = configProvider;
        return "qqq" + otherMethod(configProvider);
    }

    // Here, you will not need to parameterize your other methods.
    private static String otherMmethod() {
        return "more logic " + configProvider.getSpecialParam(DEFAULT_PARAM);
    }
}

希望这有帮助!

答案 1 :(得分:1)

通常,配置对象必须是静态的

public class CompletelyStatic 
{
    public final static String DEFAULT_PARAM = "abc";
    public static String doSomethingSpecial()
   {
        return "qqq" + Config.getSpecialParam(DEFAULT_PARAM);
    }
}

public class CompletelyStatic 
{
    private static String SPECIAL_PARAM = Config.getSpecialParam(DEFAULT_PARAM);
    public final static String DEFAULT_PARAM = "abc";
    public static String doSomethingSpecial()
   {
        return "qqq" + SPECIAL_PARAM;
    }
}

在这种情况下,

config应该是单例实例Config.getInstance().getSpecialParam(DEFAULT_PARAM);

希望这会有所帮助:)

答案 2 :(得分:1)

更好的解决方案是在应用程序启动期间通过类似static的方法加载Config init()变量,如下面的代码所示。这种方法的优点是,如果您从Config转移到其他类别,您不需要更改/修改所有依赖类。否则,您需要从调用doSomethingSpecial()的位置更改所有类。

public class CompletelyStatic {

       private static Config configProvider;

       //you need to load the below init method during application start up
       public static void init(Config configProvider) {
           CompletelyStatic.configProvider= configProvider;
       }

       public static String doSomethingSpecial() {
           return "qqq" + otherMethod();
        }

        private static String otherMmethod() {
           return "more logic " + configProvider.getSpecialParam(DEFAULT_PARAM);
       }
     }

此外,在这种方法中,方法签名public String doSomethingSpecial()没有从原始类更改(因此对所有依赖类没有影响,但只有一点是在启动期间加载init