diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java index 87b23d6592..3c0b63bc32 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -30,26 +30,30 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** - * Encapsulates information about a bean method consisting of a {@link #getMethod() method} - * and a {@link #getBean() bean}. Provides convenient access to method parameters, - * method return value, method annotations. + * Encapsulates information about a handler method consisting of a + * {@linkplain #getMethod() method} and a {@linkplain #getBean() bean}. + * Provides convenient access to method parameters, method return value, method annotations. * - *
The class may be created with a bean instance or with a bean name (e.g. lazy bean, - * prototype bean). Use {@link #createWithResolvedBean()} to obtain an {@link HandlerMethod} - * instance with a bean instance initialized through the bean factory. + *
The class may be created with a bean instance or with a bean name (e.g. lazy-init bean, + * prototype bean). Use {@link #createWithResolvedBean()} to obtain a {@link HandlerMethod} + * instance with a bean instance resolved through the associated {@link BeanFactory}. * * @author Arjen Poutsma * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 4.0 */ public class HandlerMethod { - protected final Log logger = LogFactory.getLog(HandlerMethod.class); + /** Logger that is available to subclasses */ + protected final Log logger = LogFactory.getLog(getClass()); private final Object bean; private final BeanFactory beanFactory; + private final Class> beanType; + private final Method method; private final Method bridgedMethod; @@ -65,6 +69,7 @@ public class HandlerMethod { Assert.notNull(method, "Method is required"); this.bean = bean; this.beanFactory = null; + this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); @@ -79,6 +84,7 @@ public class HandlerMethod { Assert.notNull(methodName, "Method name is required"); this.bean = bean; this.beanFactory = null; + this.beanType = ClassUtils.getUserClass(bean); this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); this.parameters = initMethodParameters(); @@ -93,22 +99,22 @@ public class HandlerMethod { Assert.hasText(beanName, "Bean name is required"); Assert.notNull(beanFactory, "BeanFactory is required"); Assert.notNull(method, "Method is required"); - Assert.isTrue(beanFactory.containsBean(beanName), - "BeanFactory [" + beanFactory + "] does not contain bean [" + beanName + "]"); this.bean = beanName; this.beanFactory = beanFactory; + this.beanType = ClassUtils.getUserClass(beanFactory.getType(beanName)); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); } /** - * Copy constructor for use in sub-classes. + * Copy constructor for use in subclasses. */ protected HandlerMethod(HandlerMethod handlerMethod) { Assert.notNull(handlerMethod, "HandlerMethod is required"); this.bean = handlerMethod.bean; this.beanFactory = handlerMethod.beanFactory; + this.beanType = handlerMethod.beanType; this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; @@ -122,6 +128,7 @@ public class HandlerMethod { Assert.notNull(handler, "Handler object is required"); this.bean = handler; this.beanFactory = handlerMethod.beanFactory; + this.beanType = handlerMethod.beanType; this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; @@ -152,18 +159,17 @@ public class HandlerMethod { } /** - * Returns the type of the handler for this handler method. - * Note that if the bean type is a CGLIB-generated class, the original, user-defined class is returned. + * This method returns the type of the handler for this handler method. + *
Note that if the bean type is a CGLIB-generated class, the original
+ * user-defined class is returned.
*/
public Class> getBeanType() {
- Class> clazz = (this.bean instanceof String ?
- this.beanFactory.getType((String) this.bean) : this.bean.getClass());
- return ClassUtils.getUserClass(clazz);
+ return this.beanType;
}
/**
- * If the bean method is a bridge method, this method returns the bridged (user-defined) method.
- * Otherwise it returns the same method as {@link #getMethod()}.
+ * If the bean method is a bridge method, this method returns the bridged
+ * (user-defined) method. Otherwise it returns the same method as {@link #getMethod()}.
*/
protected Method getBridgedMethod() {
return this.bridgedMethod;
@@ -198,8 +204,8 @@ public class HandlerMethod {
}
/**
- * Returns a single annotation on the underlying method traversing its super methods if no
- * annotation can be found on the given method itself.
+ * Returns a single annotation on the underlying method traversing its super methods
+ * if no annotation can be found on the given method itself.
* @param annotationType the type of annotation to introspect the method for.
* @return the annotation, or {@code null} if none found
*/
@@ -208,8 +214,8 @@ public class HandlerMethod {
}
/**
- * If the provided instance contains a bean name rather than an object instance, the bean name is resolved
- * before a {@link HandlerMethod} is created and returned.
+ * If the provided instance contains a bean name rather than an object instance,
+ * the bean name is resolved before a {@link HandlerMethod} is created and returned.
*/
public HandlerMethod createWithResolvedBean() {
Object handler = this.bean;
@@ -220,26 +226,27 @@ public class HandlerMethod {
return new HandlerMethod(this, handler);
}
+ public String getShortLogMessage() {
+ int args = this.method.getParameterTypes().length;
+ return getBeanType().getName() + "#" + this.method.getName() + "[" + args + " args]";
+ }
+
+
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
+ public boolean equals(Object other) {
+ if (this == other) {
return true;
}
- if (obj != null && obj instanceof HandlerMethod) {
- HandlerMethod other = (HandlerMethod) obj;
- return this.bean.equals(other.bean) && this.method.equals(other.method);
+ if (!(other instanceof HandlerMethod)) {
+ return false;
}
- return false;
+ HandlerMethod otherMethod = (HandlerMethod) other;
+ return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method));
}
@Override
public int hashCode() {
- return this.bean.hashCode() * 31 + this.method.hashCode();
- }
-
- public String getShortLogMessage() {
- int args = method.getParameterTypes().length;
- return getBeanType().getName() + "#" + this.method.getName() + "[" + args + " args]";
+ return (this.bean.hashCode() * 31 + this.method.hashCode());
}
@Override
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java
index e14f0b07e7..18a119669c 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java
@@ -30,7 +30,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -159,7 +158,7 @@ public abstract class AbstractMethodMessageHandler Sub-classes should also take into account custom argument types configured via
- * {@link #setCustomArgumentResolvers(java.util.List)}.
+ * have not already been set via {@link #setArgumentResolvers}.
+ * Subclasses should also take into account custom argument types configured via
+ * {@link #setCustomArgumentResolvers}.
*/
protected abstract List extends HandlerMethodArgumentResolver> initArgumentResolvers();
/**
* Return the list of return value handlers to use. Invoked only if the return
- * value handlers have not already been set via {@link #setReturnValueHandlers(java.util.List)}.
- * Sub-classes should also take into account custom return value types configured
- * via {@link #setCustomReturnValueHandlers(java.util.List)}.
+ * value handlers have not already been set via {@link #setReturnValueHandlers}.
+ * Subclasses should also take into account custom return value types configured
+ * via {@link #setCustomReturnValueHandlers}.
*/
protected abstract List extends HandlerMethodReturnValueHandler> initReturnValueHandlers();
@@ -253,9 +251,8 @@ public abstract class AbstractMethodMessageHandler The class may be created with a bean instance or with a bean name (e.g. lazy-init bean,
* prototype bean). Use {@link #createWithResolvedBean()} to obtain a {@link HandlerMethod}
@@ -40,17 +40,20 @@ import org.springframework.util.ClassUtils;
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
+ * @author Juergen Hoeller
* @since 3.1
*/
public class HandlerMethod {
/** Logger that is available to subclasses */
- protected final Log logger = LogFactory.getLog(HandlerMethod.class);
+ protected final Log logger = LogFactory.getLog(getClass());
private final Object bean;
private final BeanFactory beanFactory;
+ private final Class> beanType;
+
private final Method method;
private final Method bridgedMethod;
@@ -66,6 +69,7 @@ public class HandlerMethod {
Assert.notNull(method, "Method is required");
this.bean = bean;
this.beanFactory = null;
+ this.beanType = ClassUtils.getUserClass(bean);
this.method = method;
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
this.parameters = initMethodParameters();
@@ -80,6 +84,7 @@ public class HandlerMethod {
Assert.notNull(methodName, "Method name is required");
this.bean = bean;
this.beanFactory = null;
+ this.beanType = ClassUtils.getUserClass(bean);
this.method = bean.getClass().getMethod(methodName, parameterTypes);
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method);
this.parameters = initMethodParameters();
@@ -94,22 +99,22 @@ public class HandlerMethod {
Assert.hasText(beanName, "Bean name is required");
Assert.notNull(beanFactory, "BeanFactory is required");
Assert.notNull(method, "Method is required");
- Assert.isTrue(beanFactory.containsBean(beanName),
- "BeanFactory [" + beanFactory + "] does not contain bean [" + beanName + "]");
this.bean = beanName;
this.beanFactory = beanFactory;
+ this.beanType = ClassUtils.getUserClass(beanFactory.getType(beanName));
this.method = method;
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
this.parameters = initMethodParameters();
}
/**
- * Copy constructor for use in sub-classes.
+ * Copy constructor for use in subclasses.
*/
protected HandlerMethod(HandlerMethod handlerMethod) {
Assert.notNull(handlerMethod, "HandlerMethod is required");
this.bean = handlerMethod.bean;
this.beanFactory = handlerMethod.beanFactory;
+ this.beanType = handlerMethod.beanType;
this.method = handlerMethod.method;
this.bridgedMethod = handlerMethod.bridgedMethod;
this.parameters = handlerMethod.parameters;
@@ -123,6 +128,7 @@ public class HandlerMethod {
Assert.notNull(handler, "Handler object is required");
this.bean = handler;
this.beanFactory = handlerMethod.beanFactory;
+ this.beanType = handlerMethod.beanType;
this.method = handlerMethod.method;
this.bridgedMethod = handlerMethod.bridgedMethod;
this.parameters = handlerMethod.parameters;
@@ -153,18 +159,17 @@ public class HandlerMethod {
}
/**
- * Returns the type of the handler for this handler method.
- * Note that if the bean type is a CGLIB-generated class, the original, user-defined class is returned.
+ * This method returns the type of the handler for this handler method.
+ * Note that if the bean type is a CGLIB-generated class, the original
+ * user-defined class is returned.
*/
public Class> getBeanType() {
- Class> clazz = (this.bean instanceof String ?
- this.beanFactory.getType((String) this.bean) : this.bean.getClass());
- return ClassUtils.getUserClass(clazz);
+ return this.beanType;
}
/**
- * If the bean method is a bridge method, this method returns the bridged (user-defined) method.
- * Otherwise it returns the same method as {@link #getMethod()}.
+ * If the bean method is a bridge method, this method returns the bridged
+ * (user-defined) method. Otherwise it returns the same method as {@link #getMethod()}.
*/
protected Method getBridgedMethod() {
return this.bridgedMethod;
@@ -199,8 +204,8 @@ public class HandlerMethod {
}
/**
- * Returns a single annotation on the underlying method traversing its super methods if no
- * annotation can be found on the given method itself.
+ * Returns a single annotation on the underlying method traversing its super methods
+ * if no annotation can be found on the given method itself.
* @param annotationType the type of annotation to introspect the method for.
* @return the annotation, or {@code null} if none found
*/
@@ -209,8 +214,8 @@ public class HandlerMethod {
}
/**
- * If the provided instance contains a bean name rather than an object instance, the bean name is resolved
- * before a {@link HandlerMethod} is created and returned.
+ * If the provided instance contains a bean name rather than an object instance,
+ * the bean name is resolved before a {@link HandlerMethod} is created and returned.
*/
public HandlerMethod createWithResolvedBean() {
Object handler = this.bean;
@@ -221,21 +226,22 @@ public class HandlerMethod {
return new HandlerMethod(this, handler);
}
+
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
+ public boolean equals(Object other) {
+ if (this == other) {
return true;
}
- if (obj != null && obj instanceof HandlerMethod) {
- HandlerMethod other = (HandlerMethod) obj;
- return (this.bean.equals(other.bean) && this.method.equals(other.method));
+ if (!(other instanceof HandlerMethod)) {
+ return false;
}
- return false;
+ HandlerMethod otherMethod = (HandlerMethod) other;
+ return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method));
}
@Override
public int hashCode() {
- return this.bean.hashCode() * 31 + this.method.hashCode();
+ return (this.bean.hashCode() * 31 + this.method.hashCode());
}
@Override
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
index 2e02f62cf1..9860598fb0 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2015 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.
@@ -40,8 +40,8 @@ import org.springframework.web.method.HandlerMethodSelector;
import org.springframework.web.servlet.HandlerMapping;
/**
- * Abstract base class for {@link HandlerMapping} implementations that define a
- * mapping between a request and a {@link HandlerMethod}.
+ * Abstract base class for {@link HandlerMapping} implementations that define
+ * a mapping between a request and a {@link HandlerMethod}.
*
* For each registered handler method, a unique mapping is maintained with
* subclasses defining the details of the mapping type {@code