Skip to content

Commit 72ff98a

Browse files
committed
Apply code review
Signed-off-by: yongjunhong <[email protected]>
1 parent 2eddd3b commit 72ff98a

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
import java.lang.annotation.Annotation;
2020
import java.lang.reflect.AnnotatedElement;
2121
import java.lang.reflect.Method;
22+
import java.lang.reflect.Modifier;
2223
import java.util.Collections;
2324
import java.util.LinkedHashMap;
2425
import java.util.List;
2526
import java.util.Map;
27+
import java.util.Objects;
2628
import java.util.function.Predicate;
2729
import java.util.stream.Stream;
2830

@@ -71,6 +73,7 @@
7173
* @author Rossen Stoyanchev
7274
* @author Sam Brannen
7375
* @author Olga Maciaszek-Sharma
76+
* @author Yongjun Hong
7477
* @since 3.1
7578
*/
7679
@SuppressWarnings("removal")
@@ -183,13 +186,47 @@ protected boolean isHandler(Class<?> beanType) {
183186
* Uses type-level and method-level {@link RequestMapping @RequestMapping}
184187
* and {@link HttpExchange @HttpExchange} annotations to create the
185188
* {@link RequestMappingInfo}.
189+
* <p>For CGLIB proxy classes, additional validation is performed based on method visibility:
190+
* <ul>
191+
* <li>Private methods cannot be overridden and therefore cannot be used as handler methods.</li>
192+
* <li>Package-private methods from different packages are inaccessible and must be
193+
* changed to public or protected.</li>
194+
* </ul>
186195
* @return the created {@code RequestMappingInfo}, or {@code null} if the method
187196
* does not have a {@code @RequestMapping} or {@code @HttpExchange} annotation
188197
* @see #getCustomMethodCondition(Method)
189198
* @see #getCustomTypeCondition(Class)
190199
*/
191200
@Override
192201
protected @Nullable RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
202+
int modifiers = method.getModifiers();
203+
204+
if (isCglibProxy(handlerType)) {
205+
if (Modifier.isPrivate(modifiers)) {
206+
throw new IllegalStateException(
207+
"Private method [" + method + "] on CGLIB proxy class [" + handlerType.getName() +
208+
"] cannot be used as a request handler method because private methods cannot be overridden. " +
209+
"Change the method to non-private visibility or use interface-based JDK proxying instead.");
210+
}
211+
212+
if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) {
213+
Class<?> declaringClass = method.getDeclaringClass();
214+
Package methodPackage = declaringClass.getPackage();
215+
Package handlerPackage = handlerType.getPackage();
216+
217+
if (Objects.equals(methodPackage, handlerPackage)) {
218+
String methodPackageName = (methodPackage != null) ? methodPackage.getName() : "default package";
219+
String handlerPackageName = (handlerPackage != null) ? handlerPackage.getName() : "default package";
220+
221+
throw new IllegalStateException(
222+
"Package-private method [" + method + "] on CGLIB proxy class [" + declaringClass.getName() +
223+
"] from package [" + methodPackageName + "] cannot be advised when used by handler class [" +
224+
handlerType.getName() + "] from package [" + handlerPackageName + "] because it is effectively private. " +
225+
"Either make the method public/protected or use interface-based JDK proxying instead.");
226+
}
227+
}
228+
}
229+
193230
RequestMappingInfo info = createRequestMappingInfo(method);
194231
if (info != null) {
195232
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
@@ -207,6 +244,12 @@ protected boolean isHandler(Class<?> beanType) {
207244
return info;
208245
}
209246

247+
248+
private boolean isCglibProxy(Class<?> beanType) {
249+
return beanType.getName().contains("$$");
250+
}
251+
252+
210253
@Nullable String getPathPrefix(Class<?> handlerType) {
211254
for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
212255
if (entry.getValue().test(handlerType)) {

0 commit comments

Comments
 (0)