簡體   English   中英

新實例 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());
    }

...

}

我希望每次調用initJiraFactory一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM