当前位置: 代码迷 >> java >> Spring的自动装配,新操作员和困惑
  详细解决方案

Spring的自动装配,新操作员和困惑

热度:69   发布时间:2023-07-31 13:43:15.0

我有一个叫做发动机的课,还有一辆汽车。

class Engine {

...some params
...getters
...setters

}

class Car extends Engine {

... some params
... getters 
... setters

}

现在在控制器中说有一个名为“ ./getCarDetails”的端点

有一个对应于Engine类,称为engines

现在,因为对carDetails我需要的发动机和其他一些参数可以我使用engineRepository从其他一些细节的数据越来越引擎表的数据和otherRepository。

我所做的就是将Engine类作为组件并自动接线。 现在我有了engine bean,我正在为每辆车设置引擎值。 例如

@Autowired
Engine engine;

for(Car car: cars){
 car.setEngineParam(engine.getEngineParam());
}

问题 :-

每辆车都有相同的引擎

但是当我使用new运算符创建对象时,一切正常。

题:-

我应该永远不要在spring boot app中使用new operator吗?

没有新的操作员使用自动装配,如何解决当前问题?

引擎是相同的,因为默认范围是SINGLETON

每次从容器请求新bean时,都可以使用PROTOTYPE范围来获取新bean。 您还需要代理,因为您是在控制器中自动装配代理,而不是从容器中明确请求。 因此,用以下注释您的引擎类:

@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)

如果每次请求时都需要不同的引擎,则需要原型范围的bean,而不是单例@Component。 每次您请求时都会为您提供一个新对象。

或者,如果您可以命名的引擎数量有限,请使用命名的单例bean(请参阅@Qualifier)。 缺点是每次您请求相同的命名bean时,您都会得到相同的对象。

在Spring文档中找到“原型范围”。 祝好运!

您说您使Engine成为了一个组件:

我所做的就是将Engine类作为组件并自动接线。 现在我有了engine bean,我正在为每辆车设置引擎值。 例如

听起来Engine确实应该是一个实体(您的应用程序中的域类)。 将域对象的生命周期留给依赖项注入框架听起来有些困难。

Should i never use new operator in spring boot app ? 切勿对Spring托管bean使用new(例如,Controller,Repository,Service等)

How do i solve the current problem without new operator using autowiring ? 如果您有数据库,请将Engine类作为一个实体。 不要对引擎类使用自动装配。 它表示数据(数据库中的状态),不应将其视为依赖项。

如果所讨论的类是由依赖注入框架管理的,则永远不要用new创建它。

首先,我认为Car不应扩展Engine,因为Car不是引擎。 汽车具有引擎,应提供。 示例通过构造函数显示,但也可以设置。 不建议使用 ,它被认为是有害的。

public class Car {
  private Engine engine;
  public Car(Engine engine) {
     this.engine = engine;
  }
}

关于将Car和Engine创建为容器中的 。 除非您只希望在应用程序中使用一辆带有一个引擎的汽车,否则您必须采用另一种方式。

有几种方法。 您可以根据需要配置任意数量的汽车,并通过将其创建为@Bean来为它们提供不同的引擎

创建一个类(在容器启动时调用)并添加汽车和引擎

@Bean
public Car ford() {return new Car(v8());}
//public Car ford(Engine v8) {return new Car(v8);} // if engines is in separate configuration file

@Bean
public Engine v8() {
  return new V8Engine(); // extends/implements Engine
}

@Bean
public Engine standard() {
  return new StandardEngine(); // extends/implements Engine
}

但是,您可以通过扩展/实现Car来创建诸如Ford,Volvo和BMW之类的实现,并将@Component和@Autowire用于引擎。

  相关解决方案