Some Fixes and Improvements

* Remove `durable-subscription-name` from the `JmsMessageDrivenEndpointParser`, since we don't have such an attribute any more
* Fix `configuration.adoc` for various typos
* Remove `spring.integration.messagingAnnotations.require.componentAnnotation` and `spring.integration.messagingGateway.convertReceiveMessage` properties and their usage,
since they are not actual any more starting with SI-5.0
* Fix tests appropriately

Address PR comments and more polishing

Polishing
This commit is contained in:
Artem Bilan
2016-08-31 11:53:52 -04:00
committed by Gary Russell
parent 370be4853d
commit 868004e9e4
12 changed files with 128 additions and 238 deletions

View File

@@ -356,11 +356,8 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
*/
private void registerMessagingAnnotationPostProcessors(AnnotationMetadata meta, BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)) {
String requireComponentAnnotationExpression =
IntegrationProperties.getExpressionFor(IntegrationProperties.REQUIRE_COMPONENT_ANNOTATION);
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
.addPropertyValue("requireComponentAnnotation", requireComponentAnnotationExpression)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME,

View File

@@ -55,7 +55,6 @@ import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.support.SmartLifecycleRoleController;
import org.springframework.integration.util.MessagingAnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
@@ -84,7 +83,6 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
private ConfigurableListableBeanFactory beanFactory;
private boolean requireComponentAnnotation;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
@@ -93,17 +91,6 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
/**
*
* @param requireComponentAnnotation the {@code boolean} flag to indicate requirements for the
* {@link Component} annotation presentation for the messaging annotations.
* @since 4.3
* @see org.springframework.integration.context.IntegrationProperties#REQUIRE_COMPONENT_ANNOTATION
*/
public void setRequireComponentAnnotation(boolean requireComponentAnnotation) {
this.requireComponentAnnotation = requireComponentAnnotation;
}
protected ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
@@ -147,75 +134,65 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
Assert.notNull(this.beanFactory, "BeanFactory must not be null");
final Class<?> beanClass = this.getBeanClass(bean);
if (this.requireComponentAnnotation && AnnotationUtils.findAnnotation(beanClass, Component.class) == null) {
// we only post-process stereotype components
return bean;
}
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Map<Class<? extends Annotation>, List<Annotation>> annotationChains =
new HashMap<Class<? extends Annotation>, List<Annotation>>();
for (Class<? extends Annotation> annotationType :
MessagingAnnotationPostProcessor.this.postProcessors.keySet()) {
if (AnnotatedElementUtils.isAnnotated(method, annotationType.getName())) {
List<Annotation> annotationChain = getAnnotationChain(method, annotationType);
if (annotationChain.size() > 0) {
annotationChains.put(annotationType, annotationChain);
}
ReflectionUtils.doWithMethods(beanClass, method -> {
Map<Class<? extends Annotation>, List<Annotation>> annotationChains = new HashMap<>();
for (Class<? extends Annotation> annotationType :
MessagingAnnotationPostProcessor.this.postProcessors.keySet()) {
if (AnnotatedElementUtils.isAnnotated(method, annotationType.getName())) {
List<Annotation> annotationChain = getAnnotationChain(method, annotationType);
if (annotationChain.size() > 0) {
annotationChains.put(annotationType, annotationChain);
}
}
}
for (Map.Entry<Class<? extends Annotation>, List<Annotation>> entry : annotationChains.entrySet()) {
Class<? extends Annotation> annotationType = entry.getKey();
List<Annotation> annotations = entry.getValue();
MethodAnnotationPostProcessor postProcessor =
MessagingAnnotationPostProcessor.this.postProcessors.get(annotationType);
if (postProcessor != null && postProcessor.shouldCreateEndpoint(method, annotations)) {
Method targetMethod = method;
if (AopUtils.isJdkDynamicProxy(bean)) {
try {
targetMethod = bean.getClass().getMethod(method.getName(), method.getParameterTypes());
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Service methods must be extracted to the service "
+ "interface for JdkDynamicProxy. The affected bean is: '" + beanName + "' "
+ "and its method: '" + method + "'", e);
for (Entry<Class<? extends Annotation>, List<Annotation>> entry : annotationChains.entrySet()) {
Class<? extends Annotation> annotationType = entry.getKey();
List<Annotation> annotations = entry.getValue();
MethodAnnotationPostProcessor<?> postProcessor =
MessagingAnnotationPostProcessor.this.postProcessors.get(annotationType);
if (postProcessor != null && postProcessor.shouldCreateEndpoint(method, annotations)) {
Method targetMethod = method;
if (AopUtils.isJdkDynamicProxy(bean)) {
try {
targetMethod = bean.getClass().getMethod(method.getName(), method.getParameterTypes());
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Service methods must be extracted to the service "
+ "interface for JdkDynamicProxy. The affected bean is: '" + beanName + "' "
+ "and its method: '" + method + "'", e);
}
}
Object result = postProcessor.postProcess(bean, beanName, targetMethod, annotations);
if (result != null && result instanceof AbstractEndpoint) {
AbstractEndpoint endpoint = (AbstractEndpoint) result;
String autoStartup = MessagingAnnotationUtils.resolveAttribute(annotations, "autoStartup",
String.class);
if (StringUtils.hasText(autoStartup)) {
autoStartup = getBeanFactory().resolveEmbeddedValue(autoStartup);
if (StringUtils.hasText(autoStartup)) {
endpoint.setAutoStartup(Boolean.parseBoolean(autoStartup));
}
}
Object result = postProcessor.postProcess(bean, beanName, targetMethod, annotations);
if (result != null && result instanceof AbstractEndpoint) {
AbstractEndpoint endpoint = (AbstractEndpoint) result;
String autoStartup = MessagingAnnotationUtils.resolveAttribute(annotations, "autoStartup",
String.class);
if (StringUtils.hasText(autoStartup)) {
autoStartup = getBeanFactory().resolveEmbeddedValue(autoStartup);
if (StringUtils.hasText(autoStartup)) {
endpoint.setAutoStartup(Boolean.parseBoolean(autoStartup));
}
}
String phase = MessagingAnnotationUtils.resolveAttribute(annotations, "phase", String.class);
String phase = MessagingAnnotationUtils.resolveAttribute(annotations, "phase", String.class);
if (StringUtils.hasText(phase)) {
phase = getBeanFactory().resolveEmbeddedValue(phase);
if (StringUtils.hasText(phase)) {
phase = getBeanFactory().resolveEmbeddedValue(phase);
if (StringUtils.hasText(phase)) {
endpoint.setPhase(Integer.parseInt(phase));
}
endpoint.setPhase(Integer.parseInt(phase));
}
}
String endpointBeanName = generateBeanName(beanName, method, annotationType);
endpoint.setBeanName(endpointBeanName);
getBeanFactory().registerSingleton(endpointBeanName, endpoint);
getBeanFactory().initializeBean(endpoint, endpointBeanName);
String endpointBeanName = generateBeanName(beanName, method, annotationType);
endpoint.setBeanName(endpointBeanName);
getBeanFactory().registerSingleton(endpointBeanName, endpoint);
getBeanFactory().initializeBean(endpoint, endpointBeanName);
Role role = AnnotationUtils.findAnnotation(method, Role.class);
if (role != null) {
MessagingAnnotationPostProcessor.this.lazyLifecycleRoles.add(role.value(),
endpointBeanName);
}
Role role = AnnotationUtils.findAnnotation(method, Role.class);
if (role != null) {
MessagingAnnotationPostProcessor.this.lazyLifecycleRoles.add(role.value(),
endpointBeanName);
}
}
}

View File

@@ -66,16 +66,6 @@ public final class IntegrationProperties {
*/
public static final String THROW_EXCEPTION_ON_LATE_REPLY = INTEGRATION_PROPERTIES_PREFIX + "messagingTemplate.throwExceptionOnLateReply";
/**
* Specifies the value of {@link org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor#requireComponentAnnotation}.
*/
public static final String REQUIRE_COMPONENT_ANNOTATION = INTEGRATION_PROPERTIES_PREFIX + "messagingAnnotations.require.componentAnnotation";
/**
* Specifies the value of {@link org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor#requireComponentAnnotation}.
*/
public static final String GATEWAY_CONVERT_RECEIVE_MESSAGE = INTEGRATION_PROPERTIES_PREFIX + "messagingGateway.convertReceiveMessage";
private static Properties defaults;
static {

View File

@@ -47,7 +47,6 @@ import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.GatewayHeader;
import org.springframework.integration.context.IntegrationProperties;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
import org.springframework.integration.support.management.TrackableComponent;
@@ -130,8 +129,6 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint
private volatile MethodArgsMessageMapper argsMapper;
private volatile boolean convertReceiveMessage;
/**
* Create a Factory whose service interface type can be configured by setter injection.
* If none is set, it will fall back to the default service interface type,
@@ -343,8 +340,6 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint
}
}
this.convertReceiveMessage =
getIntegrationProperty(IntegrationProperties.GATEWAY_CONVERT_RECEIVE_MESSAGE, Boolean.class);
this.initialized = true;
}
}
@@ -434,12 +429,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint
if (paramCount == 0 && !hasPayloadExpression) {
if (shouldReply) {
if (shouldReturnMessage) {
if (this.convertReceiveMessage) {
return gateway.receive();
}
else {
return gateway.receiveMessage();
}
return gateway.receiveMessage();
}
response = gateway.receive();
}

View File

@@ -3,5 +3,3 @@ spring.integration.channels.maxUnicastSubscribers=0x7fffffff
spring.integration.channels.maxBroadcastSubscribers=0x7fffffff
spring.integration.taskScheduler.poolSize=10
spring.integration.messagingTemplate.throwExceptionOnLateReply=false
spring.integration.messagingAnnotations.require.componentAnnotation=false
spring.integration.messagingGateway.convertReceiveMessage=false

View File

@@ -13,10 +13,6 @@
<annotation-config/> <!-- Second declaration should not be a problem - see INT-3445 -->
<util:properties id="integrationGlobalProperties">
<beans:prop key="spring.integration.messagingAnnotations.require.componentAnnotation">true</beans:prop>
</util:properties>
<beans:bean id="annotatedEndpoint"
class="org.springframework.integration.config.annotation.AnnotatedEndpointActivationTests.AnnotatedEndpoint"/>

View File

@@ -17,7 +17,6 @@
package org.springframework.integration.config.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -80,7 +79,7 @@ public class AnnotatedEndpointActivationTests {
assertEquals(1, count);
assertTrue(this.applicationContext.containsBean("annotatedEndpoint.process.serviceActivator"));
assertFalse(this.applicationContext.containsBean("annotatedEndpoint2.process.serviceActivator"));
assertTrue(this.applicationContext.containsBean("annotatedEndpoint2.process.serviceActivator"));
}
@Test

View File

@@ -16,20 +16,14 @@
package org.springframework.integration.gateway;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.mock;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -50,8 +44,6 @@ import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.context.IntegrationProperties;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.support.utils.IntegrationUtils;
import org.springframework.messaging.Message;
@@ -161,41 +153,6 @@ public class GatewayProxyFactoryBeanTests {
assertEquals("foo", message.getPayload());
}
@Test
public void testReceiveMessageConvert() throws Exception {
QueueChannel replyChannel = new QueueChannel();
replyChannel.send(new GenericMessage<>("foo"));
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
proxyFactory.setServiceInterface(TestService.class);
proxyFactory.setDefaultReplyChannel(replyChannel);
BeanFactory beanFactory = mock(BeanFactory.class);
given(beanFactory.containsBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME))
.willReturn(true);
willAnswer(invocation -> {
Properties properties = new Properties();
properties.setProperty(IntegrationProperties.GATEWAY_CONVERT_RECEIVE_MESSAGE, "true");
return properties;
})
.given(beanFactory)
.getBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME, Properties.class);
proxyFactory.setBeanFactory(beanFactory);
proxyFactory.afterPropertiesSet();
TestService service = (TestService) proxyFactory.getObject();
try {
service.getMessage();
fail("ClassCastException expected");
}
catch (Exception e) {
assertThat(e, instanceOf(ClassCastException.class));
assertThat(e.getMessage(),
containsString("java.lang.String cannot be cast to org.springframework.messaging.Message"));
}
}
@Test
public void testRequestReplyWithTypeConversion() throws Exception {
final QueueChannel requestChannel = new QueueChannel();