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
This commit is contained in:
Artem Bilan
2018-12-13 16:14:37 -05:00
committed by Gary Russell
parent 33e52486cf
commit d7356aa85d
4 changed files with 42 additions and 47 deletions

View File

@@ -225,9 +225,8 @@ public class IntegrationManagementConfigurer
Assert.state(this.applicationContext != null, "'applicationContext' must not be null");
Assert.state(MANAGEMENT_CONFIGURER_NAME.equals(this.beanName), getClass().getSimpleName()
+ " bean name must be " + MANAGEMENT_CONFIGURER_NAME);
ClassLoader classLoader = IntegrationManagementConfigurer.class.getClassLoader();
if (ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry",
classLoader)) {
this.applicationContext.getClassLoader())) {
this.metricsCaptor = MicrometerMetricsCaptor.loadCaptor(this.applicationContext);
}
if (this.metricsCaptor != null) {

View File

@@ -39,7 +39,6 @@ import org.springframework.integration.transformer.support.ExpressionEvaluatingH
import org.springframework.integration.transformer.support.MessageProcessingHeaderValueMessageProcessor;
import org.springframework.integration.transformer.support.RoutingSlipHeaderValueMessageProcessor;
import org.springframework.integration.transformer.support.StaticHeaderValueMessageProcessor;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
@@ -50,15 +49,16 @@ import org.springframework.util.xml.DomUtils;
* @author Oleg Zhurakousky
* @author Artem Bilan
* @author Gary Russell
*
* @since 2.0
*/
public abstract class HeaderEnricherParserSupport extends AbstractTransformerParser {
private final Map<String, String> elementToNameMap = new HashMap<String, String>();
private final static Map<String, String[][]> cannedHeaderElementExpressions = new HashMap<>();
private final Map<String, Class<?>> elementToTypeMap = new HashMap<String, Class<?>>();
private final Map<String, String> elementToNameMap = new HashMap<>();
private final static Map<String, String[][]> cannedHeaderElementExpressions = new HashMap<String, String[][]>();
private final Map<String, String> elementToTypeMap = new HashMap<>();
static {
cannedHeaderElementExpressions.put("header-channels-to-string", new String[][] {
@@ -75,10 +75,10 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
}
protected final void addElementToHeaderMapping(String elementName, String headerName) {
this.addElementToHeaderMapping(elementName, headerName, null);
addElementToHeaderMapping(elementName, headerName, null);
}
protected final void addElementToHeaderMapping(String elementName, String headerName, Class<?> headerType) {
protected final void addElementToHeaderMapping(String elementName, String headerName, String headerType) {
this.elementToNameMap.put(elementName, headerName);
if (headerType != null) {
this.elementToTypeMap.put(elementName, headerType);
@@ -104,7 +104,7 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
String headerName = null;
Element headerElement = (Element) node;
String elementName = node.getLocalName();
Class<?> headerType = null;
String headerType = null;
String expression = null;
String overwrite = headerElement.getAttribute("overwrite");
if ("header".equals(elementName)) {
@@ -116,24 +116,11 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
if (headerType != null && StringUtils.hasText(headerElement.getAttribute("type"))) {
parserContext.getReaderContext().error("The " + elementName
+ " header does not accept a 'type' attribute. The required type is ["
+ headerType.getName() + "]", element);
+ headerType + "]", element);
}
}
if (headerType == null) {
String headerTypeName = headerElement.getAttribute("type");
if (StringUtils.hasText(headerTypeName)) {
ClassLoader classLoader = parserContext.getReaderContext().getBeanClassLoader();
if (classLoader == null) {
classLoader = getClass().getClassLoader();
}
try {
headerType = ClassUtils.forName(headerTypeName, classLoader);
}
catch (Exception e) {
parserContext.getReaderContext().error("unable to resolve type [" +
headerTypeName + "] for header '" + headerName + "'", element, e);
}
}
headerType = headerElement.getAttribute("type");
}
if (headerName == null) {
String ttlExpression = headerElement.getAttribute("time-to-live-expression");
@@ -148,21 +135,20 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
expression = expression.replace(", ####", "");
}
overwrite = "true";
this.addHeader(element, headers, parserContext, headerName, headerElement, headerType,
addHeader(element, headers, parserContext, headerName, headerElement, headerType,
expression, overwrite);
}
}
}
else {
this.addHeader(element, headers, parserContext, headerName, headerElement, headerType, null,
overwrite);
addHeader(element, headers, parserContext, headerName, headerElement, headerType, null, overwrite);
}
}
}
}
private void addHeader(Element element, ManagedMap<String, Object> headers, ParserContext parserContext,
String headerName, Element headerElement, Class<?> headerType, String expression, String overwrite) {
String headerName, Element headerElement, String headerType, String expression, String overwrite) {
String value = headerElement.getAttribute("value");
String ref = headerElement.getAttribute(REF_ATTRIBUTE);
@@ -233,15 +219,20 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
"The 'method' attribute cannot be used with the 'value' attribute.", element);
}
if (IntegrationMessageHeaderAccessor.ROUTING_SLIP.equals(headerName)) {
List<String> routingSlipPath = new ManagedList<String>();
List<String> routingSlipPath = new ManagedList<>();
routingSlipPath.addAll(Arrays.asList(StringUtils.tokenizeToStringArray(value, ";")));
valueProcessorBuilder =
BeanDefinitionBuilder.genericBeanDefinition(RoutingSlipHeaderValueMessageProcessor.class)
.addConstructorArgValue(routingSlipPath);
}
else {
Object headerValue = (headerType != null) ?
new TypedStringValue(value, headerType) : value;
Object headerValue = value;
if (StringUtils.hasText(headerType)) {
TypedStringValue typedStringValue = new TypedStringValue(value);
typedStringValue.setTargetTypeName(headerType);
headerValue = typedStringValue;
}
valueProcessorBuilder =
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
.addConstructorArgValue(headerValue);
@@ -280,8 +271,9 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
}
}
else {
valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class);
valueProcessorBuilder.addConstructorArgValue(innerComponentDefinition);
valueProcessorBuilder =
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
.addConstructorArgValue(innerComponentDefinition);
}
}
else {
@@ -296,8 +288,9 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
.addConstructorArgValue(method);
}
else {
valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
.addConstructorArgReference(ref);
valueProcessorBuilder =
BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class)
.addConstructorArgReference(ref);
}
}
if (StringUtils.hasText(overwrite)) {
@@ -312,7 +305,8 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
* @param element The element.
* @param parserContext The parser context.
*/
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element,
ParserContext parserContext) {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2018 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.
@@ -36,16 +36,18 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Artem Bilan
*/
public class StandardHeaderEnricherParser extends HeaderEnricherParserSupport {
public StandardHeaderEnricherParser() {
this.addElementToHeaderMapping("reply-channel", MessageHeaders.REPLY_CHANNEL);
this.addElementToHeaderMapping("error-channel", MessageHeaders.ERROR_CHANNEL);
this.addElementToHeaderMapping("correlation-id", IntegrationMessageHeaderAccessor.CORRELATION_ID);
this.addElementToHeaderMapping("expiration-date", IntegrationMessageHeaderAccessor.EXPIRATION_DATE, Long.class);
this.addElementToHeaderMapping("priority", IntegrationMessageHeaderAccessor.PRIORITY, Integer.class);
this.addElementToHeaderMapping("routing-slip", IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class);
addElementToHeaderMapping("reply-channel", MessageHeaders.REPLY_CHANNEL);
addElementToHeaderMapping("error-channel", MessageHeaders.ERROR_CHANNEL);
addElementToHeaderMapping("correlation-id", IntegrationMessageHeaderAccessor.CORRELATION_ID);
addElementToHeaderMapping("expiration-date", IntegrationMessageHeaderAccessor.EXPIRATION_DATE,
Long.class.getName());
addElementToHeaderMapping("priority", IntegrationMessageHeaderAccessor.PRIORITY, Integer.class.getName());
addElementToHeaderMapping("routing-slip", IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class.getName());
}
@Override

View File

@@ -177,13 +177,13 @@ public class ScatterGatherHandler extends AbstractReplyProducingMessageHandler i
}
private void checkClass(Class<?> gathererClass, String className, String type) throws LinkageError {
Class<?> clazz = null;
try {
clazz = ClassUtils.forName(className, getClass().getClassLoader());
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
Assert.isAssignable(clazz, gathererClass, "the '" + type + "' must be an " + className + " instance");
}
catch (Exception e) {
catch (ClassNotFoundException e) {
throw new IllegalStateException("The class for '" + className + "' cannot be loaded", e);
}
Assert.isAssignable(clazz, gathererClass, "the '" + type + "' must be an " + className + " instance");
}
}