【问题标题】:Should i never use 'new' keyword on a spring boot project?我不应该在 Spring Boot 项目中使用“new”关键字吗?
【发布时间】:2018-09-11 01:24:40
【问题描述】:

我正在研究 Spring Boot Rest API,我最终还是到处使用 new 关键字。

我想知道,我在程序中使用 new 关键字时是否做错了什么。如果绝对禁止在实际项目中使用 new 关键字。

如果答案是肯定的,我应该使用@component 注释来注释我编写的每个类,以便我可以使用@autowired 实例化一个对象。

如果答案是否定的,我们什么时候可以打破这条规则?

【问题讨论】:

  • 你可以做任何你想做的事情
  • @JacobG。谢谢大佬。

标签: java spring spring-boot dependency-injection


【解决方案1】:

您可以在 spring 应用程序中使用 new 关键字创建对象。

但这些对象将超出 Spring Application Context 的范围,因此不受 Spring 管理。

由于这些不是 Spring 管理的,因此任何嵌套级别的依赖项(例如您的 Service 类具有对您的 Repository 类的引用等) 不会解决。

因此,如果您尝试调用服务类中的方法,您最终可能会获得存储库的 NullPointer。

@Service
public class GreetingService {
    @Autowired
    private GreetingRepository greetingRepository;
    public String greet(String userid) {
       return greetingRepository.greet(userid); 
    }
}

@RestController
public class GreetingController {
    @Autowired
    private GreetingService greetingService;
    @RequestMapping("/greeting")
    public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello %s", greetingService.greet(name));
    }
    @RequestMapping("/greeting2")
    public String greeting2(@RequestParam(value = "name", defaultValue = "World") String name) {
      GreetingService newGreetingService = new GreetingService();
      return String.format("Hello %s", newGreetingService.greet(name));
    }
}

在上面的例子中,/greeting 可以工作,但/greeting2 会失败,因为嵌套的依赖关系没有被解析。

因此,如果您希望您的对象由弹簧管理,那么您必须自动装配它们。 一般来说,对于视图层 pojo 和自定义 bean 配置,您将使用 new 关键字。

【讨论】:

    【解决方案2】:

    没有使用或不使用new的规则。 如果您希望 Spring 管理您的对象或想自己处理它们,这取决于您。 Spring 简化了对象创建、依赖管理和自动连接;但是,如果您不想这样做,可以使用 new 实例化它。

    【讨论】:

      【解决方案3】:

      我认为使用new 关键字很好,但你应该了解不同原型(Controller、Service、Repository)之间的区别

      您可以按照这个问题弄清楚:

      What's the difference between @Component, @Repository & @Service annotations in Spring?

      使用适当的注释将允许您正确使用 DI(依赖注入),这将有助于为您的 Spring Boot 应用程序编写切片测试。 Service,ControllerRepository 组件也被创建为 Singleton,因此 GC 开销较小。此外,使用 new 关键字创建的组件不受 Spring 管理,默认情况下 Spring 永远不会在使用 new 创建的对象中注入依赖项。

      Spring 官方文档: https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.html

      【讨论】:

        【解决方案4】:

        当您必须将对象创建为服务并将模拟对象注入为 dao 时,您将需要 new 在 Spring 模拟测试中。

        【讨论】:

          【解决方案5】:

          看下面的代码;如您所见,根据需要动态加载广告的条件。所以这里你不能@autowire这组项目,因为所有信息都是从数据库或外部系统加载的,所以你只需要相应地填充你的模型。

          if (customer.getType() == CustomerType.INTERNET) {
              List < Advertisement > adList = new ArrayList < Advertisement > ();
              for (Product product: internetProductList) {
                  Advertisement advertisement = new Advertisement();
                  advertisement.setProduct(product);
                  adList.add(advertisement);
              }
          }
          

          注意使用 Spring 来管理外部依赖项是合适的 就像将 JDBC 连接插入 DAO 或类似的配置 指定要使用的数据库类型。

          【讨论】:

            猜你喜欢
            • 2020-06-19
            • 2020-08-14
            • 2017-12-15
            • 2012-03-07
            • 1970-01-01
            • 1970-01-01
            • 2011-02-04
            • 1970-01-01
            • 2011-07-27
            相关资源
            最近更新 更多