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 ?
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.