Does using annotations to inject dependencies remove the main benefit of dependency injection(external configuration)?

跟風遠走 提交于 2019-12-22 05:40:10

问题


I am using Spring, here is a controller:

@Controller
public class PersonController {

@Resource(name="PersonService")
private PersonService personService;

    @RequestMapping(value = "/Person", method = RequestMethod.GET)
    public String getPersons(Model model) {

    // Retrieve all persons by delegating the call to PersonService
    List<Person> persons = personService.getAll();

    // Attach persons to the Model
    model.addAttribute("persons", persons);
    //then return to view jsp       
}

and here is a service :

@Service("personService")
@Transactional
public class PersonService {

    public List<Person> getAll() {
        //do whatever
       }
}

However, to properly make use of DI I should change the controller to make use of an interface (?) like so:

@Controller
public class PersonController {

@Resource(name="personService")
private IPersonService personService; //Now an interface
}

This would then allow me, for example, to use two services one test and one live. Which I could alter by adding/removing the annotation on the services :

@Service("personService") // this line would be added/removed
@Transactional
public class LivePersonService implements IPersonService {

    public List<Person> getAll() {
        //do whatever
       }
}

and

@Service("personService") //this line would be added/removed
@Transactional
public class TestPersonService implements IPersonService {

    public List<Person> getAll() {
        //do something else
       }
}

However one of the main benefits is lost due to the fact that the code has to be recompiled ? Whereas if I used xml lookup I could alter the dependency on-the-fly ?


回答1:


The configuration is still external, because it is outside where you define which implementation is going to be injected. Inside the class, you just hardcode the "name" of something the class depends on (which is ok, because this dependency is inherent to the class).

This said, you can use XML to override the annotations of your code for the tests execution (you would have a specific XML application context for your tests) and specify which implementation you will inject.

Therefore, you don't need to change your code to run the tests. Take a look to this answer.




回答2:


Well that's correct. Annotations are configuration inside the source code. Mainly intended when you have one class for each service. If you have more than one implementation for a particular interface, then XML will be a better option. Also you can mix XML configutation with annotations.




回答3:


The conventional way, that I heard last time from DI camp, is that in unit tests, you shouldn't use the DI framework. Rather, simply instantiate mock service yourself and set it to the host object

test()
    PersonController contr = new PersonController();
    contr.personService = new TestPersonService();
    // testing contr

This was hailed as the first and major achievement of DI, much to the puzzlement of people (like me) who don't get it. See my previous criticisms: advantage of using applicationcontext.getbean vs @configurable

If the DI supporters in this thread reflect the new trend in DI camp, they no longer do unit tests that way; instead tests depend on DI too, with a test specific DI config. Then it's really no different from service locator pattern. If the major feature of DI is moot, then what's the point?

Your controller class perfectly illustrated that. It cannot be used outside Spring DI framework as a POJO. There's nothing POJO about it. And nobody cares, rightfully. Same thing if your class depends on a service locator framework.

There are other features provided by Spring beans framework, none of them depends on DI; they can be implemented in a service locator framework just as well. Many people when defending DI the design pattern, are actually defending Spring the entire stack. You can actually use Spring as a service locator framework; Spring will not advertise this now, it's a blow to its main hype point; but it will once the hype weakens and it must appeal to the doubters.



来源:https://stackoverflow.com/questions/6548995/does-using-annotations-to-inject-dependencies-remove-the-main-benefit-of-depende

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!