在叶类中,实例化一个具有@Inject批注的类

时间:2015-01-19 10:26:52

标签: java dependency-injection

一些背景

  1. 这是一个小型的爱好项目,我知道虽然这里使用的一些东西,如包装纸甚至DI都不是必需的,但它们是用于学习目的。

  2. 以前在阅读Spring的文档时,我已经阅读了很多次,非常强调没有代码必须依赖于DI框架。这是有道理的:你编写了具有某些依赖关系的库类,他们知道他们会以某种方式接收它们,但并不真正关心它们。这样就可以在没有DI的情况下在其他地方使用和共享这些库类,没有或只有很少的更改。

  3. Google Guice用作DI框架(它的重量轻!)。

  4. 问题:

    此时,有一个类具有使用@Inject注释声明的依赖项。在Factory内构建此类时,无法直接调用DI

    有一个接口,它是套接字对象的包装器:

    interface ClientContainer {
        interface ClientContainerFactory {
           ClientContainer getFrom(Socket s);
        }
    
        public Socket getSocket();
    
        // .... Other stuff applicable to a client. Removed for brevity.
    }
    

    工厂,隐藏ClientContainer的具体实施:

    // Package local concrete class.
    class SampleContainerImpl implements ClientContainer {
        // Observers are notified on various events such as
        // Client closed the connection and...
        private final List<Observer> observers = new List<>();
    
        // A default observer implementation must be provided in
        // order to cleanup and close resources when exceptions
        // occur. It means if a IOException is raised while reading
        // from client socket, SampleContainerImpl will not close
        // that socket but delegates the task to this class.
        private Observer defaultObserverInCaseOfException;
    
        // Such a long name!
        @Inject
        void inCaseOfExceptionObserverSetter(Observer<ClientContainer> o) {
            this.defaultObserverInCaseOfException = o;
        }
    
        SampleContainerImpl(Socket clientSocket) {
           this.socket = clientSocket;
        }
    
        // Rest of the code removed for brevity
    }
    

    为了隐藏我的具体类,我在具体类的同一个包中创建了一个工厂,但是使用了公共访问修饰符。问题就在这里:

    public class SampleFactory implements ClientContainer.ClientContainerFactory {
        public ClientContainer getFrom(final Socket s) {
           final ClientContainer c = new ClientContainer(s);
           // Okay... what to do with our class who has an @Inject?
           // The only way I can think of is to make SampleFactory 
           // aware of the DI -> bad. DI is not a service locator,
           // and I do not want to use a service locator either!
    
           return c;
        }
    }
    

1 个答案:

答案 0 :(得分:0)

这很有趣,我现在可以看到问题:

在考虑DI时,实施ClientContainer.ClientContainerFactory是没用的,也是个坏主意。 ClientContainer必须从DI获得。对于直到主根的其他类也是如此。

这是对的吗?