在Spring Boot项目中声明同一个类/数据访问对象(DAO)的多个实例是否有害?

huangapple 未分类评论43阅读模式
英文:

Is declaring multiple instances of the same class/DAO in a Spring Boot project harmful?

问题

我刚开始学习Spring,之前主要是从事Java EE开发,所以像IOC和依赖注入这样的东西对我来说都是比较新的。根据Spring文档的说明,我理解任何一个类要调用其依赖项的实例,我可以选择将这些依赖项自动连接,作为一种依赖项注入的形式。实际上,这与我们在Java中通常做的常规实例声明是分开的,就像下面这样:Animal animal1 = new Animal()

在我的一个小测试Spring Boot项目服务中,我注意到我最终既要进行依赖项注入,又要进行普通的类实例化。我使用JPA Repository来构建我的存储库层,并自动连接存储库类,以便我可以像这样使用它们:

@Autowired 
customerAccountRepo 

这一切都很好。我还有一个DAO customerMembershipValidity,其属性是其他声明的POJO,并且其中有一些公共辅助函数来设置DAO的属性。然而,为了使用这个DAO,我发现自己需要以传统的方式创建DAO的多个实例,通过多次实例化CustomerMembershipValidity customerMembershipValidity1 = new CustomerMembershipValidity()来在服务中调用公共的辅助方法,比如customerMembershipValidity.setNewExpiry()。我认为不需要自动连接这个,因为我处理的是一个DAO或者POJO,而不是另一个服务...或者应该连接吗?

目前看来,当我进行单元测试时,代码似乎是功能正常的,但我想知道这是否会损害代码的整体持久性和合理性,或者在我运行Spring Boot应用程序时是否有可能在端到端测试中出现问题。

英文:

I'm just starting to pick up Spring, coming from a purely Java EE background, so stuff like IOC and dependency injection is all kinda new to me. As per the Spring docs, I understand that for any class to call on instances of its dependencies, I can choose to autowire those dependencies as a form of dependency injection. And that this is actually aside from the usual instance declaration we always do in java like below: Animal animal1 = new Animal()

In my one of my little test Spring boot project services, I noticed that I end up doing both dependency injection and normal class instantiation. I use JPA Repository to craft my repo layer, and autowire the repo classes so I can use them like eg.

@Autowired 
customerAccountRepo 

This is all fine. I also have a DAO customerMembershipValidity whose attributes are other declared POJOs and has some public helper functions within to set the DAO's attributes. In order to use this DAO, however, I find myself creating multiple instances of the DAO the traditional way, instantiating
CustomerMembershipValidity customerMembershipValidity1 = new CustomerMembershipValidity() multiple times throughout the service to call on public helper methods like customerMembershipValidity.setNewExpiry(). I didnt think there would be a need to autowire this since I'm dealing with a DAO or POJO, not another service... or should I?

For now, the code seems functional when I do my unit-testing, but I would like to know if this would harm the overall longevity and sensibility of the code, or if it's forseeable to end up breaking in E2E when I run the Spring Boot application.

答案1

得分: 0

我有一些建议:

  1. DAO 应该是一个单例的 Spring Bean,你将其注入到需要它的服务 Bean 中。确保在 DAO 中没有可变的共享状态,只有数据库操作。
  2. 我编写的 DAO 可能会使用映射函数将 ResultSet 映射到对象/集合,但我不认为需要使用辅助函数。
  3. Spring 偏好使用构造函数注入。你不应该使用 setter 或 autowired 属性来注入依赖。
  4. 如果你使用 new,意味着该对象不受 Spring 控制。在方法范围内为对象调用 new 是适当的,但不适用于像 DAO 这样的 Spring Bean。
  5. 单元测试和生产环境是两回事。我倾向于在单元测试中不使用 Spring。我在 JUnit 测试中调用 new,但不在生产代码中使用。一旦我测试过 DAO,就可以为依赖于它的服务使用模拟。

你明智地选择了学习 Spring,将 Java EE 抛在身后。Java EE 已经是一个二十年前的过时标准。

英文:

I have a few recommendations:

  1. DAO should be a singleton Spring Bean that you inject into service bean(s) that need it. Make sure there is no mutable shared state in your DAO - just database operations.
  2. The DAOs I write might use mapper functions to map ResultSet to objects/collections, but I don't see the need for helpers.
  3. Spring preference is to use constructor injection. You should not use setter or autowired attribute to inject dependencies.
  4. If you use new, that means the object is not under Spring's control. It's appropriate to call new for objects in method scope, but not a Spring Bean like a DAO.
  5. Unit testing and production are two different things. I prefer to leave Spring out of unit testing. I call new for JUnit tests, but not production code. Once I've tested the DAO, I can use mocks for services that depend on it.

You're smart to take up Spring and leave Java EE behind. It's a twenty year old dead standard.

huangapple
  • 本文由 发表于 2020年4月6日 22:53:47
  • 转载请务必保留本文链接:https://java.coder-hub.com/61062594.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定