Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* Provides annotations for annotation-based configuration.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.annotation;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.integration.aop;

import org.jspecify.annotations.Nullable;

import org.springframework.integration.core.MessageSource;
import org.springframework.integration.util.CompoundTrigger;
import org.springframework.messaging.Message;
Expand Down Expand Up @@ -56,7 +58,7 @@ public CompoundTriggerAdvice(CompoundTrigger compoundTrigger, Trigger overrideTr
* @return the message or null
*/
@Override
public Message<?> afterReceive(Message<?> result, MessageSource<?> source) {
public @Nullable Message<?> afterReceive(@Nullable Message<?> result, MessageSource<?> source) {
if (result == null) {
this.compoundTrigger.setOverride(this.override);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.Nullable;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
Expand Down Expand Up @@ -64,12 +66,15 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact

private final PublisherMetadataSource metadataSource;

@Nullable
private DestinationResolver<MessageChannel> channelResolver;

@SuppressWarnings("NullAway.Init")
private BeanFactory beanFactory;

private MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory();

@Nullable
private String defaultChannelName;

private volatile boolean messageBuilderFactorySet;
Expand All @@ -85,7 +90,7 @@ public MessagePublishingInterceptor(PublisherMetadataSource metadataSource) {
* @param defaultChannelName the default channel name.
* @since 4.0.3
*/
public void setDefaultChannelName(String defaultChannelName) {
public void setDefaultChannelName(@Nullable String defaultChannelName) {
this.defaultChannelName = defaultChannelName;
}

Expand All @@ -100,24 +105,22 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

protected MessageBuilderFactory getMessageBuilderFactory() {
if (!this.messageBuilderFactorySet) {
if (this.beanFactory != null) {
this.messageBuilderFactory = IntegrationUtils.getMessageBuilderFactory(this.beanFactory);
}
this.messageBuilderFactory = IntegrationUtils.getMessageBuilderFactory(this.beanFactory);
this.messageBuilderFactorySet = true;
}
return this.messageBuilderFactory;
}

@Override
public final Object invoke(MethodInvocation invocation) throws Throwable {
public final @Nullable Object invoke(MethodInvocation invocation) throws Throwable {
initMessagingTemplateIfAny();
StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
Class<?> targetClass = AopUtils.getTargetClass(invocation.getThis());
Class<?> targetClass = AopUtils.getTargetClass(Objects.requireNonNull(invocation.getThis()));
Method method = AopUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
String[] argumentNames = resolveArgumentNames(method);
@Nullable String[] argumentNames = resolveArgumentNames(method);
context.setVariable(PublisherMetadataSource.METHOD_NAME_VARIABLE_NAME, method.getName());
if (invocation.getArguments().length > 0 && argumentNames != null) {
Map<Object, Object> argumentMap = new HashMap<>();
if (invocation.getArguments().length > 0 && argumentNames != null) {
Map<@Nullable Object, @Nullable Object> argumentMap = new HashMap<>();
for (int i = 0; i < argumentNames.length; i++) {
if (invocation.getArguments().length <= i) {
break;
Expand Down Expand Up @@ -152,7 +155,7 @@ private void initMessagingTemplateIfAny() {
}
}

private String[] resolveArgumentNames(Method method) {
private @Nullable String @Nullable [] resolveArgumentNames(Method method) {
return this.parameterNameDiscoverer.getParameterNames(method);
}

Expand Down Expand Up @@ -187,7 +190,7 @@ private void publishMessage(Method method, StandardEvaluationContext context) {
}
}

private Map<String, Object> evaluateHeaders(Method method, StandardEvaluationContext context) {
private @Nullable Map<String, Object> evaluateHeaders(Method method, StandardEvaluationContext context) {
Map<String, Expression> headerExpressionMap = this.metadataSource.getExpressionsForHeaders(method);
if (headerExpressionMap != null) {
return ExpressionEvalMap.from(headerExpressionMap)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void setChannelAttributeName(String channelAttributeName) {
}

@Override
public String getChannelName(Method method) {
public @Nullable String getChannelName(Method method) {
return this.channels.computeIfAbsent(method,
method1 -> {
String channelName = getAnnotationValue(method, this.channelAttributeName);
Expand All @@ -92,7 +92,7 @@ public String getChannelName(Method method) {
}

@Override
public Expression getExpressionForPayload(Method method) {
public @Nullable Expression getExpressionForPayload(Method method) {
return this.payloadExpressions.computeIfAbsent(method,
method1 -> {
Expression payloadExpression = null;
Expand Down Expand Up @@ -141,7 +141,7 @@ public Map<String, Expression> getExpressionsForHeaders(Method method) {
return this.headersExpressions.computeIfAbsent(method,
method1 -> {
Map<String, Expression> headerExpressions = new HashMap<>();
String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method);
@Nullable String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method);
Annotation[][] annotationArray = method.getParameterAnnotations();
for (int i = 0; i < annotationArray.length; i++) {
Annotation[] parameterAnnotations = annotationArray[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.Map;
import java.util.stream.Collectors;

import org.jspecify.annotations.Nullable;

import org.springframework.expression.Expression;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
Expand Down Expand Up @@ -66,7 +68,7 @@ public void setChannelMap(Map<String, String> channelMap) {
}

@Override
public Expression getExpressionForPayload(Method method) {
public @Nullable Expression getExpressionForPayload(Method method) {
for (Map.Entry<String, Expression> entry : this.payloadExpressionMap.entrySet()) {
if (PatternMatchUtils.simpleMatch(entry.getKey(), method.getName())) {
return entry.getValue();
Expand All @@ -76,7 +78,7 @@ public Expression getExpressionForPayload(Method method) {
}

@Override
public Map<String, Expression> getExpressionsForHeaders(Method method) {
public @Nullable Map<String, Expression> getExpressionsForHeaders(Method method) {
return this.headerExpressionMap
.entrySet()
.stream()
Expand All @@ -87,7 +89,7 @@ public Map<String, Expression> getExpressionsForHeaders(Method method) {
}

@Override
public String getChannelName(Method method) {
public @Nullable String getChannelName(Method method) {
for (Map.Entry<String, String> entry : this.channelMap.entrySet()) {
if (PatternMatchUtils.simpleMatch(entry.getKey(), method.getName())) {
return entry.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;

import org.aopalliance.aop.Advice;
import org.jspecify.annotations.Nullable;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
Expand Down Expand Up @@ -73,7 +75,7 @@ public PublisherAnnotationAdvisor(Class<? extends Annotation>... publisherAnnota
* @param defaultChannelName the default channel name.
* @since 4.0.3
*/
public void setDefaultChannelName(String defaultChannelName) {
public void setDefaultChannelName(@Nullable String defaultChannelName) {
this.interceptor.setDefaultChannelName(defaultChannelName);
}

Expand Down Expand Up @@ -104,7 +106,7 @@ private static Pointcut buildPointcut(Class<? extends Annotation>[] publisherAnn
result.union(cpc).union(mpc);
}
}
return result;
return Objects.requireNonNull(result);
}

private static final class MetaAnnotationMatchingPointcut implements Pointcut {
Expand Down Expand Up @@ -133,7 +135,7 @@ private static final class MetaAnnotationMatchingPointcut implements Pointcut {
* (can be <code>null</code>)
*/
MetaAnnotationMatchingPointcut(
Class<? extends Annotation> classAnnotationType, Class<? extends Annotation> methodAnnotationType) {
@Nullable Class<? extends Annotation> classAnnotationType, @Nullable Class<? extends Annotation> methodAnnotationType) {

Assert.isTrue((classAnnotationType != null || methodAnnotationType != null),
"Either Class annotation type or Method annotation type needs to be specified (or both)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@

package org.springframework.integration.aop;

import org.jspecify.annotations.Nullable;

import org.springframework.aop.framework.autoproxy.AbstractBeanFactoryAwareAdvisingPostProcessor;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.util.Assert;

/**
* Post-processes beans that contain the
* method-level @{@link org.springframework.integration.annotation.Publisher} annotation.
* <p>
* Only one bean instance of this processor can be declared in the application context, manual
* or automatic by thr framework via annotation or XML processing.
* or automatic by the framework via annotation or XML processing.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
Expand All @@ -42,10 +45,18 @@
public class PublisherAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor
implements BeanNameAware, SmartInitializingSingleton {

private String defaultChannelName;
/**
* This value is optional and may be {@code null}, indicating that no default channel
* is configured and message routing must be handled explicitly elsewhere. For example:
* {@link MessagePublishingInterceptor} can accept a null value for this attribute.
*
*/
private @Nullable String defaultChannelName;

@SuppressWarnings("NullAway.Init")
private String beanName;

@SuppressWarnings("NullAway.Init")
private BeanFactory beanFactory;

/**
Expand All @@ -60,6 +71,7 @@ public void setDefaultChannelName(String defaultChannelName) {

@Override
public void setBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
this.beanName = name;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.lang.reflect.Method;
import java.util.Map;

import org.jspecify.annotations.Nullable;

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
Expand Down Expand Up @@ -55,7 +57,7 @@ interface PublisherMetadataSource {
* @param method The Method.
* @return The channel name.
*/
String getChannelName(Method method);
@Nullable String getChannelName(Method method);

/**
* Returns the SpEL expression to be evaluated for creating the Message
Expand All @@ -64,7 +66,7 @@ interface PublisherMetadataSource {
* @return rhe payload expression.
* @since 5.0.4
*/
Expression getExpressionForPayload(Method method);
@Nullable Expression getExpressionForPayload(Method method);

/**
* Returns the map of expression strings to be evaluated for any headers
Expand All @@ -73,6 +75,6 @@ interface PublisherMetadataSource {
* @param method The Method.
* @return The header expressions.
*/
Map<String, Expression> getExpressionsForHeaders(Method method);
@Nullable Map<String, Expression> getExpressionsForHeaders(Method method);

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import java.time.Duration;

import org.jspecify.annotations.Nullable;

import org.springframework.integration.util.DynamicPeriodicTrigger;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -67,7 +69,7 @@ public void setActivePollPeriod(long activePollPeriod) {
}

@Override
public Message<?> afterReceive(Message<?> result, Object source) {
public @Nullable Message<?> afterReceive(@Nullable Message<?> result, Object source) {
if (result == null) {
this.trigger.setDuration(this.idlePollPeriod);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.util.Map;
import java.util.stream.Collectors;

import org.jspecify.annotations.Nullable;

import org.springframework.expression.Expression;

/**
Expand All @@ -34,18 +36,18 @@
*/
public class SimplePublisherMetadataSource implements PublisherMetadataSource {

private volatile String channelName;
private @Nullable String channelName;

private volatile Expression payloadExpression;
private @Nullable Expression payloadExpression;

private volatile Map<String, Expression> headerExpressions;
private @Nullable Map<String, Expression> headerExpressions;

public void setChannelName(String channelName) {
this.channelName = channelName;
}

@Override
public String getChannelName(Method method) {
public @Nullable String getChannelName(Method method) {
return this.channelName;
}

Expand All @@ -54,7 +56,7 @@ public void setPayloadExpression(String payloadExpression) {
}

@Override
public Expression getExpressionForPayload(Method method) {
public @Nullable Expression getExpressionForPayload(Method method) {
return this.payloadExpression;
}

Expand All @@ -67,7 +69,7 @@ public void setHeaderExpressions(Map<String, String> headerExpressions) {
}

@Override
public Map<String, Expression> getExpressionsForHeaders(Method method) {
public @Nullable Map<String, Expression> getExpressionsForHeaders(Method method) {
return this.headerExpressions;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* Provides classes to support message publication using AOP.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.aop;
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class ConfigurableCompositeMessageConverter extends CompositeMessageConve

private final boolean registerDefaults;

@SuppressWarnings("NullAway.Init")
private BeanFactory beanFactory;

/**
Expand Down