Skip to content

Commit a1c1e32

Browse files
committed
Call spring.factories customizers in the same way as one from props
Previously, customizers loaded from spring.factories were called using LambdaSafe. This resulted in customizers with a generic type more specific than Object being ignored. A customizer loaded from the logging.structured.json.customizer property was not affected as it was called directly rather than through LambdaSafe. This commit aligns the way in which customizers loaded from spring.factories are called with the way in which any customizer specified using the logging.structured.json.customizer property is called. Closes gh-43312
1 parent f9aedf5 commit a1c1e32

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.boot.util.Instantiator;
2828
import org.springframework.boot.util.Instantiator.AvailableParameters;
2929
import org.springframework.boot.util.Instantiator.FailureHandler;
30-
import org.springframework.boot.util.LambdaSafe;
3130
import org.springframework.core.GenericTypeResolver;
3231
import org.springframework.core.env.Environment;
3332
import org.springframework.core.io.support.SpringFactoriesLoader;
@@ -108,11 +107,12 @@ private List<StructuredLoggingJsonMembersCustomizer<?>> loadStructuredLoggingJso
108107
ArgumentResolver.from(this.instantiator::getArg));
109108
}
110109

111-
@SuppressWarnings("unchecked")
110+
@SuppressWarnings({ "unchecked", "rawtypes" })
112111
private void invokeCustomizers(List<StructuredLoggingJsonMembersCustomizer<?>> customizers,
113112
Members<Object> members) {
114-
LambdaSafe.callbacks(StructuredLoggingJsonMembersCustomizer.class, customizers, members)
115-
.invoke((customizer) -> customizer.customize(members));
113+
for (StructuredLoggingJsonMembersCustomizer<?> customizer : customizers) {
114+
((StructuredLoggingJsonMembersCustomizer) customizer).customize(members);
115+
}
116116
}
117117

118118
/**

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactoryTests.java

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.junit.jupiter.api.Test;
2222

23+
import org.springframework.boot.json.JsonWriter.Members;
2324
import org.springframework.boot.json.JsonWriter.ValueProcessor;
2425
import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters;
2526
import org.springframework.boot.util.Instantiator.AvailableParameters;
@@ -104,18 +105,49 @@ void getUsingClassNameInjectsCustomParameter() {
104105
}
105106

106107
@Test
107-
void getInjectCustomizers() {
108+
void getInjectStringMembersCustomizer() {
108109
this.environment.setProperty("logging.structured.json.rename.spring", "test");
109110
SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class);
110-
StructuredLoggingJsonMembersCustomizer<?> customizer = (members) -> members
111-
.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase));
112-
given(factoriesLoader.load(any(), any(ArgumentResolver.class))).willReturn(List.of(customizer));
111+
given(factoriesLoader.load(any(), any(ArgumentResolver.class)))
112+
.willReturn(List.of(new StringMembersStructuredLoggingJsonMembersCustomizer()));
113113
StructuredLogFormatterFactory<LogEvent> factory = new StructuredLogFormatterFactory<>(factoriesLoader,
114114
LogEvent.class, this.environment, this::addAvailableParameters, this::addCommonFormatters);
115-
CutomizedFormatter formatter = (CutomizedFormatter) factory.get(CutomizedFormatter.class.getName());
115+
CustomizedFormatter formatter = (CustomizedFormatter) factory.get(CustomizedFormatter.class.getName());
116116
assertThat(formatter.format(new LogEvent())).contains("\"test\":\"BOOT\"");
117117
}
118118

119+
@Test
120+
void getInjectObjectMembersCustomizer() {
121+
this.environment.setProperty("logging.structured.json.rename.spring", "test");
122+
SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class);
123+
given(factoriesLoader.load(any(), any(ArgumentResolver.class)))
124+
.willReturn(List.of(new ObjectMembersStructuredLoggingJsonMembersCustomizer()));
125+
StructuredLogFormatterFactory<LogEvent> factory = new StructuredLogFormatterFactory<>(factoriesLoader,
126+
LogEvent.class, this.environment, this::addAvailableParameters, this::addCommonFormatters);
127+
CustomizedFormatter formatter = (CustomizedFormatter) factory.get(CustomizedFormatter.class.getName());
128+
assertThat(formatter.format(new LogEvent())).contains("\"test\":\"BOOT\"");
129+
}
130+
131+
static class StringMembersStructuredLoggingJsonMembersCustomizer
132+
implements StructuredLoggingJsonMembersCustomizer<String> {
133+
134+
@Override
135+
public void customize(Members<String> members) {
136+
members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase));
137+
}
138+
139+
}
140+
141+
static class ObjectMembersStructuredLoggingJsonMembersCustomizer
142+
implements StructuredLoggingJsonMembersCustomizer<Object> {
143+
144+
@Override
145+
public void customize(Members<Object> members) {
146+
members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase));
147+
}
148+
149+
}
150+
119151
static class LogEvent {
120152

121153
}
@@ -167,9 +199,9 @@ public String format(DifferentLogEvent event) {
167199

168200
}
169201

170-
static class CutomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
202+
static class CustomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
171203

172-
CutomizedFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
204+
CustomizedFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
173205
super((members) -> members.add("spring", "boot"), customizer);
174206
}
175207

0 commit comments

Comments
 (0)