【问题标题】:Does using annotations to inject dependencies remove the main benefit of dependency injection(external configuration)?使用注解注入依赖项会消除依赖项注入(外部配置)的主要好处吗?
【发布时间】:2011-07-01 14:03:03
【问题描述】:

我正在使用 Spring,这是一个控制器:

@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       
}

这是一项服务:

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

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

但是,要正确使用 DI,我应该更改控制器以使用接口 (?),如下所示:

@Controller
public class PersonController {

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

例如,这将允许我使用两项服务,一项是测试服务,一项是实时服务。我可以通过添加/删除服务上的注释来改变:

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

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

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

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

但是,由于必须重新编译代码这一事实而失去了主要好处之一?而如果我使用 xml 查找,我可以即时更改依赖关系?

【问题讨论】:

  • 我不会将其列为 DI 的一项重要优势 - 我认为这也许是一个不错的选择,但仅此而已。
  • 这将是相当主观的 - 有些人喜欢外部 XML 配置,有些人喜欢相对简洁的注释。没有人是“正确的”。
  • @skaffman,还有哪些重要的好处?
  • @NimChimpsky:DI 的主要好处,即从外部注入依赖项,而不是代码去获取它。
  • @skaffman,好的,那么 DI 对日常编码还有哪些其他实际好处。我可以看到根据您的配置(实时、测试、客户)查找不同服务的好处。还有什么?

标签: java unit-testing spring dependency-injection


【解决方案1】:

配置仍然是外部的,因为它在您定义要注入的实现之外。在类中,您只需硬编码类 依赖something"name"(这没关系,因为这种依赖是类)。

也就是说,您可以使用 XML 来覆盖代码的注释以执行测试(您的测试将有一个特定的 XML 应用程序上下文)并指定您将注入的实现。

因此,您无需更改代码即可运行测试。看看this answer

【讨论】:

    【解决方案2】:

    嗯,没错。注释是源代码中的配置。主要用于当您为每个服务设置一个类时。如果您对特定接口有多个实现,那么 XML 将是一个更好的选择。您还可以将 XML 配置与注释混合使用。

    【讨论】:

      【解决方案3】:

      我上次从 DI 阵营听到的传统方法是,在单元测试中,您不应该使用 DI 框架。相反,只需自己实例化模拟服务并将其设置为宿主对象

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

      这被誉为 DI 的第一个重大成就,这让不明白这一点的人(比如我)非常困惑。看我之前的批评:advantage of using applicationcontext.getbean vs @configurable

      如果这个帖子中的 DI 支持者反映了 DI 阵营的新趋势,他们不再那样做单元测试;相反,测试也依赖于 DI,具有测试特定的 DI 配置。那么它真的和服务定位器模式没有什么不同。如果 DI 的主要特点没有实际意义,那还有什么意义呢?

      您的控制器类完美地说明了这一点。它不能在 Spring DI 框架之外用作 POJO。没有任何关于它的 POJO。没有人在乎,这是理所当然的。如果您的类依赖于服务定位器框架,情况也是如此。

      Spring beans 框架还提供了其他一些特性,它们都不依赖于 DI;它们也可以在服务定位器框架中实现。许多人在捍卫 DI 设计模式时,实际上是在捍卫 Spring 的整个堆栈。您实际上可以将 Spring 用作服务定位器框架; Spring 现在不会宣传这个,这是对其主要炒作点的打击;但一旦炒作减弱,它就会吸引怀疑者。

      【讨论】:

        猜你喜欢
        • 2011-11-22
        • 1970-01-01
        • 1970-01-01
        • 2020-12-20
        • 1970-01-01
        • 2020-03-14
        • 1970-01-01
        • 1970-01-01
        • 2017-02-16
        相关资源
        最近更新 更多