Spring创建两个@Configuration bean启动

时间:2019-04-26 08:56:32

标签: java spring configuration

我有以下课程:

@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,该端点带有@Component注释

然后我尝试在端点中获取Bean

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

EndpointStatus在其他任何地方都没有使用。

据我所知,应该没有理由创建第二个bean ...

但是在启动时我总是得到

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

我在这里做什么错了?

编辑:

尝试了所有无济于事的答案。

我的班级现在看起来像这样

@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 个答案:

答案 0 :(得分:2)

只是一个猜测,但是将配置类定义为配置和工厂bean返回类型都可能是问题。
EndpointStatus是一个配置类,因为该类是用@Configuration声明的,并且一个配置类在Spring中产生一个bean,当您用{注释bean工厂方法getEndpointStatus()时,它也是一个显式bean。 {1}}。
就像您定义了两次bean一样。

答案 1 :(得分:2)

只需将您的Configuration类的名称从EndpointStatus更改为EndpointStatusConfig,然后将仅使用EndpointStatus类创建一个bean。

在将EndpointStatus都标记为@Configuration和@Bean时,它会创建2个Bean。

答案 2 :(得分:-1)

我认为您的问题是使用@Configuration而不是@Component

@Configuration将尝试使用@Autowired将类内的任何@Bean@Configuration添加到Spring上下文,但不会将其自身添加到Spring上下文。

如果要将该类作为bean添加到spring上下文中,则应使用@Component

编辑:

您是否尝试在自身上注入带有@Configuration的EndpointStatus类?

如果您不知道春季注射剂是什么,请尝试以下操作:

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