From af213a09eed2153b4f4b6fa1ade42a08c60f2dbb Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 7 Oct 2015 13:25:41 +0200 Subject: [PATCH] Polishing --- .../ApplicationListenerMethodAdapter.java | 77 ++++++++++--------- .../context/event/EventListener.java | 25 +++--- .../jms/annotation/JmsListener.java | 48 ++++++------ ...msListenerAnnotationBeanPostProcessor.java | 12 +-- 4 files changed, 82 insertions(+), 80 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index 94d5c792fa..4f1b5a301f 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -81,6 +81,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe private EventListener eventListener; + public ApplicationListenerMethodAdapter(String beanName, Class targetClass, Method method) { this.beanName = beanName; this.method = method; @@ -90,6 +91,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe this.methodKey = new AnnotatedElementKey(this.method, this.targetClass); } + /** * Initialize this instance. */ @@ -98,11 +100,40 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe this.evaluator = evaluator; } + @Override public void onApplicationEvent(ApplicationEvent event) { processEvent(event); } + @Override + public boolean supportsEventType(ResolvableType eventType) { + for (ResolvableType declaredEventType : this.declaredEventTypes) { + if (declaredEventType.isAssignableFrom(eventType)) { + return true; + } + else if (PayloadApplicationEvent.class.isAssignableFrom(eventType.getRawClass())) { + ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric(); + if (declaredEventType.isAssignableFrom(payloadType)) { + return true; + } + } + } + return eventType.hasUnresolvableGenerics(); + } + + @Override + public boolean supportsSourceType(Class sourceType) { + return true; + } + + @Override + public int getOrder() { + Order order = getMethodAnnotation(Order.class); + return (order != null ? order.value() : 0); + } + + /** * Process the specified {@link ApplicationEvent}, checking if the condition * match and handling non-null result, if any. @@ -144,7 +175,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe } protected void handleResult(Object result) { - Assert.notNull(this.applicationContext, "ApplicationContext must no be null."); if (result.getClass().isArray()) { Object[] events = ObjectUtils.toObjectArray(result); for (Object event : events) { @@ -164,6 +194,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe private void publishEvent(Object event) { if (event != null) { + Assert.notNull(this.applicationContext, "ApplicationContext must no be null"); this.applicationContext.publishEvent(event); } } @@ -174,41 +205,14 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe } String condition = getCondition(); if (StringUtils.hasText(condition)) { - Assert.notNull(this.evaluator, "Evaluator must no be null."); - EvaluationContext evaluationContext = this.evaluator.createEvaluationContext(event, - this.targetClass, this.method, args); + Assert.notNull(this.evaluator, "EventExpressionEvaluator must no be null"); + EvaluationContext evaluationContext = this.evaluator.createEvaluationContext( + event, this.targetClass, this.method, args); return this.evaluator.condition(condition, this.methodKey, evaluationContext); } return true; } - @Override - public boolean supportsEventType(ResolvableType eventType) { - for (ResolvableType declaredEventType : this.declaredEventTypes) { - if (declaredEventType.isAssignableFrom(eventType)) { - return true; - } - else if (PayloadApplicationEvent.class.isAssignableFrom(eventType.getRawClass())) { - ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric(); - if (declaredEventType.isAssignableFrom(payloadType)) { - return true; - } - } - } - return eventType.hasUnresolvableGenerics(); - } - - @Override - public boolean supportsSourceType(Class sourceType) { - return true; - } - - @Override - public int getOrder() { - Order order = getMethodAnnotation(Order.class); - return (order != null ? order.value() : 0); - } - protected A getMethodAnnotation(Class annotationType) { return AnnotationUtils.findAnnotation(this.method, annotationType); } @@ -246,7 +250,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe * Return the target bean instance to use. */ protected Object getTargetBean() { - Assert.notNull(this.applicationContext, "ApplicationContext must no be null."); + Assert.notNull(this.applicationContext, "ApplicationContext must no be null"); return this.applicationContext.getBean(this.beanName); } @@ -346,8 +350,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe private List resolveDeclaredEventTypes() { int count = this.method.getParameterTypes().length; if (count > 1) { - throw new IllegalStateException("Maximum one parameter is allowed " + - "for event listener method: " + method); + throw new IllegalStateException( + "Maximum one parameter is allowed for event listener method: " + this.method); } EventListener ann = getEventListener(); if (ann != null && ann.classes().length > 0) { @@ -359,13 +363,14 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe } else { if (count == 0) { - throw new IllegalStateException("Event parameter is mandatory " + - "for event listener method: " + method); + throw new IllegalStateException( + "Event parameter is mandatory for event listener method: " + this.method); } return Collections.singletonList(ResolvableType.forMethodParameter(this.method, 0)); } } + @Override public String toString() { return this.method.toGenericString(); diff --git a/spring-context/src/main/java/org/springframework/context/event/EventListener.java b/spring-context/src/main/java/org/springframework/context/event/EventListener.java index b393b66f4c..5f86890079 100644 --- a/spring-context/src/main/java/org/springframework/context/event/EventListener.java +++ b/spring-context/src/main/java/org/springframework/context/event/EventListener.java @@ -29,8 +29,8 @@ import org.springframework.core.annotation.AliasFor; * Annotation that marks a method as a listener for application events. * *

If an annotated method supports a single event type, the method may - * declare a single parameter that reflects the event type to listen to. If - * an annotated method supports multiple event types, this annotation may + * declare a single parameter that reflects the event type to listen to. + * If an annotated method supports multiple event types, this annotation may * refer to one or more supported event types using the {@code classes} * attribute. See {@link #classes} for further details. * @@ -42,20 +42,19 @@ import org.springframework.core.annotation.AliasFor; * when using Java config or manually via the {@code } * element when using XML config. * - *

Annotated methods may have a non-{@code void} return type. When they - * do, the result of the method invocation is sent as a new event. If the - * return type is either an array or a collection, each element is sent as - * a new event. + *

Annotated methods may have a non-{@code void} return type. When they do, + * the result of the method invocation is sent as a new event. If the return type + * is either an array or a collection, each element is sent as a new event. * - *

It is also possible to define the order in which listeners for a - * certain event are invoked. To do so, add a regular + *

It is also possible to define the order in which listeners for a certain + * event are invoked. To do so, add Spring's common * {@link org.springframework.core.annotation.Order @Order} annotation * alongside this annotation. * - *

While it is possible for an event listener to declare that it throws - * arbitrary exception types, any checked exceptions thrown from an event - * listener will be wrapped in a {@link java.lang.reflect.UndeclaredThrowableException} - * since the caller can only handle runtime exceptions. + *

While it is possible for an event listener to declare that it throws arbitrary + * exception types, any checked exceptions thrown from an event listener will be + * wrapped in an {@link java.lang.reflect.UndeclaredThrowableException} since + * the caller can only handle runtime exceptions. * * @author Stephane Nicoll * @since 4.2 @@ -89,4 +88,4 @@ public @interface EventListener { */ String condition() default ""; -} \ No newline at end of file +} diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java index 29cfaa10f7..bf62c49317 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java @@ -26,21 +26,20 @@ import java.lang.annotation.Target; import org.springframework.messaging.handler.annotation.MessageMapping; /** - * Annotation that marks a method to be the target of a JMS message - * listener on the specified {@link #destination}. The {@link #containerFactory} - * identifies the {@link org.springframework.jms.config.JmsListenerContainerFactory - * JmsListenerContainerFactory} to use to build the JMS listener container. If not - * set, a default container factory is assumed to be available with a bean - * name of {@code jmsListenerContainerFactory} unless an explicit default has been - * provided through configuration. + * Annotation that marks a method to be the target of a JMS message listener on the + * specified {@link #destination}. The {@link #containerFactory} identifies the + * {@link org.springframework.jms.config.JmsListenerContainerFactory} to use to build + * the JMS listener container. If not set, a default container factory is + * assumed to be available with a bean name of {@code jmsListenerContainerFactory} + * unless an explicit default has been provided through configuration. * - *

Processing of {@code @JmsListener} annotations is performed by - * registering a {@link JmsListenerAnnotationBeanPostProcessor}. This can be - * done manually or, more conveniently, through the {@code } - * element or {@link EnableJms @EnableJms} annotation. + *

Processing of {@code @JmsListener} annotations is performed by registering a + * {@link JmsListenerAnnotationBeanPostProcessor}. This can be done manually or, + * more conveniently, through the {@code } element or + * {@link EnableJms @EnableJms} annotation. * - *

Annotated methods are allowed to have flexible signatures similar to what - * {@link MessageMapping} provides: + *

Annotated JMS listener methods are allowed to have flexible signatures similar + * to what {@link MessageMapping} provides: *

    *
  • {@link javax.jms.Session} to get access to the JMS session
  • *
  • {@link javax.jms.Message} or one of its subclasses to get access to the raw JMS message
  • @@ -49,15 +48,15 @@ import org.springframework.messaging.handler.annotation.MessageMapping; * arguments, including support for validation *
  • {@link org.springframework.messaging.handler.annotation.Header @Header}-annotated method * arguments to extract specific header values, including standard JMS headers defined by - * {@link org.springframework.jms.support.JmsHeaders JmsHeaders}
  • + * {@link org.springframework.jms.support.JmsHeaders} *
  • {@link org.springframework.messaging.handler.annotation.Headers @Headers}-annotated - * method argument that must also be assignable to {@link java.util.Map} for obtaining access to all - * headers
  • - *
  • {@link org.springframework.messaging.MessageHeaders MessageHeaders} arguments for - * obtaining access to all headers
  • - *
  • {@link org.springframework.messaging.support.MessageHeaderAccessor MessageHeaderAccessor} - * or {@link org.springframework.jms.support.JmsMessageHeaderAccessor JmsMessageHeaderAccessor} - * for convenient access to all method arguments
  • + * method argument that must also be assignable to {@link java.util.Map} for obtaining + * access to all headers + *
  • {@link org.springframework.messaging.MessageHeaders} arguments for obtaining + * access to all headers
  • + *
  • {@link org.springframework.messaging.support.MessageHeaderAccessor} or + * {@link org.springframework.jms.support.JmsMessageHeaderAccessor} for convenient + * access to all method arguments
  • *
* *

Annotated methods may have a non-{@code void} return type. When they do, @@ -75,9 +74,9 @@ import org.springframework.messaging.handler.annotation.MessageMapping; */ @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) -@MessageMapping @Documented @Repeatable(JmsListeners.class) +@MessageMapping public @interface JmsListener { /** @@ -88,7 +87,7 @@ public @interface JmsListener { String id() default ""; /** - * The bean name of the {@link org.springframework.jms.config.JmsListenerContainerFactory JmsListenerContainerFactory} + * The bean name of the {@link org.springframework.jms.config.JmsListenerContainerFactory} * to use to create the message listener container responsible for serving this endpoint. *

If not specified, the default container factory is used, if any. */ @@ -96,8 +95,7 @@ public @interface JmsListener { /** * The destination name for this listener, resolved through the container-wide - * {@link org.springframework.jms.support.destination.DestinationResolver DestinationResolver} - * strategy. + * {@link org.springframework.jms.support.destination.DestinationResolver} strategy. */ String destination(); diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java index 373f8443a4..334a359891 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java @@ -54,8 +54,8 @@ import org.springframework.util.StringUtils; /** * Bean post-processor that registers methods annotated with {@link JmsListener} * to be invoked by a JMS message listener container created under the cover - * by a {@link org.springframework.jms.config.JmsListenerContainerFactory} according - * to the parameters of the annotation. + * by a {@link org.springframework.jms.config.JmsListenerContainerFactory} + * according to the attributes of the annotation. * *

Annotated methods can use flexible arguments as defined by {@link JmsListener}. * @@ -63,10 +63,10 @@ import org.springframework.util.StringUtils; * {@code } XML element, and also by the {@link EnableJms} * annotation. * - *

Auto-detect any {@link JmsListenerConfigurer} instances in the container, + *

Autodetects any {@link JmsListenerConfigurer} instances in the container, * allowing for customization of the registry to be used, the default container - * factory or for fine-grained control over endpoints registration. See - * {@link EnableJms} Javadoc for complete usage details. + * factory or for fine-grained control over endpoints registration. See the + * {@link EnableJms} javadocs for complete usage details. * * @author Stephane Nicoll * @author Juergen Hoeller @@ -282,7 +282,7 @@ public class JmsListenerAnnotationBeanPostProcessor return resolve(jmsListener.id()); } else { - return "org.springframework.jms.JmsListenerEndpointContainer#" + counter.getAndIncrement(); + return "org.springframework.jms.JmsListenerEndpointContainer#" + this.counter.getAndIncrement(); } }