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

时间:2019-02-14 05:53:21

标签: java spring spring-boot

我有一个叫做Engine和Car的课。

class Engine {

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

}

class Car extends Engine {

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

}

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

的端点。

有一个对应于名为 engines 的Engine类。

现在,由于对于 carDetails我需要引擎和其他一些参数,因此我正在使用 engineRepository 从其他一些详细信息数据中获取引擎表的数据和otherRepository。

我所做的是我使Engine类成为一个组件并对其自动接线。现在我有了engine bean,我正在为每辆车设置引擎值。 例如。

@Autowired
Engine engine;

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

问题:-

每辆车具有相同的发动机

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

问题:-

  

我应该从不在Spring Boot应用程序中使用new运算符吗?

     

在没有新操作员的情况下如何解决当前问题   自动接线?

4 个答案:

答案 0 :(得分:1)

引擎是一样的,因为默认范围是SINGLETON

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

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

您说您将Engine做成了一个组件:

  

我所做的是我使Engine类成为一个组件并对其自动接线。现在我有了engine bean,我正在为每辆车设置引擎值。例如。

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

Should i never use new operator in spring boot app ? 切勿对Spring托管的bean(例如,控制器,存储库,服务等)使用new

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

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

答案 3 :(得分:0)

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

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

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

有几种方法。您可以根据需要配置任意数量的汽车,并通过将其创建为@Bean

来为它们提供不同的引擎

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

@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并使用@Component和@Autowire作为引擎来创建福特,沃尔沃和宝马之类的实现。