All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.jms.config.JmsListenerEndpointRegistrar Maven / Gradle / Ivy

There is a newer version: 6.1.13
Show newest version
/*
 * Copyright 2002-2023 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.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.jms.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
import org.springframework.util.Assert;

/**
 * Helper bean for registering {@link JmsListenerEndpoint} with a {@link JmsListenerEndpointRegistry}.
 *
 * @author Stephane Nicoll
 * @author Juergen Hoeller
 * @since 4.1
 * @see org.springframework.jms.annotation.JmsListenerConfigurer
 */
public class JmsListenerEndpointRegistrar implements BeanFactoryAware, InitializingBean {

	@Nullable
	private JmsListenerEndpointRegistry endpointRegistry;

	@Nullable
	private MessageHandlerMethodFactory messageHandlerMethodFactory;

	@Nullable
	private JmsListenerContainerFactory containerFactory;

	@Nullable
	private String containerFactoryBeanName;

	@Nullable
	private BeanFactory beanFactory;

	private final List endpointDescriptors = new ArrayList<>();

	private boolean startImmediately;

	private Object mutex = this.endpointDescriptors;


	/**
	 * Set the {@link JmsListenerEndpointRegistry} instance to use.
	 */
	public void setEndpointRegistry(@Nullable JmsListenerEndpointRegistry endpointRegistry) {
		this.endpointRegistry = endpointRegistry;
	}

	/**
	 * Return the {@link JmsListenerEndpointRegistry} instance for this
	 * registrar, may be {@code null}.
	 */
	@Nullable
	public JmsListenerEndpointRegistry getEndpointRegistry() {
		return this.endpointRegistry;
	}

	/**
	 * Set the {@link MessageHandlerMethodFactory} to use to configure the message
	 * listener responsible to serve an endpoint detected by this processor.
	 * 

By default, {@link DefaultMessageHandlerMethodFactory} is used and it * can be configured further to support additional method arguments * or to customize conversion and validation support. See * {@link DefaultMessageHandlerMethodFactory} javadoc for more details. */ public void setMessageHandlerMethodFactory(@Nullable MessageHandlerMethodFactory messageHandlerMethodFactory) { this.messageHandlerMethodFactory = messageHandlerMethodFactory; } /** * Return the custom {@link MessageHandlerMethodFactory} to use, if any. */ @Nullable public MessageHandlerMethodFactory getMessageHandlerMethodFactory() { return this.messageHandlerMethodFactory; } /** * Set the {@link JmsListenerContainerFactory} to use in case a {@link JmsListenerEndpoint} * is registered with a {@code null} container factory. *

Alternatively, the bean name of the {@link JmsListenerContainerFactory} to use * can be specified for a lazy lookup, see {@link #setContainerFactoryBeanName}. */ public void setContainerFactory(JmsListenerContainerFactory containerFactory) { this.containerFactory = containerFactory; } /** * Set the bean name of the {@link JmsListenerContainerFactory} to use in case * a {@link JmsListenerEndpoint} is registered with a {@code null} container factory. * Alternatively, the container factory instance can be registered directly: * see {@link #setContainerFactory(JmsListenerContainerFactory)}. * @see #setBeanFactory */ public void setContainerFactoryBeanName(String containerFactoryBeanName) { this.containerFactoryBeanName = containerFactoryBeanName; } /** * A {@link BeanFactory} only needs to be available in conjunction with * {@link #setContainerFactoryBeanName}. */ @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; if (beanFactory instanceof ConfigurableBeanFactory cbf) { this.mutex = cbf.getSingletonMutex(); } } @Override public void afterPropertiesSet() { registerAllEndpoints(); } protected void registerAllEndpoints() { Assert.state(this.endpointRegistry != null, "No JmsListenerEndpointRegistry set"); synchronized (this.mutex) { for (JmsListenerEndpointDescriptor descriptor : this.endpointDescriptors) { this.endpointRegistry.registerListenerContainer( descriptor.endpoint, resolveContainerFactory(descriptor)); } this.startImmediately = true; // trigger immediate startup } } private JmsListenerContainerFactory resolveContainerFactory(JmsListenerEndpointDescriptor descriptor) { if (descriptor.containerFactory != null) { return descriptor.containerFactory; } else if (this.containerFactory != null) { return this.containerFactory; } else if (this.containerFactoryBeanName != null) { Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name"); // Consider changing this if live change of the factory is required... this.containerFactory = this.beanFactory.getBean( this.containerFactoryBeanName, JmsListenerContainerFactory.class); return this.containerFactory; } else { throw new IllegalStateException("Could not resolve the " + JmsListenerContainerFactory.class.getSimpleName() + " to use for [" + descriptor.endpoint + "] no factory was given and no default is set."); } } /** * Register a new {@link JmsListenerEndpoint} alongside the * {@link JmsListenerContainerFactory} to use to create the underlying container. *

The {@code factory} may be {@code null} if the default factory should be * used for the supplied endpoint. */ public void registerEndpoint(JmsListenerEndpoint endpoint, @Nullable JmsListenerContainerFactory factory) { Assert.notNull(endpoint, "Endpoint must not be null"); Assert.hasText(endpoint.getId(), "Endpoint id must be set"); // Factory may be null, we defer the resolution right before actually creating the container JmsListenerEndpointDescriptor descriptor = new JmsListenerEndpointDescriptor(endpoint, factory); synchronized (this.mutex) { if (this.startImmediately) { // register and start immediately Assert.state(this.endpointRegistry != null, "No JmsListenerEndpointRegistry set"); this.endpointRegistry.registerListenerContainer(descriptor.endpoint, resolveContainerFactory(descriptor), true); } else { this.endpointDescriptors.add(descriptor); } } } /** * Register a new {@link JmsListenerEndpoint} using the default * {@link JmsListenerContainerFactory} to create the underlying container. * @see #setContainerFactory(JmsListenerContainerFactory) * @see #registerEndpoint(JmsListenerEndpoint, JmsListenerContainerFactory) */ public void registerEndpoint(JmsListenerEndpoint endpoint) { registerEndpoint(endpoint, null); } private static class JmsListenerEndpointDescriptor { public final JmsListenerEndpoint endpoint; @Nullable public final JmsListenerContainerFactory containerFactory; public JmsListenerEndpointDescriptor(JmsListenerEndpoint endpoint, @Nullable JmsListenerContainerFactory containerFactory) { this.endpoint = endpoint; this.containerFactory = containerFactory; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy