我有一个叫做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运算符吗?
在没有新操作员的情况下如何解决当前问题 自动接线?
答案 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作为引擎来创建福特,沃尔沃和宝马之类的实现。