Новый экземпляр Spring Scope - PullRequest
1 голос
/ 04 февраля 2020

Я использую Spring boot, и я хотел бы знать, есть ли способ создавать новый экземпляр каждый раз, когда я вызываю конкретный c метод.

Я имею в виду, у меня есть одноэлементный объект, предназначенный для создания новых экземпляров класса с автосвязью, и я хочу, чтобы каждый раз, когда я вызываю функцию 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());
    }

...

}

Я хочу новый экземпляр JiraFactory каждый раз, когда я вызываю init, и быть тем же объектом, когда я использую другие методы.

Есть ли способ сделать это?

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Вы также можете добавить @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) аннотацию к компоненту

0 голосов
/ 04 февраля 2020

Взгляните на область действия @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 в качестве компонента-прототипа

@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?
        }
    }
}

Бобы-прототипы ведут себя как "обычные" (одиночные) бины, вы сможете @Autowire использовать в них другие службы. Однако имейте в виду, что Spring не управляет жизненным циклом этих компонентов, что означает возможную утечку памяти.

В некоторых отношениях вы можете думать о роли контейнеров Spring, когда говорите о bean-объекте с прототипом как о замене оператора Java 'new'. Все аспекты жизненного цикла после этой точки должны обрабатываться клиентом.

Это означает, что вам придется каким-то образом отслеживать эти компоненты и следить за тем, чтобы в какой-то момент не было ссылок на них будет существовать для того, чтобы их можно было собирать.


Примечание , обычно рекомендуется избегать 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!"); 
   }
}
...