Fix StatusAggregator static initialization

Prior to this commit, there was a cycle between `StatusAggregator` and
`SimpleStatusAggregator`, which caused a static initialization bug -
depending on which class (the implementation or its interface) was
loaded first.

This commit turns the static field of the `StatusAggregator` interface
into a static method to avoid this problem.

Fixes gh-21211
This commit is contained in:
Brian Clozel 2020-04-28 21:01:14 +02:00
parent ea5f282e9b
commit ec871d6752
5 changed files with 21 additions and 7 deletions

View File

@ -56,7 +56,7 @@ class AvailabilityProbesHealthEndpointGroup implements HealthEndpointGroup {
@Override
public StatusAggregator getStatusAggregator() {
return StatusAggregator.DEFAULT;
return StatusAggregator.getDefault();
}
@Override

View File

@ -57,7 +57,7 @@ class AvailabilityProbesHealthEndpointGroupTests {
@Test
void getStatusAggregatorReturnsDefaultStatusAggregator() {
assertThat(this.group.getStatusAggregator()).isEqualTo(StatusAggregator.DEFAULT);
assertThat(this.group.getStatusAggregator()).isEqualTo(StatusAggregator.getDefault());
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,6 +37,9 @@ import org.springframework.util.ObjectUtils;
public class SimpleStatusAggregator implements StatusAggregator {
private static final List<String> DEFAULT_ORDER;
static final StatusAggregator INSTANCE;
static {
List<String> defaultOrder = new ArrayList<>();
defaultOrder.add(Status.DOWN.getCode());
@ -44,6 +47,7 @@ public class SimpleStatusAggregator implements StatusAggregator {
defaultOrder.add(Status.UP.getCode());
defaultOrder.add(Status.UNKNOWN.getCode());
DEFAULT_ORDER = Collections.unmodifiableList(getUniformCodes(defaultOrder.stream()));
INSTANCE = new SimpleStatusAggregator();
}
private final List<String> order;

View File

@ -33,10 +33,13 @@ import java.util.Set;
public interface StatusAggregator {
/**
* A {@link StatusAggregator} instance using default ordering rules.
* Return {@link StatusAggregator} instance using default ordering rules.
* @return a {@code StatusAggregator} with default ordering rules.
* @since 2.3.0
*/
StatusAggregator DEFAULT = new SimpleStatusAggregator();
static StatusAggregator getDefault() {
return SimpleStatusAggregator.INSTANCE;
}
/**
* Return the aggregate status for the given set of statuses.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,14 @@ import static org.assertj.core.api.Assertions.assertThat;
class SimpleStatusAggregatorTests {
@Test
void getAggregateStatusWhenUsingDefaultOrder() {
void getAggregateStatusWhenUsingDefaultInstance() {
StatusAggregator aggregator = StatusAggregator.getDefault();
Status status = aggregator.getAggregateStatus(Status.DOWN, Status.UP, Status.UNKNOWN, Status.OUT_OF_SERVICE);
assertThat(status).isEqualTo(Status.DOWN);
}
@Test
void getAggregateStatusWhenUsingNewDefaultOrder() {
SimpleStatusAggregator aggregator = new SimpleStatusAggregator();
Status status = aggregator.getAggregateStatus(Status.DOWN, Status.UP, Status.UNKNOWN, Status.OUT_OF_SERVICE);
assertThat(status).isEqualTo(Status.DOWN);