What are the benefits of dependency injection containers?

前端 未结 16 2786
南笙
南笙 2020-12-02 04:09

I understand benefits of dependency injection itself. Let\'s take Spring for instance. I also understand benefits of other Spring featureslike AOP, helpers of different kind

16条回答
  •  忘掉有多难
    2020-12-02 05:03

    The reason for using a DI container are that you don't have to have a billion properties pre-configured in your code that are simply getters and setters. Do you really want to hardcode all those with new X()? Sure, you can have a default, but the DI container allows the creation of singletons which is extremely easy and allows you to focus on the details of the code, not the miscellaneous task of initializing it.

    For example, Spring allows you to implement the InitializingBean interface and add an afterPropertiesSet method (you may also specify an "init-method" to avoid coupling your code to Spring). These methods will allow you to ensure that any interface specified as a field in your class instance is configured correctly upon startup, and then you no longer have to null-check your getters and setters (assuming you do allow your singletons to remain thread-safe).

    Furthermore, it is much easier to do complex initializations with a DI container instead of doing them yourself. For instance, I assist with using XFire (not CeltiXFire, we only use Java 1.4). The app used Spring, but it unfortunately used XFire's services.xml configuration mechanism. When a Collection of elements needed to declare that it had ZERO or more instances instead of ONE or more instances, I had to override some of the provided XFire code for this particular service.

    There are certain XFire defaults defined in its Spring beans schema. So, if we were using Spring to configure the services, the beans could have been used. Instead, what happened was that I had to supply an instance of a specific class in the services.xml file instead of using the beans. To do this, I needed to provide the constructor and set up the references declared in the XFire configuration. The real change that I needed to make required that I overload a single class.

    But, thanks to the services.xml file, I had to create four new classes, setting their defaults according to their defaults in the Spring configuration files in their constructors. If we had been able to use the Spring configuration, I could have just stated:

    
        
    
    
    
        
    
    
    
        
    
    
    
    

    Instead, it looked more like this:

    public class TheFirstPointlessClass extends SomeXFireClass {
        public TheFirstPointlessClass() {
            setFirstProperty(new TheSecondPointlessClass());
            setSecondProperty(new TheThingThatWasHereBefore());
        }
    }
    
    public class TheSecondPointlessClass extends YetAnotherXFireClass {
        public TheSecondPointlessClass() {
            setFirstProperty(TheThirdPointlessClass());
        }
    }
    
    public class TheThirdPointlessClass extends GeeAnotherXFireClass {
        public TheThirdPointlessClass() {
            setFirstProperty(new AnotherThingThatWasHereBefore());
            setSecondProperty(new WowItsActuallyTheCodeThatChanged());
        }
    }
    
    public class WowItsActuallyTheCodeThatChanged extends TheXFireClassIActuallyCareAbout {
        public WowItsActuallyTheCodeThatChanged() {
        }
    
        public overrideTheMethod(Object[] arguments) {
            //Do overridden stuff
        }
    }
    

    So the net result is that four additional, mostly pointless Java classes had to be added to the codebase to achieve the affect that one additional class and some simple dependency container information achieved. This isn't the "exception that proves the rule", this IS the rule...handling quirks in code is much cleaner when the properties are already provided in a DI container and you're simply changing them to suit a special situation, which happens more often than not.

提交回复
热议问题