Skip to content

Commit d7356aa

Browse files
artembilangaryrussell
authored andcommitted
Use Context CL wherever it is applicable (#2656)
* Use Context CL wherever it is applicable * Use `ClassUtils.getDefaultClassLoader()` in the `IntegrationManagementConfigurer` for checking a Micrometer presence from the `afterSingletonsInstantiated()` * Use `ClassUtils.getDefaultClassLoader()` in the `ScatterGatherHandler` to load required class * Refactor `HeaderEnricherParserSupport` do not use CL at all. The `TypedStringValue` will resolve a target type later by the `BeanFactory`. This way we honor a property placeholder behavior for the `type` XML attribute * * Use `ClassUtils.getDefaultClassLoader()` in the ScatterGatherHandler ctor
1 parent 33e5248 commit d7356aa

File tree

4 files changed

+42
-47
lines changed

4 files changed

+42
-47
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,8 @@ public void afterSingletonsInstantiated() {
225225
Assert.state(this.applicationContext != null, "'applicationContext' must not be null");
226226
Assert.state(MANAGEMENT_CONFIGURER_NAME.equals(this.beanName), getClass().getSimpleName()
227227
+ " bean name must be " + MANAGEMENT_CONFIGURER_NAME);
228-
ClassLoader classLoader = IntegrationManagementConfigurer.class.getClassLoader();
229228
if (ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry",
230-
classLoader)) {
229+
this.applicationContext.getClassLoader())) {
231230
this.metricsCaptor = MicrometerMetricsCaptor.loadCaptor(this.applicationContext);
232231
}
233232
if (this.metricsCaptor != null) {

spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java

+28-34
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import org.springframework.integration.transformer.support.MessageProcessingHeaderValueMessageProcessor;
4040
import org.springframework.integration.transformer.support.RoutingSlipHeaderValueMessageProcessor;
4141
import org.springframework.integration.transformer.support.StaticHeaderValueMessageProcessor;
42-
import org.springframework.util.ClassUtils;
4342
import org.springframework.util.StringUtils;
4443
import org.springframework.util.xml.DomUtils;
4544

@@ -50,15 +49,16 @@
5049
* @author Oleg Zhurakousky
5150
* @author Artem Bilan
5251
* @author Gary Russell
52+
*
5353
* @since 2.0
5454
*/
5555
public abstract class HeaderEnricherParserSupport extends AbstractTransformerParser {
5656

57-
private final Map<String, String> elementToNameMap = new HashMap<String, String>();
57+
private final static Map<String, String[][]> cannedHeaderElementExpressions = new HashMap<>();
5858

59-
private final Map<String, Class<?>> elementToTypeMap = new HashMap<String, Class<?>>();
59+
private final Map<String, String> elementToNameMap = new HashMap<>();
6060

61-
private final static Map<String, String[][]> cannedHeaderElementExpressions = new HashMap<String, String[][]>();
61+
private final Map<String, String> elementToTypeMap = new HashMap<>();
6262

6363
static {
6464
cannedHeaderElementExpressions.put("header-channels-to-string", new String[][] {
@@ -75,10 +75,10 @@ protected final String getTransformerClassName() {
7575
}
7676

7777
protected final void addElementToHeaderMapping(String elementName, String headerName) {
78-
this.addElementToHeaderMapping(elementName, headerName, null);
78+
addElementToHeaderMapping(elementName, headerName, null);
7979
}
8080

81-
protected final void addElementToHeaderMapping(String elementName, String headerName, Class<?> headerType) {
81+
protected final void addElementToHeaderMapping(String elementName, String headerName, String headerType) {
8282
this.elementToNameMap.put(elementName, headerName);
8383
if (headerType != null) {
8484
this.elementToTypeMap.put(elementName, headerType);
@@ -104,7 +104,7 @@ protected void processHeaders(Element element, ManagedMap<String, Object> header
104104
String headerName = null;
105105
Element headerElement = (Element) node;
106106
String elementName = node.getLocalName();
107-
Class<?> headerType = null;
107+
String headerType = null;
108108
String expression = null;
109109
String overwrite = headerElement.getAttribute("overwrite");
110110
if ("header".equals(elementName)) {
@@ -116,24 +116,11 @@ protected void processHeaders(Element element, ManagedMap<String, Object> header
116116
if (headerType != null && StringUtils.hasText(headerElement.getAttribute("type"))) {
117117
parserContext.getReaderContext().error("The " + elementName
118118
+ " header does not accept a 'type' attribute. The required type is ["
119-
+ headerType.getName() + "]", element);
119+
+ headerType + "]", element);
120120
}
121121
}
122122
if (headerType == null) {
123-
String headerTypeName = headerElement.getAttribute("type");
124-
if (StringUtils.hasText(headerTypeName)) {
125-
ClassLoader classLoader = parserContext.getReaderContext().getBeanClassLoader();
126-
if (classLoader == null) {
127-
classLoader = getClass().getClassLoader();
128-
}
129-
try {
130-
headerType = ClassUtils.forName(headerTypeName, classLoader);
131-
}
132-
catch (Exception e) {
133-
parserContext.getReaderContext().error("unable to resolve type [" +
134-
headerTypeName + "] for header '" + headerName + "'", element, e);
135-
}
136-
}
123+
headerType = headerElement.getAttribute("type");
137124
}
138125
if (headerName == null) {
139126
String ttlExpression = headerElement.getAttribute("time-to-live-expression");
@@ -148,21 +135,20 @@ protected void processHeaders(Element element, ManagedMap<String, Object> header
148135
expression = expression.replace(", ####", "");
149136
}
150137
overwrite = "true";
151-
this.addHeader(element, headers, parserContext, headerName, headerElement, headerType,
138+
addHeader(element, headers, parserContext, headerName, headerElement, headerType,
152139
expression, overwrite);
153140
}
154141
}
155142
}
156143
else {
157-
this.addHeader(element, headers, parserContext, headerName, headerElement, headerType, null,
158-
overwrite);
144+
addHeader(element, headers, parserContext, headerName, headerElement, headerType, null, overwrite);
159145
}
160146
}
161147
}
162148
}
163149

164150
private void addHeader(Element element, ManagedMap<String, Object> headers, ParserContext parserContext,
165-
String headerName, Element headerElement, Class<?> headerType, String expression, String overwrite) {
151+
String headerName, Element headerElement, String headerType, String expression, String overwrite) {
166152

167153
String value = headerElement.getAttribute("value");
168154
String ref = headerElement.getAttribute(REF_ATTRIBUTE);
@@ -233,15 +219,20 @@ else if (isScript) {
233219
"The 'method' attribute cannot be used with the 'value' attribute.", element);
234220
}
235221
if (IntegrationMessageHeaderAccessor.ROUTING_SLIP.equals(headerName)) {
236-
List<String> routingSlipPath = new ManagedList<String>();
222+
List<String> routingSlipPath = new ManagedList<>();
237223
routingSlipPath.addAll(Arrays.asList(StringUtils.tokenizeToStringArray(value, ";")));
238224
valueProcessorBuilder =
239225
BeanDefinitionBuilder.genericBeanDefinition(RoutingSlipHeaderValueMessageProcessor.class)
240226
.addConstructorArgValue(routingSlipPath);
241227
}
242228
else {
243-
Object headerValue = (headerType != null) ?
244-
new TypedStringValue(value, headerType) : value;
229+
Object headerValue = value;
230+
231+
if (StringUtils.hasText(headerType)) {
232+
TypedStringValue typedStringValue = new TypedStringValue(value);
233+
typedStringValue.setTargetTypeName(headerType);
234+
headerValue = typedStringValue;
235+
}
245236
valueProcessorBuilder =
246237
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
247238
.addConstructorArgValue(headerValue);
@@ -280,8 +271,9 @@ else if (isCustomBean) {
280271
}
281272
}
282273
else {
283-
valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class);
284-
valueProcessorBuilder.addConstructorArgValue(innerComponentDefinition);
274+
valueProcessorBuilder =
275+
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
276+
.addConstructorArgValue(innerComponentDefinition);
285277
}
286278
}
287279
else {
@@ -296,8 +288,9 @@ else if (isCustomBean) {
296288
.addConstructorArgValue(method);
297289
}
298290
else {
299-
valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
300-
.addConstructorArgReference(ref);
291+
valueProcessorBuilder =
292+
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
293+
.addConstructorArgReference(ref);
301294
}
302295
}
303296
if (StringUtils.hasText(overwrite)) {
@@ -312,7 +305,8 @@ else if (isCustomBean) {
312305
* @param element The element.
313306
* @param parserContext The parser context.
314307
*/
315-
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
308+
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element,
309+
ParserContext parserContext) {
316310
}
317311

318312
}

spring-integration-core/src/main/java/org/springframework/integration/config/xml/StandardHeaderEnricherParser.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,16 +36,18 @@
3636
*
3737
* @author Mark Fisher
3838
* @author Oleg Zhurakousky
39+
* @author Artem Bilan
3940
*/
4041
public class StandardHeaderEnricherParser extends HeaderEnricherParserSupport {
4142

4243
public StandardHeaderEnricherParser() {
43-
this.addElementToHeaderMapping("reply-channel", MessageHeaders.REPLY_CHANNEL);
44-
this.addElementToHeaderMapping("error-channel", MessageHeaders.ERROR_CHANNEL);
45-
this.addElementToHeaderMapping("correlation-id", IntegrationMessageHeaderAccessor.CORRELATION_ID);
46-
this.addElementToHeaderMapping("expiration-date", IntegrationMessageHeaderAccessor.EXPIRATION_DATE, Long.class);
47-
this.addElementToHeaderMapping("priority", IntegrationMessageHeaderAccessor.PRIORITY, Integer.class);
48-
this.addElementToHeaderMapping("routing-slip", IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class);
44+
addElementToHeaderMapping("reply-channel", MessageHeaders.REPLY_CHANNEL);
45+
addElementToHeaderMapping("error-channel", MessageHeaders.ERROR_CHANNEL);
46+
addElementToHeaderMapping("correlation-id", IntegrationMessageHeaderAccessor.CORRELATION_ID);
47+
addElementToHeaderMapping("expiration-date", IntegrationMessageHeaderAccessor.EXPIRATION_DATE,
48+
Long.class.getName());
49+
addElementToHeaderMapping("priority", IntegrationMessageHeaderAccessor.PRIORITY, Integer.class.getName());
50+
addElementToHeaderMapping("routing-slip", IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class.getName());
4951
}
5052

5153
@Override

spring-integration-core/src/main/java/org/springframework/integration/scattergather/ScatterGatherHandler.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,13 @@ public boolean isRunning() {
177177
}
178178

179179
private void checkClass(Class<?> gathererClass, String className, String type) throws LinkageError {
180-
Class<?> clazz = null;
181180
try {
182-
clazz = ClassUtils.forName(className, getClass().getClassLoader());
181+
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
182+
Assert.isAssignable(clazz, gathererClass, "the '" + type + "' must be an " + className + " instance");
183183
}
184-
catch (Exception e) {
184+
catch (ClassNotFoundException e) {
185+
throw new IllegalStateException("The class for '" + className + "' cannot be loaded", e);
185186
}
186-
Assert.isAssignable(clazz, gathererClass, "the '" + type + "' must be an " + className + " instance");
187187
}
188188

189189
}

0 commit comments

Comments
 (0)