问题描述
我有一个叫做发动机的课,还有一辆汽车。
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吗?
没有新的操作员使用自动装配,如何解决当前问题?
1楼
引擎是相同的,因为默认范围是SINGLETON
。
每次从容器请求新bean时,都可以使用PROTOTYPE
范围来获取新bean。
您还需要代理,因为您是在控制器中自动装配代理,而不是从容器中明确请求。
因此,用以下注释您的引擎类:
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
2楼
如果每次请求时都需要不同的引擎,则需要原型范围的bean,而不是单例@Component。 每次您请求时都会为您提供一个新对象。
或者,如果您可以命名的引擎数量有限,请使用命名的单例bean(请参阅@Qualifier)。 缺点是每次您请求相同的命名bean时,您都会得到相同的对象。
在Spring文档中找到“原型范围”。 祝好运!
3楼
您说您使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
创建它。
4楼
首先,我认为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用于引擎。