【问题标题】:Can I inject an object that created dynamically我可以注入一个动态创建的对象吗
【发布时间】:2023-03-11 15:20:01
【问题描述】:

我有一个关于依赖注入的问题。

我有一堂课,说:

class MyClass {
    MyServiceAPI serviceAPI;
    public setSession(Session session) {
         serviceAPI = new MyServiceAPI(session);     
    }
    ....
}

会话由另一个类创建,该类在运行时从数据库中加载它。

class MyAnotherClass {
    Myclass myClass;

    @Inject
    MyAnotherClass(MyClass myClass) {
        this.myClass = myClass;
    }

    public someFunction() {
        String key = <read from database>;
        Session session = new Session(key);
        myClass.setSession();
        ......
    }
}

如前所述,MyClass 实例被注入到 MyAnotherClass 中,而 MyClass 中的 serviceAPI 实例是使用 new 创建的。如果我想将 ServiceAPI 注入 MyClass,我可以在创建会话的类中创建它,并使用 setter 将其设置为 MyClass。

但问题是我真的不想让 MyAnotherClass 创建 MyServiceAPI 并将其注入 MyClass。我希望 MyAnotherClass 不知道 MyServiceAPI 的存在。

有没有办法可以使用 Guice 或 Spring 等依赖注入器来做到这一点?还是简单的 Java?

非常感谢。

【问题讨论】:

  • 是的,看起来应该将MyClass 注入MyAnotherClass。此外,MyServiceAPI 可能应该注入到MyClass 中。如果不知道代码的语义/意图,这种问题很难回答......
  • 是的。我明白你的意思。抱歉,这个问题有点糟糕。让我稍微改变一下。

标签: java spring dependency-injection guice


【解决方案1】:

如果您希望在纯 Java 中进行依赖注入,那么从 Java 6 开始,可以通过内置的 Java 服务提供者接口提供一些支持。虽然它需要一些 jar 文件等管道。看看 here for Java SPI

【讨论】:

    【解决方案2】:

    使用 guice 和简单工厂的可能解决方案。 MyServiceAPI 可以是一个接口。

    public class MyClass {
    
        @Inject
        private MyServiceFactory factory;
        private MyServiceAPI myServiceAPI;
    
        public void setSession(Session session) {
            myServiceAPI = factory.createMyServiceAPI(session);
        }
    }
    
    public class MyServiceFactory {
    
        MyServiceAPI createMyServiceAPI(Session session) {
            // create with new, inject via Injector, do what you want... :)
            return <yourobject>;
        }
    }
    

    【讨论】:

      【解决方案3】:

      你只需要为此使用一个好的老式工厂。

      class MyAnotherClass {
          MyClassFactory myClassFactory;
      
          @Inject
          MyAnotherClass( MyClassFactory myClassFactory ) {
              this.myClassFactory = myClassFactory;
          }
      
          public void someFunction() {
              String key = "1"; // read from DB
              myClass = myClassFactory.getMyClass( key );
          }
      }
      
      class MyClassFactory {
          public MyClass getMyClass( String key ) {
              Session session = new Session( key );
              MyClass myClass = new MyClass();
              myClass.setSession( session );
              return myClass;
          }
      }
      

      【讨论】:

        【解决方案4】:

        我确实认为您可能需要重新排序您的依赖项。同样,在不知道您的完整代码的情况下,这有点困难,但看看您的示例,以下内容似乎是正确的:

        • MyClass 实际上取决于 MyServiceAPI 而不是 Session。因此,您应该直接在其构造函数中注入MyServiceAPI

        • Session 应该在其构造函数中注入其sessionId(或其他)。你可以在 Guice 中绑定它的值,所以你会得到类似:@Inject @SessionId public Session(String sessionId)。或者您可以将sessionId 和一些SessionService 都注入Session,这样它就可以从服务中检索自己的数据。

        • MyServiceAPI 应该将Session 注入其中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-26
          • 1970-01-01
          • 1970-01-01
          • 2015-01-22
          • 1970-01-01
          • 2016-03-13
          相关资源
          最近更新 更多