Java tutorial
/* * Copyright 2002-2019 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.integration.context; import java.util.Properties; import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.support.DefaultMessageBuilderFactory; import org.springframework.integration.support.MessageBuilderFactory; import org.springframework.integration.support.channel.ChannelResolverUtils; import org.springframework.integration.support.context.NamedComponent; import org.springframework.integration.support.utils.IntegrationUtils; import org.springframework.lang.Nullable; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.core.DestinationResolver; import org.springframework.scheduling.TaskScheduler; import org.springframework.util.AlternativeJdkIdGenerator; import org.springframework.util.Assert; import org.springframework.util.IdGenerator; import org.springframework.util.StringUtils; /** * A base class that provides convenient access to the bean factory as * well as {@link TaskScheduler} and {@link ConversionService} instances. * * <p>This is intended to be used as a base class for internal framework * components whereas code built upon the integration framework should not * require tight coupling with the context but rather rely on standard * dependency injection. * * @author Mark Fisher * @author Oleg Zhurakousky * @author Josh Long * @author Stefan Ferstl * @author Gary Russell * @author Artem Bilan */ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedComponent, ApplicationContextAware, BeanFactoryAware, InitializingBean, ExpressionCapable { protected static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); private static final IdGenerator ID_GENERATOR = new AlternativeJdkIdGenerator(); /** * Logger that is available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); // NOSONAR protected private final ConversionService defaultConversionService = DefaultConversionService.getSharedInstance(); private DestinationResolver<MessageChannel> channelResolver; private String beanName; private String componentName; private BeanFactory beanFactory; private TaskScheduler taskScheduler; private Properties integrationProperties = IntegrationProperties.defaults(); private ConversionService conversionService; private ApplicationContext applicationContext; private MessageBuilderFactory messageBuilderFactory; private Expression expression; private boolean initialized; @Override public final void setBeanName(String beanName) { this.beanName = beanName; } @Override public String getBeanName() { return this.beanName; } /** * Will return the name of this component identified by {@link #componentName} field. * If {@link #componentName} was not set this method will default to the 'beanName' of this component; */ @Override public String getComponentName() { return StringUtils.hasText(this.componentName) ? this.componentName : this.beanName; } /** * Sets the name of this component. * @param componentName The component name. */ public void setComponentName(String componentName) { this.componentName = componentName; } /** * Subclasses may implement this method to provide component type information. */ @Override public String getComponentType() { return null; } public String getBeanDescription() { String description = null; Object source = null; if (this.beanFactory instanceof ConfigurableListableBeanFactory && ((ConfigurableListableBeanFactory) this.beanFactory).containsBeanDefinition(this.beanName)) { BeanDefinition beanDefinition = ((ConfigurableListableBeanFactory) this.beanFactory) .getBeanDefinition(this.beanName); description = beanDefinition.getResourceDescription(); source = beanDefinition.getSource(); } StringBuilder sb = new StringBuilder("bean '").append(this.beanName).append("'"); if (!this.beanName.equals(getComponentName())) { sb.append(" for component '").append(getComponentName()).append("'"); } if (description != null) { sb.append("; defined in: '").append(description).append("'"); } if (source != null) { sb.append("; from source: '").append(source).append("'"); } return sb.toString(); } @Override public void setBeanFactory(BeanFactory beanFactory) { Assert.notNull(beanFactory, "'beanFactory' must not be null"); this.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Assert.notNull(applicationContext, "'applicationContext' must not be null"); this.applicationContext = applicationContext; } /** * Specify the {@link DestinationResolver} strategy to use. * The default is a BeanFactoryChannelResolver. * @param channelResolver The channel resolver. */ public void setChannelResolver(DestinationResolver<MessageChannel> channelResolver) { Assert.notNull(channelResolver, "'channelResolver' must not be null"); this.channelResolver = channelResolver; } @Override public Expression getExpression() { return this.expression; } /** * For expression-based components, set the primary expression. * @param expression the expression. * @since 4.3 */ public final void setPrimaryExpression(Expression expression) { this.expression = expression; } @Override public final void afterPropertiesSet() { this.integrationProperties = IntegrationContextUtils.getIntegrationProperties(this.beanFactory); if (this.messageBuilderFactory == null) { if (this.beanFactory != null) { this.messageBuilderFactory = IntegrationUtils.getMessageBuilderFactory(this.beanFactory); } else { this.messageBuilderFactory = new DefaultMessageBuilderFactory(); } } onInit(); this.initialized = true; } /** * Subclasses may implement this for initialization logic. */ protected void onInit() { } /** * Return the status of this component if it has been initialized already. * @return the flag if this component has been initialized already. */ protected boolean isInitialized() { return this.initialized; } protected BeanFactory getBeanFactory() { return this.beanFactory; } /** * Configure a {@link TaskScheduler} for those components which logic relies * on the scheduled tasks. * If not provided, falls back to the global {@code taskScheduler} bean * in the application context, provided by the Spring Integration infrastructure. * @param taskScheduler the {@link TaskScheduler} to use. * @since 5.1.3 * @see #getTaskScheduler() */ public void setTaskScheduler(TaskScheduler taskScheduler) { Assert.notNull(taskScheduler, "taskScheduler must not be null"); this.taskScheduler = taskScheduler; } protected TaskScheduler getTaskScheduler() { if (this.taskScheduler == null && this.beanFactory != null) { this.taskScheduler = IntegrationContextUtils.getTaskScheduler(this.beanFactory); } return this.taskScheduler; } protected DestinationResolver<MessageChannel> getChannelResolver() { if (this.channelResolver == null) { this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory); } return this.channelResolver; } public ConversionService getConversionService() { if (this.conversionService == null && this.beanFactory != null) { this.conversionService = IntegrationUtils.getConversionService(this.beanFactory); if (this.conversionService == null && this.logger.isDebugEnabled()) { this.logger.debug("Unable to attempt conversion of Message payload types. Component '" + getComponentName() + "' has no explicit ConversionService reference, " + "and there is no 'integrationConversionService' bean within the context."); } } return this.conversionService; } protected void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } /** * Returns the {@link ApplicationContext#getId()} if the * {@link ApplicationContext} is available. * @return The id, or null if there is no application context. */ public String getApplicationContextId() { return this.applicationContext == null ? null : this.applicationContext.getId(); } /** * @return the applicationContext */ protected ApplicationContext getApplicationContext() { return this.applicationContext; } /** * @see IntegrationContextUtils#getIntegrationProperties(BeanFactory) * @return The global integration properties. */ protected Properties getIntegrationProperties() { return this.integrationProperties; } protected MessageBuilderFactory getMessageBuilderFactory() { if (this.messageBuilderFactory == null) { this.messageBuilderFactory = new DefaultMessageBuilderFactory(); } return this.messageBuilderFactory; } public void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) { this.messageBuilderFactory = messageBuilderFactory; } /** * @param key Integration property. * @param tClass the class to convert a value of Integration property. * @param <T> The expected type of the property. * @return the value of the Integration property converted to the provide type. */ protected <T> T getIntegrationProperty(String key, Class<T> tClass) { return this.defaultConversionService.convert(this.integrationProperties.getProperty(key), tClass); } @Override public String toString() { return (this.beanName != null) ? getBeanDescription() : super.toString(); } @SuppressWarnings("unchecked") @Nullable public static <T> T extractTypeIfPossible(@Nullable Object targetObject, Class<T> expectedType) { if (targetObject == null) { return null; } if (expectedType.isAssignableFrom(targetObject.getClass())) { return (T) targetObject; } else { return extractTypeIfPossible(AopProxyUtils.getSingletonTarget(targetObject), expectedType); } } public static UUID generateId() { return ID_GENERATOR.generateId(); } }