【问题标题】:maven cyclic dependency resolutionmaven 循环依赖解析
【发布时间】:2017-10-27 01:10:09
【问题描述】:

任何人都可以帮助解决我的应用程序中的这个循环依赖错误。

这是我的情况:我有 2 个类需要根据决策者值相互通信,但是如果我尝试在导致循环依赖错误的那些类中添加依赖关系,那么这 2 个类会留在不同的模块中。

我计划的示例功能将与此类似

class A {
    void funA() {
        System.out.print("Module A");
    }

    void Validate() {
        boolean decider = true; // if true indicates belongs to Class A else B
        if (decider) {
            funA();
        } else {
            B b = new B();
            b.funB();
        }
    }

    private class B {
        void funB() {
            System.out.print("Module B");
        }

        void Validate() {
            boolean decider = false;// if true indicates belongs to Class A else B
            if (decider) {
                funB();
            } else {
                A a = new A();
                a.funA();
            }
        }
    }
}

ClassA 位于 ModuleAClassB 内> 停留在 ModuleB 内,我如何通过创建新模块和移动通用功能来实现上述功能

【问题讨论】:

  • 我尝试使用 validate() 代码添加另一个模块,但即使这样也会导致循环依赖,因为 ModuleC 需要 funA()、funB() 访问,而 funA() 与 moduleC 通信需要它的依赖
  • 简而言之,重构你的代码和你的模块结构以避免模块之间的循环依赖。代码看起来如此模糊和不切实际,我们很难建议您应该如何重构
  • 您真的需要在Avalidate() 中实例化B(反之亦然)吗?

标签: java maven dependencies


【解决方案1】:

如果一个类A 需要实例化一个类B 并且B 需要实例化一个类A(意味着调用new A() 等),那么这两个类必须在同一个模块中。所以你的构造是不可能的。

不过,我想你的预期逻辑可以实现,但我不清楚你真正想用你的“决定者”和不同的调用来实现什么。

【讨论】:

    【解决方案2】:

    鉴于您的代码不是很现实,很难建议您如何重构代码。

    这里有一些建议,希望能给你灵感来解决你的实际问题

    方法一:将A和B放在同一个模块中

    您可以将AB 作为一个公共模块取出。所以AB 之间的相互引用不是问题,因为它们在同一个模块中。原始module_amodule_b 都将依赖于新的a_b_common 模块(其中包含AB

    方法 2:打破 A 和 B 之间的依赖关系

    重构您的代码,使 A 和 B 不直接相互依赖。方法很多,这里只是一个例子:

    在公共模块中有Action

    interface Action {
        void perform();
    }
    

    让A不再依赖B

    class A {
        Action fallbackAction;  // setter etc
    
        void validate() {
            if xxxxx {
                funcA();
            } else {
                fallbackAction.perform();
            }
        }
    }
    
    // similar for B
    

    使用依赖注入,通过类似的方式构造 A 和 B

    A a = new A();
    a.setFallbackAction(new Action(){ 
                          void perform() { new B().funcB(); }
                        } );
    B b = new B();
    b.setFallbackAction(new Action(){ 
                          void perform() { new A().funcA(); }
                        } );
    

    (当然,你甚至可以在 Java8 中使用 lambda 和函数式接口来处理上述内容。这只是给你一个高层次的想法)

    【讨论】:

    • Adrian,我什至想到了方法 2,但我有点怀疑第三个代码块位于哪个模块(构造 A 和 B
    • 通常您的应用程序有一个“模块”(在其中执行 DI 等)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2013-11-16
    • 2011-11-02
    相关资源
    最近更新 更多