diff --git a/spring-amqp/src/main/java/org/springframework/amqp/core/AbstractDeclarable.java b/spring-amqp/src/main/java/org/springframework/amqp/core/AbstractDeclarable.java index 3c1dfe2911..f56aa90192 100644 --- a/spring-amqp/src/main/java/org/springframework/amqp/core/AbstractDeclarable.java +++ b/spring-amqp/src/main/java/org/springframework/amqp/core/AbstractDeclarable.java @@ -35,6 +35,8 @@ * @author Gary Russell * @author Christian Tzolov * @author Ngoc Nhan + * @author Artem Bilan + * * @since 1.2 * */ @@ -104,16 +106,20 @@ public void setIgnoreDeclarationExceptions(boolean ignoreDeclarationExceptions) @Override @SuppressWarnings("NullAway") // Dataflow analysis limitation public void setAdminsThatShouldDeclare(@Nullable Object @Nullable ... adminArgs) { - Collection admins = new ArrayList<>(); if (adminArgs != null) { if (adminArgs.length > 1) { Assert.noNullElements(adminArgs, "'admins' cannot contain null elements"); } if (adminArgs.length > 0 && !(adminArgs.length == 1 && adminArgs[0] == null)) { - admins = Arrays.asList(adminArgs); + this.declaringAdmins = Arrays.asList(adminArgs); + } + else { + this.declaringAdmins = Collections.emptyList(); } } - this.declaringAdmins = admins; + else { + this.declaringAdmins = Collections.emptyList(); + } } @Override diff --git a/spring-amqp/src/main/java/org/springframework/amqp/core/Declarables.java b/spring-amqp/src/main/java/org/springframework/amqp/core/Declarables.java index 3a14f3e8f2..92ff274271 100644 --- a/spring-amqp/src/main/java/org/springframework/amqp/core/Declarables.java +++ b/spring-amqp/src/main/java/org/springframework/amqp/core/Declarables.java @@ -31,20 +31,27 @@ * * @author Gary Russell * @author Björn Michael + * @author Artem Bilan + * * @since 2.1 */ public class Declarables { - private final Collection declarables = new ArrayList<>(); + private final Collection declarables; public Declarables(Declarable... declarables) { if (!ObjectUtils.isEmpty(declarables)) { + this.declarables = new ArrayList<>(declarables.length); this.declarables.addAll(Arrays.asList(declarables)); } + else { + this.declarables = new ArrayList<>(); + } } public Declarables(Collection declarables) { Assert.notNull(declarables, "declarables cannot be null"); + this.declarables = new ArrayList<>(declarables.size()); this.declarables.addAll(declarables); } diff --git a/spring-amqp/src/main/java/org/springframework/amqp/support/postprocessor/MessagePostProcessorUtils.java b/spring-amqp/src/main/java/org/springframework/amqp/support/postprocessor/MessagePostProcessorUtils.java index 9cf981a5a2..c38fddcfe7 100644 --- a/spring-amqp/src/main/java/org/springframework/amqp/support/postprocessor/MessagePostProcessorUtils.java +++ b/spring-amqp/src/main/java/org/springframework/amqp/support/postprocessor/MessagePostProcessorUtils.java @@ -38,9 +38,10 @@ public final class MessagePostProcessorUtils { public static Collection sort(Collection processors) { - List priorityOrdered = new ArrayList<>(); - List ordered = new ArrayList<>(); - List unOrdered = new ArrayList<>(); + int potentialSize = processors.size(); + List priorityOrdered = new ArrayList<>(potentialSize); + List ordered = new ArrayList<>(potentialSize); + List unOrdered = new ArrayList<>(potentialSize); for (MessagePostProcessor processor : processors) { if (processor instanceof PriorityOrdered) { priorityOrdered.add(processor); diff --git a/spring-rabbit-stream/src/main/java/org/springframework/rabbit/stream/config/SuperStream.java b/spring-rabbit-stream/src/main/java/org/springframework/rabbit/stream/config/SuperStream.java index 424782cbab..7f71e306ad 100644 --- a/spring-rabbit-stream/src/main/java/org/springframework/rabbit/stream/config/SuperStream.java +++ b/spring-rabbit-stream/src/main/java/org/springframework/rabbit/stream/config/SuperStream.java @@ -102,9 +102,9 @@ private static Collection declarables(String name, int partitions, BiFunction> routingKeyStrategy, Map arguments) { - List declarables = new ArrayList<>(); List rks = routingKeyStrategy.apply(name, partitions); Assert.state(rks.size() == partitions, () -> "Expected " + partitions + " routing keys, not " + rks.size()); + List declarables = new ArrayList<>(partitions + 1); declarables.add( new DirectExchange(name, true, false, Map.of("x-super-stream", true))); diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java index 49dadc1104..bb0914040e 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java @@ -361,7 +361,7 @@ else if (source instanceof Method method) { private void processMultiMethodListeners(RabbitListener[] classLevelListeners, Method[] multiMethods, Object bean, String beanName) { - List checkedMethods = new ArrayList<>(); + List checkedMethods = new ArrayList<>(multiMethods.length); Method defaultMethod = null; for (Method method : multiMethods) { Method checked = checkProxy(method, bean); @@ -646,8 +646,8 @@ private List resolveQueues(RabbitListener rabbitListener, Collection queueNames = new ArrayList<>(); - List queueBeans = new ArrayList<>(); + List queueNames = new ArrayList<>(queues.length); + List queueBeans = new ArrayList<>(queues.length); for (String queue : queues) { resolveQueues(queue, queueNames, queueBeans); } @@ -818,7 +818,7 @@ private void registerBindings(QueueBinding binding, String queueName, String exc } else { final int length = binding.key().length; - routingKeys = new ArrayList<>(); + routingKeys = new ArrayList<>(length); for (int i = 0; i < length; ++i) { resolveAsStringOrQueue(resolveExpression(binding.key()[i]), routingKeys, null, "@QueueBinding.key"); } diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/batch/SimpleBatchingStrategy.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/batch/SimpleBatchingStrategy.java index b802e69665..2dd0ae04e8 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/batch/SimpleBatchingStrategy.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/batch/SimpleBatchingStrategy.java @@ -37,11 +37,13 @@ /** * A simple batching strategy that supports only one exchange/routingKey; includes a batch * size, a batched message size limit and a timeout. The message properties from the first - * message in the batch is used in the batch message. Each message is preceded by a 4 byte + * message in the batch are used in the batch message. Each message is preceded by a 4-byte * length field. * * @author Gary Russell * @author Ngoc Nhan + * @author Artem Bilan + * * @since 1.4.1 * */ @@ -53,7 +55,7 @@ public class SimpleBatchingStrategy implements BatchingStrategy { private final long timeout; - private final List messages = new ArrayList<>(); + private final List messages; private @Nullable String exchange; @@ -68,6 +70,7 @@ public class SimpleBatchingStrategy implements BatchingStrategy { * @param timeout the batch timeout. */ public SimpleBatchingStrategy(int batchSize, int bufferLimit, long timeout) { + this.messages = new ArrayList<>(batchSize); this.batchSize = batchSize; this.bufferLimit = bufferLimit; this.timeout = timeout; diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/CompositeContainerCustomizer.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/CompositeContainerCustomizer.java index 83c924f056..2f4bd64da9 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/CompositeContainerCustomizer.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/CompositeContainerCustomizer.java @@ -30,12 +30,13 @@ * * @author Rene Felgentraeger * @author Gary Russell + * @author Artem Bilan * * @since 2.4.8 */ public class CompositeContainerCustomizer implements ContainerCustomizer { - private final List> customizers = new ArrayList<>(); + private final List> customizers; /** * Create an instance with the provided delegate customizers. @@ -43,7 +44,7 @@ public class CompositeContainerCustomizer im */ public CompositeContainerCustomizer(List> customizers) { Assert.notNull(customizers, "At least one customizer must be present"); - this.customizers.addAll(customizers); + this.customizers = new ArrayList<>(customizers); } @Override diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/PublisherCallbackChannelImpl.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/PublisherCallbackChannelImpl.java index a2fbcf9b9d..a5be9939be 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/PublisherCallbackChannelImpl.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/PublisherCallbackChannelImpl.java @@ -917,7 +917,7 @@ public Collection expire(Listener listener, long cutoffTime) { return Collections.emptyList(); } - List expired = new ArrayList<>(); + List expired = new ArrayList<>(pendingConfirmsForListener.size()); Iterator> iterator = pendingConfirmsForListener.entrySet().iterator(); while (iterator.hasNext()) { PendingConfirm pendingConfirm = iterator.next().getValue(); @@ -926,7 +926,7 @@ public Collection expire(Listener listener, long cutoffTime) { iterator.remove(); CorrelationData correlationData = pendingConfirm.getCorrelationData(); if (correlationData != null && StringUtils.hasText(correlationData.getId())) { - this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null + this.pendingReturns.remove(correlationData.getId()); } } else { diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java index 5276593fc3..8d9b3d16b3 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java @@ -679,7 +679,7 @@ public void setBeforePublishPostProcessors(MessagePostProcessor... beforePublish public void addBeforePublishPostProcessors(MessagePostProcessor... beforePublishPostProcessors) { Assert.notNull(beforePublishPostProcessors, "'beforePublishPostProcessors' cannot be null"); if (this.beforePublishPostProcessors == null) { - this.beforePublishPostProcessors = new ArrayList<>(); + this.beforePublishPostProcessors = new ArrayList<>(beforePublishPostProcessors.length); } this.beforePublishPostProcessors.addAll(Arrays.asList(beforePublishPostProcessors)); this.beforePublishPostProcessors = MessagePostProcessorUtils.sort(this.beforePublishPostProcessors); @@ -740,7 +740,7 @@ public void setAfterReceivePostProcessors(MessagePostProcessor... afterReceivePo public void addAfterReceivePostProcessors(MessagePostProcessor... afterReceivePostProcessors) { Assert.notNull(afterReceivePostProcessors, "'afterReceivePostProcessors' cannot be null"); if (this.afterReceivePostProcessors == null) { - this.afterReceivePostProcessors = new ArrayList<>(); + this.afterReceivePostProcessors = new ArrayList<>(afterReceivePostProcessors.length); } this.afterReceivePostProcessors.addAll(Arrays.asList(afterReceivePostProcessors)); this.afterReceivePostProcessors = MessagePostProcessorUtils.sort(this.afterReceivePostProcessors); diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/MultiMethodRabbitListenerEndpoint.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/MultiMethodRabbitListenerEndpoint.java index 8c88227cf1..2c0673e17d 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/MultiMethodRabbitListenerEndpoint.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/MultiMethodRabbitListenerEndpoint.java @@ -71,7 +71,7 @@ public void setValidator(Validator validator) { @Override protected HandlerAdapter configureListenerAdapter(MessagingMessageListenerAdapter messageListener) { - List invocableHandlerMethods = new ArrayList<>(); + List invocableHandlerMethods = new ArrayList<>(this.methods.size()); InvocableHandlerMethod defaultHandler = null; MessageHandlerMethodFactory messageHandlerMethodFactory = getMessageHandlerMethodFactory(); Assert.state(messageHandlerMethodFactory != null, diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/BatchMessagingMessageListenerAdapter.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/BatchMessagingMessageListenerAdapter.java index f9777ac137..78a3b7af64 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/BatchMessagingMessageListenerAdapter.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/BatchMessagingMessageListenerAdapter.java @@ -66,7 +66,7 @@ public void onMessageBatch(List messages, converted = new GenericMessage<>(messages); } else { - List> messagingMessages = new ArrayList<>(); + List> messagingMessages = new ArrayList<>(messages.size()); for (org.springframework.amqp.core.Message message : messages) { try { Message messagingMessage = toMessagingMessage(message); @@ -88,7 +88,7 @@ public void onMessageBatch(List messages, converted = new GenericMessage<>(messagingMessages); } else { - List payloads = new ArrayList<>(); + List payloads = new ArrayList<>(messagingMessages.size()); for (Message message : messagingMessages) { payloads.add(message.getPayload()); } diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/MessageListenerAdapter.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/MessageListenerAdapter.java index a22eb544c1..7a04743fb5 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/MessageListenerAdapter.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/MessageListenerAdapter.java @@ -20,6 +20,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.rabbitmq.client.Channel; @@ -116,7 +117,7 @@ * } * * - * For further examples and discussion please do refer to the Spring reference documentation which describes this class + * For further examples and discussion, please do refer to the Spring reference documentation which describes this class * (and its attendant XML configuration) in detail. * * @author Juergen Hoeller @@ -189,7 +190,7 @@ public MessageListenerAdapter(Object delegate, String defaultListenerMethod) { } /** - * Set a target object to delegate message listening to. Specified listener methods have to be present on this + * Set a target object to delegate a message listening to. Specified listener methods have to be present on this * target object. *

If no explicit delegate object has been specified, listener methods are expected to present on this adapter * instance, that is, on a custom subclass of this adapter, defining listener methods. @@ -205,7 +206,7 @@ private void doSetDelegate(Object delegate) { } /** - * @return The target object to delegate message listening to. + * @return The target object to delegate a message listening to. */ protected Object getDelegate() { return this.delegate; @@ -229,8 +230,8 @@ protected String getDefaultListenerMethod() { } /** - * Set the mapping of queue name or consumer tag to method name. The first lookup - * is by queue name, if that returns null, we lookup by consumer tag, if that + * Set the mapping of the queue name or consumer tag to the method name. The first lookup + * is by queue name, if that returns null, we look up by consumer tag, if that * returns null, the {@link #setDefaultListenerMethod(String) defaultListenerMethod} * is used. * @param queueOrTagToMethodName the map. @@ -242,7 +243,7 @@ public void setQueueOrTagToMethodName(Map queueOrTagToMethodName /** * Add the mapping of a queue name or consumer tag to a method name. The first lookup - * is by queue name, if that returns null, we lookup by consumer tag, if that + * is by queue name, if that returns null, we look up by consumer tag, if that * returns null, the {@link #setDefaultListenerMethod(String) defaultListenerMethod} * is used. * @param queueOrTag The queue name or consumer tag. @@ -266,14 +267,14 @@ public String removeQueueOrTagToMethodName(String queueOrTag) { /** * Spring {@link ChannelAwareMessageListener} entry point. *

- * Delegates the message to the target listener method, with appropriate conversion of the message argument. If the - * target method returns a non-null object, wrap in a Rabbit message and send it back. + * Delegates the message to the target listener method, with the appropriate conversion of the message argument. + * If the target method returns a non-null object, wrap in a Rabbit message and send it back. * @param message the incoming Rabbit message * @param channel the Rabbit channel to operate on * @throws Exception if thrown by Rabbit API methods */ @Override - public void onMessage(Message message, @Nullable Channel channel) throws Exception { // NOSONAR + public void onMessage(Message message, @Nullable Channel channel) throws Exception { // Check whether the delegate is a MessageListener impl itself. // In that case, the adapter will simply act as a pass-through. Object delegateListener = getDelegate(); @@ -335,12 +336,12 @@ protected String getListenerMethodName(Message originalMessage, Object extracted * Build an array of arguments to be passed into the target listener method. Allows for multiple method arguments to * be built from a single message object. *

- * The default implementation builds an array with the given message object as sole element. This means that the + * The default implementation builds an array with the given message object as a sole element. This means that the * extracted message will always be passed into a single method argument, even if it is an array, with the * target method having a corresponding single argument of the array's type declared. *

- * This can be overridden to treat special message content such as arrays differently, for example passing in each - * element of the message array as distinct method argument. + * This can be overridden to treat special message content such as arrays differently, for example, passing in each + * element of the message array as a distinct method argument. * @param extractedMessage the content of the message * @param channel the Rabbit channel to operate on * @param message the incoming Rabbit message @@ -376,16 +377,17 @@ protected Object[] buildListenerArguments(Object extractedMessage, @Nullable Cha catch (InvocationTargetException ex) { Throwable targetEx = ex.getTargetException(); if (targetEx instanceof IOException iox) { - throw new AmqpIOException(iox); // NOSONAR lost stack trace + throw new AmqpIOException(iox); } else { - throw new ListenerExecutionFailedException("Listener method '" // NOSONAR lost stack trace + throw new ListenerExecutionFailedException("Listener method '" + methodName + "' threw exception", targetEx, originalMessage); } } catch (Exception ex) { - ArrayList arrayClass = new ArrayList<>(); + List arrayClass = null; if (arguments != null) { + arrayClass = new ArrayList<>(arguments.length); for (Object argument : arguments) { arrayClass.add(argument != null ? argument.getClass().toString() : " null"); } diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/ListenerExecutionFailedException.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/ListenerExecutionFailedException.java index 854522ab5d..850082c6c5 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/ListenerExecutionFailedException.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/ListenerExecutionFailedException.java @@ -16,7 +16,6 @@ package org.springframework.amqp.rabbit.support; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -27,7 +26,6 @@ import org.springframework.amqp.AmqpException; import org.springframework.amqp.core.Message; - /** * Exception to be thrown when the execution of a listener method failed. * @@ -40,7 +38,7 @@ @SuppressWarnings("serial") public class ListenerExecutionFailedException extends AmqpException { - private final List failedMessages = new ArrayList<>(); + private final List failedMessages; /** * Constructor for ListenerExecutionFailedException. @@ -50,7 +48,7 @@ public class ListenerExecutionFailedException extends AmqpException { */ public ListenerExecutionFailedException(String msg, Throwable cause, Message... failedMessage) { super(msg, cause); - this.failedMessages.addAll(Arrays.asList(failedMessage)); + this.failedMessages = Arrays.asList(failedMessage); } public @Nullable Message getFailedMessage() { diff --git a/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpListenerContainer.java b/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpListenerContainer.java index 12a9b267d4..0c5ecf0855 100644 --- a/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpListenerContainer.java +++ b/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpListenerContainer.java @@ -561,7 +561,9 @@ public void handle(Consumer.Context context, com.rabbitmq.client.amqp.Message me if (RabbitAmqpListenerContainer.this.batchSize > 1) { ConsumerBatch currentBatch = this.consumerBatch; if (currentBatch == null || currentBatch.batchReleaseFuture == null) { - currentBatch = new ConsumerBatch(context.batch(RabbitAmqpListenerContainer.this.batchSize)); + currentBatch = + new ConsumerBatch(RabbitAmqpListenerContainer.this.batchSize, + context.batch(RabbitAmqpListenerContainer.this.batchSize)); this.consumerBatch = currentBatch; } currentBatch.add(context, message); @@ -577,14 +579,15 @@ public void handle(Consumer.Context context, com.rabbitmq.client.amqp.Message me private class ConsumerBatch { - private final List batch = new ArrayList<>(); + private final List batch; private final Consumer.BatchContext batchContext; private volatile @Nullable ScheduledFuture batchReleaseFuture; - ConsumerBatch(Consumer.BatchContext batchContext) { + ConsumerBatch(int batchSize, Consumer.BatchContext batchContext) { this.batchContext = batchContext; + this.batch = new ArrayList<>(batchSize); } void add(Consumer.Context context, com.rabbitmq.client.amqp.Message message) { diff --git a/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpMessageListenerAdapter.java b/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpMessageListenerAdapter.java index ea0860b267..50c80daefa 100644 --- a/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpMessageListenerAdapter.java +++ b/spring-rabbitmq-client/src/main/java/org/springframework/amqp/rabbitmq/client/listener/RabbitAmqpMessageListenerAdapter.java @@ -191,7 +191,7 @@ public void onMessageBatch(List messages) { converted = new GenericMessage<>(messagingMessages); } else { - List payloads = new ArrayList<>(); + List payloads = new ArrayList<>(messages.size()); for (org.springframework.messaging.Message message : messagingMessages) { payloads.add(message.getPayload()); }