This is the second day of my participation in Gwen Challenge

IoC is an Inversion of Control. It is also known as Dependency Injection. So why IoC? What exactly does IoC mean? Let’s introduce a simple scenario to explain.

In a foreign exchange (FX) project, the need to provide customers with real-time exchange news, normally, need from different news agency first subscribe to news sources, and then through the batch program periodically to the specified server to grab the latest foreign news news, the news in the local database, then finally at the front display.

Assume that the FXNewsProvider does this

public class FXNewsProvider {
    private IFXNewsListener newsListener;
    private IFXNewsPersister newsPersister;
    public void getAndPersistNews(a){
       String[] newsIds = newsListener.getAvailableNewsIds();
       if (newsIds.length == 0) return ;
       for(String newsId : newsIds){ FXNewsBean newsBean = newsListener.getNwesByPK(newsId); newsPersister.persistNews(newsBean); newsListener.postProcessIfNecessary(newsId); }}}Copy the code

The FXNewsProvider relies on newsListener to fetch news, and newsPersister stores news, so you need to construct these two dependent classes in the constructor

public FXNewsProvider(a){
        newsListener = new DJNewsListener();
        newsPersister = new DJNewPersister();
}
Copy the code

Before IoC, we used to do this. Is it really necessary to actively get whatever dependency you need every time you use it? All we end up doing is calling the services provided by the dependent objects. So the IoC did all these things for us that had nothing to do with business logic.

In the IoC model, how does the injected object inform the girl in the figure above (IoC Service Provider) to provide appropriate services for it? There are three methods of dependency injection summarized in authoritative articles: 1. Constructor injection 2. Setter injection 3. Interface injection

Constructor injection

public FXNewsProvider(IFXNewsListener newsListener, IFXNewsPersister newsPersister){
        this.newsListener = newsListener;
        this.newsPersister = newsPersister;
    }
Copy the code

2. Setter method injection

public class FXNewsProvider {
    private IFXNewsListener newsListener;
    private IFXNewsPersister newsPersister;
    
    public IFXNewsListener getNewsListener(a) {
        return newsListener;
    }
​
    public void setNewsListener(IFXNewsListener newsListener) {
        this.newsListener = newsListener;
    }
​
    public IFXNewsPersister getNewsPersister(a) {
        return newsPersister;
    }
​
    public void setNewsPersister(IFXNewsPersister newsPersister) {
        this.newsPersister = newsPersister; }}Copy the code

In this case, neither the interface implemented nor the method declared in the interface is important. What matters is that the parameter type of the method declared in the interface must be the type of the object on which the injected object depends.

Comparison of the three methods interface injection: In terms of the use of injection methods, interface injection is not advocated at present, and is basically in the “retired” state. It is intrusive because it forces the injected object to implement unnecessary interfaces.

Constructor injection: The advantage is that objects are ready to be used immediately after construction is complete. The disadvantage is that the constructor argument list can be long when there are many dependent objects. When constructing objects by reflection, it is difficult to handle and maintain the same type of parameters.

Setter method injection: Because methods can be named, setter method injection is more descriptive than constructor injection. In addition, setter methods can be inherited, allowing default values to be set, with good IDE support. The disadvantage is that you can’t get into the ready state immediately after construction is complete.