[英]Difference between creating new instance and using scope prototype annotation in Spring
[英]New Instance Spring Scope
我正在使用 Spring Boot,我想知道是否有辦法在每次調用特定方法時創建一個新實例。
我的意思是,我有一個專用於創建自動裝配類的新實例的單例對象,我希望每次調用函數init
,只有當我調用它時,才會創建該對象的新實例。
@Component
public class PlatformFactoryManager {
@Autowired
private JiraFactory jiraFactory;
/**
* Obtain new factory instance of specified platform.
*/
public IPlatformFactory getNewInstance(UserAccount userAccount, AuthenticationService authService, PlatformBean platform) {
switch (platform.getPlatformName()) {
case "Jira Restaurantes":
jiraFactory.init(authService.getBy(userAccount.getUserId(), Platforms.JIRA_RESTAURANTES), platform);
return jiraFactory;
case "Jira Yapiko":
jiraFactory.init(authService.getBy(userAccount.getUserId(), Platforms.JIRA_YAPIKO), platform);
return jiraFactory;
case "Jira FDJGS":
jiraFactory.init(authService.getBy(userAccount.getUserId(), Platforms.JIRA_FDJGS), platform);
return jiraFactory;
default:
return null;
}
}
}
@Component
public class JiraFactory implements IPlatformFactory {
@Autowired
private JiraBroker jiraBroker;
private String platformName;
private String url;
public void init(UserAuthentication credentials, PlatformBean platform) {
this.platform = platform;
this.credentials = credentials;
jiraBroker.init(platform.getUrl());
}
...
}
我希望每次調用init
時JiraFactory
一個JiraFactory
的新實例,並且在我使用其他方法時是同一個對象。
有什么辦法嗎?
您也可以向組件添加@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
注釋
看看@Prototype
范圍。 您可以將JiraFactory
組件重構為如下所示:
public class JiraFactory implements IPlatformFactory {
private final JiraBroker jiraBroker;
private String platformName;
private String url;
public JiraFactory(final JiraBroker jiraBroker, UserAuthentication credentials, PlatformBean platform) {
this.jiraBroker=jiraBroker;
this.platform = platform;
this.credentials = credentials;
jiraBroker.init(platform.getUrl());
}
}
在@Configuration
類中,您可以創建JiraFactory
bean 作為原型 bean
@Configuration
class JiraConfig {
@Bean
@Scope("prototype")
public IPlatformFactory iPlatformFactory(final JiraBroker jiraBroker, final JiraBroker jiraBroker, UserAccount userAccount, AuthenticationService authService, PlatformBean platform) {
switch (platform.getPlatformName()) {
case "Jira Restaurantes":
return new JiraFactory (jiraBroker, authService.getBy(userAccount.getUserId(), Platforms.JIRA_RESTAURANTES), platform);
case "Jira Yapiko":
return new JiraFactory (jiraBroker, authService.getBy(userAccount.getUserId(), Platforms.JIRA_YAPIKO), platform);
case "Jira FDJGS":
return new JiraFactory (jiraBroker, authService.getBy(userAccount.getUserId(), Platforms.JIRA_FDJGS), platform);
default:
return null; // maybe better throw exception?
}
}
}
原型 bean 的行為類似於“普通”(單例)bean,您將能夠在其中@Autowire
其他服務。 但是,請記住,Spring 不管理這些 bean 的生命周期,這意味着它可能存在內存泄漏。
在某些方面,在談論原型范圍的 bean 時,您可以將 Spring 容器的角色視為 Java 'new' 運算符的某種替代品。 超過那個點的所有生命周期方面都必須由客戶處理。
這意味着,您必須以某種方式跟蹤這些 bean,並確保在某個時刻不存在對它們的引用,以便它們被垃圾收集。
旁注,通常建議避免使用init()
方法。 在大多數情況下,可以用構造函數替換它們。 如果無法使用它們,您可以嘗試使用@PostConstruct
而不是手動調用它們。
@Component
class MyComponent {
@PostConstruct
public void init(){ // will be called by Spring once the bean/component is created
System.out.println("Component created!");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.