Spring создает два бина @Configuration при запуске - PullRequest
1 голос
/ 26 апреля 2019

У меня есть следующий класс:

@Configuration
public class EndpointStatus {

private static final Logger serverLogger = LogManager.getLogger(EndpointStatus.class);

private Long id;
private volatile Status status;

@OneToOne
private volatile CurrentJob currentJob;

public enum Status {
    AVAILABLE,
    BUSY
}

@Bean
@Primary
public EndpointStatus getEndpointStatus() {
    serverLogger.info("STATUS CREATED");
    return new EndpointStatus();
}

public EndpointStatus() {
}

public CurrentJob getCurrentJob() {
    return currentJob;
}

public void setCurrentJob(CurrentJob currentJob) {
    this.currentJob = currentJob;
}

public Status getStatus() {
    return status;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public void setStatus(Status status) {
    this.status = status;
}

public boolean isBusy() {
    return getStatus() == Status.BUSY;
}

Бин используется в конечной точке, которая помечена @ Component

и затем я пытаюсь получить бин в конечной точке, как

ApplicationContext ctx = new AnnotationConfigApplicationContext(EndpointStatus.class);
EndpointStatus sc = ctx.getBean(EndpointStatus.class);

EndpointStatus больше нигде не используется.

Насколько мне известно, не должно быть оснований для создания второго компонента ...

Однако при запуске я всегда получаю

INFO 6169 [main] c.e.k.d.r.m.i.EndpointStatus             : STATUS CREATED
INFO 6169 [main] c.e.k.d.r.m.i.EndpointStatus             : STATUS CREATED

Что я здесь не так делаю?

EDIT:

Перепробовал каждый ответ, но безрезультатно.

мой класс теперь выглядит так

@Configuration
public class EndpointStatusConfig {

private static final Logger serverLogger = LogManager.getLogger(JavaXRest.class);

private Long id;
private volatile Status status = EndpointStatusConfig.Status.AVAILABLE;

@OneToOne
private volatile CurrentJob currentJob;

public enum Status {
    AVAILABLE,
    BUSY
}

@Bean
@Primary
public EndpointStatusConfig getEndpointStatus() {
    serverLogger.info("STATUS CREATED");
    return new EndpointStatusConfig();
}

public CurrentJob getCurrentJob() {
    return currentJob;
}

public void setCurrentJob(CurrentJob currentJob) {
    this.currentJob = currentJob;
}

public Status getStatus() {
    return status;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public void setStatus(Status status) {
    this.status = status;
}

public boolean isBusy() {
    return getStatus() == Status.BUSY;
}

  } 

независимо от того, @Component или @Configuration, вызов sc в конечной точке приведет к сотням bean-компонентов, созданных для сбоя приложения ...

EDIT2: это становится все хуже и хуже ... теперь даже звони на

if ( sc.isBusy() ) { return Response.ok( sc.getCurrentJob() ).type(MediaType.APPLICATION_JSON).build(); }

перейдет к @Bean и создаст столько объектов EndpointStatus, сколько сможет, до сбоя приложения .... @Component создает один объект при запуске, затем тысячи. @Configuration создаст 2 при запуске, а затем тысячи также ...

Ответы [ 3 ]

2 голосов
/ 26 апреля 2019

Вероятно, проблема заключается в догадках, но определение класса конфигурации как конфигурации, так и типа возврата фабричного компонента
EndpointStatus - это класс конфигурации, поскольку класс объявлен с @Configuration, а класс конфигурации создаетbean-компонент Spring, и он также является явным bean-компонентом, поскольку вы аннотировали метод фабрики bean-компонентов getEndpointStatus() с помощью @Bean.
Это немного похоже на то, что вы определили дважды bean-компонент.

2 голосов
/ 26 апреля 2019

Просто измените имя вашего класса конфигурации с EndpointStatus на EndpointStatusConfig, и тогда будет создан только один компонент с классом EndpointStatus.

Поскольку вы аннотируете EndpointStatus как @Configuration & @Bean, он создает 2 компонента..

0 голосов
/ 26 апреля 2019

Я думаю, что ваша проблема использует @Configuration вместо @Component

@Configuration попытается добавить в контекст пружины любой @Autowired или @Bean внутри класса с @Configuration, но выигралне добавляйте его самостоятельно в контекст весны.

Если вы хотите добавить этот класс в качестве bean-компонента к контексту весны, вы должны использовать @Component

Редактировать:

Вы пытались внедрить класс EndpointStatus с @Configuration на себя?

Если вы не знаете, что такое инъекция весной, попробуйте следующее:

@Autowired
EndpointStatus status;

void yourMethod(){
   //Change this 
   //ApplicationContext ctx = new AnnotationConfigApplicationContext(EndpointStatus.class);
   //EndpointStatus sc = ctx.getBean(EndpointStatus.class);
   //Use instead the status variable declared before
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...