6

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 ?

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • I wouldn't have listed that as an important benefit of DI - I'd consider that to be a nice-to-have, perhaps, but nothing more. – skaffman Jul 01 '11 at 14:14
  • This is going to be pretty subjective - some people prefer external XML configuration, some people prefer the relative brevity of annotations. No one is "correct". – matt b Jul 01 '11 at 14:21
  • @skaffman, what other important benefits are there ? – NimChimpsky Jul 01 '11 at 14:40
  • @NimChimpsky: DI *is* the main benefit, i.e. inject the dependency from outside, rather than the code going off to fetch it. – skaffman Jul 01 '11 at 14:41
  • @skaffman, ok so what other practical benefits does DI have to everyday coding. I can see the benefit of looking up a different service depending on your config (live,test, customer). What else is there ? – NimChimpsky Jul 01 '11 at 14:44
  • @NimChimpsky: This is getting into "new question" territory, and there are plenty prior question SO about this. Also, http://en.wikipedia.org/wiki/Dependency_injection – skaffman Jul 01 '11 at 14:51

3 Answers3

4

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.

Community
  • 1
  • 1
Mr.Eddart
  • 10,050
  • 13
  • 49
  • 77
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.

Luciano
  • 8,552
  • 5
  • 32
  • 56
0

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.

Community
  • 1
  • 1
irreputable
  • 44,725
  • 9
  • 65
  • 93