简体   繁体   English

Spring创建了两个@Configuration bean启动

[英]Spring creates two of @Configuration beans starting up

I have following class: 我有以下课程:

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

Bean is used in endpoint which is annotated with @Component Bean用于使用@Component注释的端点

and then i try to get the bean in endpoint like 然后我尝试在端点中获取bean

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

EndpointStatus is not used anywhere else. 在任何其他地方都不使用EndpointStatus

To my knowledge, there should be no reason to create a second bean... 据我所知,没有理由创建第二个bean ...

However at startup I always get 但是在创业时我总是得到

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

What am I doing wrong here? 我在这做错了什么?

EDIT: 编辑:

Have tried every answer given to no avail whatsoever.. 尝试过的每一个答案都无济于事......

my class now looks like this 我的课现在看起来像这样

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

  } 

no matter @Component or @Configuration, making call to sc in endpoint will result in hundreds of beans created crashing the app... 无论是@Component还是@Configuration,在端点调用sc都会导致数百个bean被创建崩溃应用程序...

EDIT2: this is just getting worse and worse ... now even call to EDIT2:这变得越来越糟 ......现在甚至打电话给

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

will jump to @Bean and create as many EndpointStatus objects as it can before the application crashes.... @Component creates one at startup, then thousands. 将跳转到@Bean并在应用程序崩溃之前创建尽可能多的EndpointStatus对象.... @Component在启动时创建一个,然后创建数千个。 @Configuration will create 2 at startup and then thousands also... @Configuration将在启动时创建2,然后成千上万...

Just a guesswork but defining the configuration class both as a configuration and a factory bean return type is probably the issue. 只是猜测,但将配置类定义为配置和工厂bean返回类型可能是个问题。
EndpointStatus is a configuration class as the class is declared with @Configuration and a configuration class produces a bean in Spring and it is also an explicit bean as you annotated the bean factory method getEndpointStatus() with @Bean . EndpointStatus是配置类的类被声明与@Configuration和配置类在春季产生一个bean,它也是一个明确的bean作为您注释的bean工厂方法getEndpointStatus()@Bean
It is a little like if you had defined twice the bean. 这有点像你已经定义了两次bean。

Simply change the name of your Configuration class from EndpointStatus to EndpointStatusConfig and this will then only create a single bean with EndpointStatus class. 只需将Configuration类的名称从EndpointStatus更改为EndpointStatusConfig,然后只创建一个带有EndpointStatus类的bean。

As you are annotating EndpointStatus both as @Configuration & @Bean it creates 2 Beans. 当您将EndpointStatus注释为@Configuration和@Bean时,它会创建2个Bean。

I think your problem is using @Configuration instead of @Component 我认为您的问题是使用@Configuration而不是@Component

The @Configuration will try add to spring context any @Autowired or @Bean inside the class with @Configuration but won't add it self to the spring context. @Configuration将尝试使用@Configuration在类中添加任何@Autowired@Bean spring上下文,但不会将它自己添加到spring上下文中。

If you want to add that class as a bean to the spring context you should use @Component 如果要将该类作为bean添加到spring上下文中,则应使用@Component

Edit: 编辑:

Did you try to inject EndpointStatus class with the @Configuration on it self? 您是否尝试使用@Configuration自行注入EndpointStatus类?

In case you don't and don't know what is injection in spring try this: 如果你没有,也不知道春天注射什么,试试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM