diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java index ae9e41d6ad9..c3437b5d3dc 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -34,7 +34,7 @@ import org.springframework.util.ClassUtils; /** * AspectJ-based proxy factory, allowing for programmatic building * of proxies which include AspectJ aspects (code style as well - * Java 5 annotation style). + * annotation style). * * @author Rob Harrop * @author Juergen Hoeller diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java index 048cc603ccc..27fb520d40d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -60,8 +60,8 @@ public class AspectMetadata implements Serializable { private final Class aspectClass; /** - * AspectJ reflection information (AspectJ 5 / Java 5 specific). - * Re-resolved on deserialization since it isn't serializable itself. + * AspectJ reflection information. + *

Re-resolved on deserialization since it isn't serializable itself. */ private transient AjType ajType; diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java index 8055ec98cb6..860f0d6339c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -183,8 +183,8 @@ public abstract class AopUtils { * may be {@code DefaultFoo}. In this case, the method may be * {@code DefaultFoo.bar()}. This enables attributes on that method to be found. *

NOTE: In contrast to {@link org.springframework.util.ClassUtils#getMostSpecificMethod}, - * this method resolves Java 5 bridge methods in order to retrieve attributes - * from the original method definition. + * this method resolves bridge methods in order to retrieve attributes from + * the original method definition. * @param method the method to be invoked, which may come from an interface * @param targetClass the target class for the current invocation. * May be {@code null} or may not even implement the method. diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java index 847f1bb8622..bd1e0ea182d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 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. @@ -24,8 +24,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Simple ClassFilter that looks for a specific Java 5 annotation - * being present on a class. + * Simple ClassFilter that looks for a specific annotation being present on a class. * * @author Juergen Hoeller * @since 2.0 diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java index d734fbc0f14..34d79acfc57 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -26,9 +26,8 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Simple Pointcut that looks for a specific Java 5 annotation - * being present on a {@link #forClassAnnotation class} or - * {@link #forMethodAnnotation method}. + * Simple {@link Pointcut} that looks for a specific annotation being present on a + * {@linkplain #forClassAnnotation class} or {@linkplain #forMethodAnnotation method}. * * @author Juergen Hoeller * @author Sam Brannen diff --git a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java index 720c7b889bb..d507fa76bba 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -27,9 +27,10 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Simple MethodMatcher that looks for a specific Java 5 annotation - * being present on a method (checking both the method on the invoked - * interface, if any, and the corresponding method on the target class). + * Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks + * for a specific annotation being present on a method (checking both the method + * on the invoked interface, if any, and the corresponding method on the target + * class). * * @author Juergen Hoeller * @author Sam Brannen diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverAnnotationTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverAnnotationTests.java deleted file mode 100644 index fb64933db17..00000000000 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverAnnotationTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2018 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.aop.aspectj; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.junit.jupiter.api.Test; - -/** - * Additional parameter name discover tests that need Java 5. - * Yes this will re-run the tests from the superclass, but that - * doesn't matter in the grand scheme of things... - * - * @author Adrian Colyer - * @author Chris Beams - */ -public class AspectJAdviceParameterNameDiscoverAnnotationTests extends AspectJAdviceParameterNameDiscovererTests { - - @Test - public void testAnnotationBinding() { - assertParameterNames(getMethod("pjpAndAnAnnotation"), - "execution(* *(..)) && @annotation(ann)", - new String[] {"thisJoinPoint","ann"}); - } - - - public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {} - - @interface MyAnnotation {} - -} diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java index 40a5de33103..beb986e6f82 100644 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -17,8 +17,11 @@ package org.springframework.aop.aspectj; import java.lang.reflect.Method; +import java.util.Arrays; import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException; @@ -27,200 +30,265 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** - * Unit tests for the {@link AspectJAdviceParameterNameDiscoverer} class. - * - *

See also {@link TigerAspectJAdviceParameterNameDiscovererTests} for tests relating to annotations. + * Unit tests for {@link AspectJAdviceParameterNameDiscoverer}. * * @author Adrian Colyer * @author Chris Beams + * @author Sam Brannen */ -public class AspectJAdviceParameterNameDiscovererTests { +class AspectJAdviceParameterNameDiscovererTests { - @Test - public void testNoArgs() { - assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]); - } + @Nested + class StandardTests { - @Test - public void testJoinPointOnly() { - assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"}); - } + @Test + void noArgs() { + assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]); + } - @Test - public void testJoinPointStaticPartOnly() { - assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"}); - } + @Test + void joinPointOnly() { + assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"}); + } - @Test - public void testTwoJoinPoints() { - assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class, - "Failed to bind all argument names: 1 argument(s) could not be bound"); - } + @Test + void joinPointStaticPartOnly() { + assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"}); + } - @Test - public void testOneThrowable() { - assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"}); - } + @Test + void twoJoinPoints() { + assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class, + "Failed to bind all argument names: 1 argument(s) could not be bound"); + } - @Test - public void testOneJPAndOneThrowable() { - assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"}); - } + @Test + void oneThrowable() { + assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"}); + } - @Test - public void testOneJPAndTwoThrowables() { - assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class, - "Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2"); - } + @Test + void oneJPAndOneThrowable() { + assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"}); + } - @Test - public void testThrowableNoCandidates() { - assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class, - "Not enough arguments in method to satisfy binding of returning and throwing variables"); - } + @Test + void oneJPAndTwoThrowables() { + assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class, + "Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2"); + } - @Test - public void testReturning() { - assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"}); - } + @Test + void throwableNoCandidates() { + assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class, + "Not enough arguments in method to satisfy binding of returning and throwing variables"); + } - @Test - public void testAmbiguousReturning() { - assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class, - "Binding of returning parameter 'obj' is ambiguous, there are 2 candidates."); - } + @Test + void returning() { + assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"}); + } - @Test - public void testReturningNoCandidates() { - assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class, - "Not enough arguments in method to satisfy binding of returning and throwing variables"); - } + @Test + void ambiguousReturning() { + assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class, + "Binding of returning parameter 'obj' is ambiguous, there are 2 candidates."); + } - @Test - public void testThisBindingOneCandidate() { - assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"}); - } + @Test + void returningNoCandidates() { + assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class, + "Not enough arguments in method to satisfy binding of returning and throwing variables"); + } - @Test - public void testThisBindingWithAlternateTokenizations() { - assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"}); - } + @Test + void thisBindingOneCandidate() { + assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"}); + } - @Test - public void testThisBindingTwoCandidates() { - assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class, - "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); - } + @Test + void thisBindingWithAlternateTokenizations() { + assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"}); + } - @Test - public void testThisBindingWithBadPointcutExpressions() { - assertException(getMethod("oneObject"), "this(", IllegalStateException.class, - "Failed to bind all argument names: 1 argument(s) could not be bound"); - assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class, - "Failed to bind all argument names: 1 argument(s) could not be bound"); - } + @Test + void thisBindingTwoCandidates() { + assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class, + "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); + } - @Test - public void testTargetBindingOneCandidate() { - assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"}); - } + @Test + void thisBindingWithBadPointcutExpressions() { + assertException(getMethod("oneObject"), "this(", IllegalStateException.class, + "Failed to bind all argument names: 1 argument(s) could not be bound"); + assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class, + "Failed to bind all argument names: 1 argument(s) could not be bound"); + } - @Test - public void testTargetBindingWithAlternateTokenizations() { - assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"}); - assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"}); - } + @Test + void targetBindingOneCandidate() { + assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"}); + } - @Test - public void testTargetBindingTwoCandidates() { - assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class, - "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); - } + @Test + void targetBindingWithAlternateTokenizations() { + assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"}); + assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"}); + } - @Test - public void testTargetBindingWithBadPointcutExpressions() { - assertException(getMethod("oneObject"), "target(", IllegalStateException.class, - "Failed to bind all argument names: 1 argument(s) could not be bound"); - assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class, - "Failed to bind all argument names: 1 argument(s) could not be bound"); - } + @Test + void targetBindingTwoCandidates() { + assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class, + "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); + } - @Test - public void testArgsBindingOneObject() { - assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"}); - } + @Test + void targetBindingWithBadPointcutExpressions() { + assertException(getMethod("oneObject"), "target(", IllegalStateException.class, + "Failed to bind all argument names: 1 argument(s) could not be bound"); + assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class, + "Failed to bind all argument names: 1 argument(s) could not be bound"); + } - @Test - public void testArgsBindingOneObjectTwoCandidates() { - assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class, - "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); - } + @Test + void argsBindingOneObject() { + assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"}); + } - @Test - public void testAmbiguousArgsBinding() { - assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class, - "Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them"); - } + @Test + void argsBindingOneObjectTwoCandidates() { + assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class, + "Found 2 candidate this(), target() or args() variables but only one unbound argument slot"); + } - @Test - public void testArgsOnePrimitive() { - assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"}); - } + @Test + void ambiguousArgsBinding() { + assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class, + "Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them"); + } - @Test - public void testArgsOnePrimitiveOneObject() { - assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class, - "Found 2 candidate variable names but only one candidate binding slot when matching primitive args"); - } + @Test + void argsOnePrimitive() { + assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"}); + } - @Test - public void testThisAndPrimitive() { - assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)", - new String[] {"obj", "count"}); - } + @Test + void argsOnePrimitiveOneObject() { + assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class, + "Found 2 candidate variable names but only one candidate binding slot when matching primitive args"); + } - @Test - public void testTargetAndPrimitive() { - assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)", - new String[] {"obj", "count"}); - } + @Test + void thisAndPrimitive() { + assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)", + new String[] {"obj", "count"}); + } - @Test - public void testThrowingAndPrimitive() { - assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex", - new String[] {"ex", "count"}); - } + @Test + void targetAndPrimitive() { + assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)", + new String[] {"obj", "count"}); + } - @Test - public void testAllTogetherNow() { - assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex", - new String[] {"thisJoinPoint", "ex", "x", "foo"}); - } + @Test + void throwingAndPrimitive() { + assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex", + new String[] {"ex", "count"}); + } + + @Test + void allTogetherNow() { + assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex", + new String[] {"thisJoinPoint", "ex", "x", "foo"}); + } - @Test - public void testReferenceBinding() { - assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"}); + @Test + void referenceBinding() { + assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"}); + } + + @Test + void referenceBindingWithAlternateTokenizations() { + assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"}); + assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"}); + assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"}); + } } - @Test - public void testReferenceBindingWithAlternateTokenizations() { - assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"}); - assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"}); - assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"}); + /** + * Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}. + */ + @Nested + class AnnotationTests { + + @Test + void atThis() { + assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"}); + } + + @Test + void atTarget() { + assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"}); + } + + @Test + void atArgs() { + assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"}); + } + + @Test + void atWithin() { + assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"}); + } + + @Test + void atWithincode() { + assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"}); + } + + @Test + void atAnnotation() { + assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"}); + } + + @Test + void ambiguousAnnotationTwoVars() { + assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class, + "Found 2 potential annotation variable(s), and 2 potential argument slots"); + } + + @Test + void ambiguousAnnotationOneVar() { + assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class, + "Found 2 candidate annotation binding variables but only one potential argument binding slot"); + } + + @Test + void annotationMedley() { + assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)", + null, "ex", new String[] {"ex", "foo", "count", "a"}); + } + + @Test + void annotationBinding() { + assertParameterNames(getMethod("pjpAndAnAnnotation"), + "execution(* *(..)) && @annotation(ann)", + new String[] {"thisJoinPoint","ann"}); + } + } - protected Method getMethod(String name) { + private Method getMethod(String name) { // Assumes no overloading of test methods... - Method[] candidates = getClass().getMethods(); - for (Method candidate : candidates) { + for (Method candidate : getClass().getMethods()) { if (candidate.getName().equals(name)) { return candidate; } @@ -228,11 +296,11 @@ public class AspectJAdviceParameterNameDiscovererTests { throw new AssertionError("Bad test specification, no method '" + name + "' found in test class"); } - protected void assertParameterNames(Method method, String pointcut, String[] parameterNames) { + private void assertParameterNames(Method method, String pointcut, String[] parameterNames) { assertParameterNames(method, pointcut, null, null, parameterNames); } - protected void assertParameterNames( + private void assertParameterNames( Method method, String pointcut, String returning, String throwing, String[] parameterNames) { assertThat(parameterNames.length).as("bad test specification, must have same number of parameter names as method arguments").isEqualTo(method.getParameterCount()); @@ -243,8 +311,8 @@ public class AspectJAdviceParameterNameDiscovererTests { discoverer.setThrowingName(throwing); String[] discoveredNames = discoverer.getParameterNames(method); - String formattedExpectedNames = format(parameterNames); - String formattedActualNames = format(discoveredNames); + String formattedExpectedNames = Arrays.toString(parameterNames); + String formattedActualNames = Arrays.toString(discoveredNames); assertThat(discoveredNames.length).as("Expecting " + parameterNames.length + " parameter names in return set '" + formattedExpectedNames + "', but found " + discoveredNames.length + @@ -257,37 +325,23 @@ public class AspectJAdviceParameterNameDiscovererTests { } } - protected void assertException(Method method, String pointcut, Class exceptionType, String message) { + private void assertException(Method method, String pointcut, Class exceptionType, String message) { assertException(method, pointcut, null, null, exceptionType, message); } - protected void assertException(Method method, String pointcut, String returning, + private void assertException(Method method, String pointcut, String returning, String throwing, Class exceptionType, String message) { AspectJAdviceParameterNameDiscoverer discoverer = new AspectJAdviceParameterNameDiscoverer(pointcut); discoverer.setRaiseExceptions(true); discoverer.setReturningName(returning); discoverer.setThrowingName(throwing); - assertThatExceptionOfType(exceptionType).isThrownBy(() -> - discoverer.getParameterNames(method)) + assertThatExceptionOfType(exceptionType) + .isThrownBy(() -> discoverer.getParameterNames(method)) .withMessageContaining(message); } - private static String format(String[] names) { - StringBuilder sb = new StringBuilder(); - sb.append('('); - for (int i = 0; i < names.length; i++) { - sb.append(names[i]); - if ((i + 1) < names.length) { - sb.append(','); - } - } - sb.append(')'); - return sb.toString(); - } - - // Methods to discover parameter names for public void noArgs() { @@ -329,4 +383,14 @@ public class AspectJAdviceParameterNameDiscovererTests { public void theBigOne(JoinPoint jp, Throwable x, int y, Object foo) { } + public void oneAnnotation(MyAnnotation ann) {} + + public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {} + + public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {} + + public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {} + + @interface MyAnnotation {} + } diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java index 20f3106c624..e1b2a93b958 100644 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -17,6 +17,9 @@ package org.springframework.aop.aspectj; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -25,6 +28,8 @@ import org.aspectj.weaver.tools.PointcutPrimitive; import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import test.annotation.EmptySpringAnnotation; +import test.annotation.transaction.Tx; import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodMatcher; @@ -56,12 +61,19 @@ public class AspectJExpressionPointcutTests { private Method setSomeNumber; + private final Map methodsOnHasGeneric = new HashMap<>(); + @BeforeEach public void setUp() throws NoSuchMethodException { getAge = TestBean.class.getMethod("getAge"); setAge = TestBean.class.getMethod("setAge", int.class); setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class); + + // Assumes no overloading + for (Method method : HasGeneric.class.getMethods()) { + methodsOnHasGeneric.put(method.getName(), method); + } } @@ -299,6 +311,279 @@ public class AspectJExpressionPointcutTests { } } + @Test + public void testMatchGenericArgument() { + String expression = "execution(* set*(java.util.List) )"; + AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); + ajexp.setExpression(expression); + + // TODO this will currently map, would be nice for optimization + //assertTrue(ajexp.matches(HasGeneric.class)); + //assertFalse(ajexp.matches(TestBean.class)); + + Method takesGenericList = methodsOnHasGeneric.get("setFriends"); + assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue(); + assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue(); + assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse(); + assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse(); + + assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); + } + + @Test + public void testMatchVarargs() throws Exception { + + @SuppressWarnings("unused") + class MyTemplate { + public int queryForInt(String sql, Object... params) { + return 0; + } + } + + String expression = "execution(int *.*(String, Object...))"; + AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut(); + jdbcVarArgs.setExpression(expression); + + assertThat(jdbcVarArgs.matches( + MyTemplate.class.getMethod("queryForInt", String.class, Object[].class), + MyTemplate.class)).isTrue(); + + Method takesGenericList = methodsOnHasGeneric.get("setFriends"); + assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse(); + assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse(); + assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse(); + assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse(); + assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse(); + } + + @Test + public void testMatchAnnotationOnClassWithAtWithin() throws Exception { + String expression = "@within(test.annotation.transaction.Tx)"; + testMatchAnnotationOnClass(expression); + } + + @Test + public void testMatchAnnotationOnClassWithoutBinding() throws Exception { + String expression = "within(@test.annotation.transaction.Tx *)"; + testMatchAnnotationOnClass(expression); + } + + @Test + public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception { + String expression = "within(@(test.annotation..*) *)"; + AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression); + assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse(); + assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue(); + + expression = "within(@(test.annotation.transaction..*) *)"; + AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression); + assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse(); + } + + @Test + public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception { + String expression = "within(@(test.annotation.transaction.*) *)"; + testMatchAnnotationOnClass(expression); + } + + private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception { + AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); + ajexp.setExpression(expression); + + assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); + assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue(); + assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue(); + assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue(); + assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + return ajexp; + } + + @Test + public void testAnnotationOnMethodWithFQN() throws Exception { + String expression = "@annotation(test.annotation.transaction.Tx)"; + AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); + ajexp.setExpression(expression); + + assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); + assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); + assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); + assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue(); + assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + } + + @Test + public void testAnnotationOnCglibProxyMethod() throws Exception { + String expression = "@annotation(test.annotation.transaction.Tx)"; + AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); + ajexp.setExpression(expression); + + ProxyFactory factory = new ProxyFactory(new BeanA()); + factory.setProxyTargetClass(true); + BeanA proxy = (BeanA) factory.getProxy(); + assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue(); + } + + @Test + public void testAnnotationOnDynamicProxyMethod() throws Exception { + String expression = "@annotation(test.annotation.transaction.Tx)"; + AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); + ajexp.setExpression(expression); + + ProxyFactory factory = new ProxyFactory(new BeanA()); + factory.setProxyTargetClass(false); + IBeanA proxy = (IBeanA) factory.getProxy(); + assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue(); + } + + @Test + public void testAnnotationOnMethodWithWildcard() throws Exception { + String expression = "execution(@(test.annotation..*) * *(..))"; + AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut(); + anySpringMethodAnnotation.setExpression(expression); + + assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse(); + assertThat(anySpringMethodAnnotation.matches( + HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); + assertThat(anySpringMethodAnnotation.matches( + HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); + assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue(); + assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + } + + @Test + public void testAnnotationOnMethodArgumentsWithFQN() throws Exception { + String expression = "@args(*, test.annotation.EmptySpringAnnotation))"; + AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut(); + takesSpringAnnotatedArgument2.setExpression(expression); + + assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches( + HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches( + HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + + assertThat(takesSpringAnnotatedArgument2.matches( + ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class), + ProcessesSpringAnnotatedParameters.class)).isTrue(); + + // True because it maybeMatches with potential argument subtypes + assertThat(takesSpringAnnotatedArgument2.matches( + ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), + ProcessesSpringAnnotatedParameters.class)).isTrue(); + + assertThat(takesSpringAnnotatedArgument2.matches( + ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), + ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse(); + } + + @Test + public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception { + String expression = "execution(* *(*, @(test..*) *))"; + AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut(); + takesSpringAnnotatedArgument2.setExpression(expression); + + assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches( + HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches( + HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse(); + assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); + + assertThat(takesSpringAnnotatedArgument2.matches( + ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class), + ProcessesSpringAnnotatedParameters.class)).isTrue(); + assertThat(takesSpringAnnotatedArgument2.matches( + ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), + ProcessesSpringAnnotatedParameters.class)).isFalse(); + } + + + public static class HasGeneric { + + public void setFriends(List friends) { + } + public void setEnemies(List enemies) { + } + public void setPartners(List partners) { + } + public void setPhoneNumbers(List numbers) { + } + } + + + public static class ProcessesSpringAnnotatedParameters { + + public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) { + } + + public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) { + } + } + + + @Tx + public static class HasTransactionalAnnotation { + + public void foo() { + } + public Object bar(String foo) { + throw new UnsupportedOperationException(); + } + } + + + @EmptySpringAnnotation + public static class SpringAnnotated { + + public void foo() { + } + } + + + interface IBeanA { + + @Tx + int getAge(); + } + + + static class BeanA implements IBeanA { + + @SuppressWarnings("unused") + private String name; + + private int age; + + public void setName(String name) { + this.name = name; + } + + @Tx + @Override + public int getAge() { + return age; + } + } + + + @Tx + static class BeanB { + + @SuppressWarnings("unused") + private String name; + + public void setName(String name) { + this.name = name; + } + } + } diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJAdviceParameterNameDiscovererTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJAdviceParameterNameDiscovererTests.java deleted file mode 100644 index 0cc3947260a..00000000000 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJAdviceParameterNameDiscovererTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2002-2017 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.aop.aspectj; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException; - -/** - * Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}; - * see supertype for remaining tests. - * - * @author Adrian Colyer - * @author Chris Beams - */ -public class TigerAspectJAdviceParameterNameDiscovererTests extends AspectJAdviceParameterNameDiscovererTests { - - @Test - public void testAtThis() { - assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"}); - } - - @Test - public void testAtTarget() { - assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"}); - } - - @Test - public void testAtArgs() { - assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"}); - } - - @Test - public void testAtWithin() { - assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"}); - } - - @Test - public void testAtWithincode() { - assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"}); - } - - @Test - public void testAtAnnotation() { - assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"}); - } - - @Test - public void testAmbiguousAnnotationTwoVars() { - assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class, - "Found 2 potential annotation variable(s), and 2 potential argument slots"); - } - - @Test - public void testAmbiguousAnnotationOneVar() { - assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class, - "Found 2 candidate annotation binding variables but only one potential argument binding slot"); - } - - @Test - public void testAnnotationMedley() { - assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)", - null, "ex", new String[] {"ex", "foo", "count", "a"}); - } - - - public void oneAnnotation(MyAnnotation ann) {} - - public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {} - - public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {} - - @interface MyAnnotation {} - -} diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJExpressionPointcutTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJExpressionPointcutTests.java deleted file mode 100644 index 23d63fb1bea..00000000000 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/TigerAspectJExpressionPointcutTests.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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.aop.aspectj; - -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import test.annotation.EmptySpringAnnotation; -import test.annotation.transaction.Tx; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.testfixture.beans.TestBean; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Java 5 specific {@link AspectJExpressionPointcutTests}. - * - * @author Rod Johnson - * @author Chris Beams - */ -public class TigerAspectJExpressionPointcutTests { - - private Method getAge; - - private final Map methodsOnHasGeneric = new HashMap<>(); - - - @BeforeEach - public void setup() throws NoSuchMethodException { - getAge = TestBean.class.getMethod("getAge"); - // Assumes no overloading - for (Method method : HasGeneric.class.getMethods()) { - methodsOnHasGeneric.put(method.getName(), method); - } - } - - - @Test - public void testMatchGenericArgument() { - String expression = "execution(* set*(java.util.List) )"; - AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); - ajexp.setExpression(expression); - - // TODO this will currently map, would be nice for optimization - //assertTrue(ajexp.matches(HasGeneric.class)); - //assertFalse(ajexp.matches(TestBean.class)); - - Method takesGenericList = methodsOnHasGeneric.get("setFriends"); - assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue(); - assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue(); - assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse(); - assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse(); - - assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); - } - - @Test - public void testMatchVarargs() throws Exception { - - @SuppressWarnings("unused") - class MyTemplate { - public int queryForInt(String sql, Object... params) { - return 0; - } - } - - String expression = "execution(int *.*(String, Object...))"; - AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut(); - jdbcVarArgs.setExpression(expression); - - assertThat(jdbcVarArgs.matches( - MyTemplate.class.getMethod("queryForInt", String.class, Object[].class), - MyTemplate.class)).isTrue(); - - Method takesGenericList = methodsOnHasGeneric.get("setFriends"); - assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse(); - assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse(); - assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse(); - assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse(); - assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse(); - } - - @Test - public void testMatchAnnotationOnClassWithAtWithin() throws Exception { - String expression = "@within(test.annotation.transaction.Tx)"; - testMatchAnnotationOnClass(expression); - } - - @Test - public void testMatchAnnotationOnClassWithoutBinding() throws Exception { - String expression = "within(@test.annotation.transaction.Tx *)"; - testMatchAnnotationOnClass(expression); - } - - @Test - public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception { - String expression = "within(@(test.annotation..*) *)"; - AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression); - assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse(); - assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue(); - - expression = "within(@(test.annotation.transaction..*) *)"; - AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression); - assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse(); - } - - @Test - public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception { - String expression = "within(@(test.annotation.transaction.*) *)"; - testMatchAnnotationOnClass(expression); - } - - private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception { - AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); - ajexp.setExpression(expression); - - assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); - assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue(); - assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue(); - assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue(); - assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - return ajexp; - } - - @Test - public void testAnnotationOnMethodWithFQN() throws Exception { - String expression = "@annotation(test.annotation.transaction.Tx)"; - AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); - ajexp.setExpression(expression); - - assertThat(ajexp.matches(getAge, TestBean.class)).isFalse(); - assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); - assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); - assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue(); - assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - } - - @Test - public void testAnnotationOnCglibProxyMethod() throws Exception { - String expression = "@annotation(test.annotation.transaction.Tx)"; - AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); - ajexp.setExpression(expression); - - ProxyFactory factory = new ProxyFactory(new BeanA()); - factory.setProxyTargetClass(true); - BeanA proxy = (BeanA) factory.getProxy(); - assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue(); - } - - @Test - public void testAnnotationOnDynamicProxyMethod() throws Exception { - String expression = "@annotation(test.annotation.transaction.Tx)"; - AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); - ajexp.setExpression(expression); - - ProxyFactory factory = new ProxyFactory(new BeanA()); - factory.setProxyTargetClass(false); - IBeanA proxy = (IBeanA) factory.getProxy(); - assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue(); - } - - @Test - public void testAnnotationOnMethodWithWildcard() throws Exception { - String expression = "execution(@(test.annotation..*) * *(..))"; - AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut(); - anySpringMethodAnnotation.setExpression(expression); - - assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse(); - assertThat(anySpringMethodAnnotation.matches( - HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); - assertThat(anySpringMethodAnnotation.matches( - HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); - assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue(); - assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - } - - @Test - public void testAnnotationOnMethodArgumentsWithFQN() throws Exception { - String expression = "@args(*, test.annotation.EmptySpringAnnotation))"; - AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut(); - takesSpringAnnotatedArgument2.setExpression(expression); - - assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches( - HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches( - HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - - assertThat(takesSpringAnnotatedArgument2.matches( - ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class), - ProcessesSpringAnnotatedParameters.class)).isTrue(); - - // True because it maybeMatches with potential argument subtypes - assertThat(takesSpringAnnotatedArgument2.matches( - ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), - ProcessesSpringAnnotatedParameters.class)).isTrue(); - - assertThat(takesSpringAnnotatedArgument2.matches( - ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), - ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse(); - } - - @Test - public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception { - String expression = "execution(* *(*, @(test..*) *))"; - AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut(); - takesSpringAnnotatedArgument2.setExpression(expression); - - assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches( - HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches( - HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse(); - assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse(); - - assertThat(takesSpringAnnotatedArgument2.matches( - ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class), - ProcessesSpringAnnotatedParameters.class)).isTrue(); - assertThat(takesSpringAnnotatedArgument2.matches( - ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class), - ProcessesSpringAnnotatedParameters.class)).isFalse(); - } - - - public static class HasGeneric { - - public void setFriends(List friends) { - } - public void setEnemies(List enemies) { - } - public void setPartners(List partners) { - } - public void setPhoneNumbers(List numbers) { - } - } - - - public static class ProcessesSpringAnnotatedParameters { - - public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) { - } - - public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) { - } - } - - - @Tx - public static class HasTransactionalAnnotation { - - public void foo() { - } - public Object bar(String foo) { - throw new UnsupportedOperationException(); - } - } - - - @EmptySpringAnnotation - public static class SpringAnnotated { - - public void foo() { - } - } - - - interface IBeanA { - - @Tx - int getAge(); - } - - - static class BeanA implements IBeanA { - - @SuppressWarnings("unused") - private String name; - - private int age; - - public void setName(String name) { - this.name = name; - } - - @Tx - @Override - public int getAge() { - return age; - } - } - - - @Tx - static class BeanB { - - @SuppressWarnings("unused") - private String name; - - public void setName(String name) { - this.name = name; - } - } - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java b/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java index d2667da96fd..1ec7cbaefeb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java +++ b/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java @@ -1,5 +1,5 @@ /** - * Support package for beans-style handling of Java 5 annotations. + * Support package for beans-style handling of annotations. */ @NonNullApi @NonNullFields diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java index a4cf5f314ce..58aa85c8cec 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -44,7 +44,7 @@ import org.springframework.util.Assert; /** * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation * that enforces required JavaBean properties to have been configured. - * Required bean properties are detected through a Java 5 annotation: + * Required bean properties are detected through an annotation: * by default, Spring's {@link Required} annotation. * *

The motivation for the existence of this BeanPostProcessor is to allow diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index ecfdf8f83a9..f632e8b49ee 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -105,7 +105,7 @@ import org.springframework.util.StringValueResolver; * *

The common annotations supported by this post-processor are available in * Java 6 (JDK 1.6) as well as in Java EE 5/6 (which provides a standalone jar for - * its common annotations as well, allowing for use in any Java 5 based application). + * its common annotations as well, allowing for use in any based application). * *

For default usage, resolving resource names as Spring bean names, * simply define the following in your application context: diff --git a/spring-context/src/main/java/org/springframework/jmx/export/naming/MetadataNamingStrategy.java b/spring-context/src/main/java/org/springframework/jmx/export/naming/MetadataNamingStrategy.java index 78c1fe2691c..c0a2c4d875e 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/naming/MetadataNamingStrategy.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/naming/MetadataNamingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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,7 +40,7 @@ import org.springframework.util.StringUtils; *

Uses the {@link JmxAttributeSource} strategy interface, so that * metadata can be read using any supported implementation. Out of the box, * {@link org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource} - * introspects a well-defined set of Java 5 annotations that come with Spring. + * introspects a well-defined set of annotations that come with Spring. * * @author Rob Harrop * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/package-info.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/package-info.java index e6fbc6ef261..e876e68edf2 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/package-info.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/package-info.java @@ -1,5 +1,5 @@ /** - * Java 5 annotation for asynchronous method execution. + * Annotation support for asynchronous method execution. */ @NonNullApi @NonNullFields diff --git a/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java b/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java index b37f390fe6f..5ec0a109e48 100644 --- a/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java +++ b/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -23,7 +23,6 @@ import org.springframework.lang.Nullable; /** * Subclass of {@link ModelMap} that implements the {@link Model} interface. - * Java 5 specific like the {@code Model} interface itself. * *

This is an implementation class exposed to handler methods by Spring MVC, typically via * a declaration of the {@link org.springframework.ui.Model} interface. There is no need to diff --git a/spring-context/src/main/java/org/springframework/ui/Model.java b/spring-context/src/main/java/org/springframework/ui/Model.java index 8e586ccd4c5..83cd2ee8bae 100644 --- a/spring-context/src/main/java/org/springframework/ui/Model.java +++ b/spring-context/src/main/java/org/springframework/ui/Model.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -22,9 +22,11 @@ import java.util.Map; import org.springframework.lang.Nullable; /** - * Java-5-specific interface that defines a holder for model attributes. - * Primarily designed for adding attributes to the model. - * Allows for accessing the overall model as a {@code java.util.Map}. + * Interface that defines a holder for model attributes. + * + *

Primarily designed for adding attributes to the model. + * + *

Allows for accessing the overall model as a {@code java.util.Map}. * * @author Juergen Hoeller * @since 2.5.1 diff --git a/spring-core/src/main/java/org/springframework/core/NestedIOException.java b/spring-core/src/main/java/org/springframework/core/NestedIOException.java index 37dbcf5afb3..235a0ae6236 100644 --- a/spring-core/src/main/java/org/springframework/core/NestedIOException.java +++ b/spring-core/src/main/java/org/springframework/core/NestedIOException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -24,8 +24,9 @@ import org.springframework.lang.Nullable; * Subclass of {@link IOException} that properly handles a root cause, * exposing the root cause just like NestedChecked/RuntimeException does. * - *

Proper root cause handling has not been added to standard IOException before - * Java 6, which is why we need to do it ourselves for Java 5 compatibility purposes. + *

Proper root cause handling was added to the standard {@code IOException} in + * Java 6, which is why Spring originally introduced {@code NestedIOException} + * for compatibility with versions prior to Java 6. * *

The similarity between this class and the NestedChecked/RuntimeException * class is unavoidable, as this class needs to derive from IOException. diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index 0c1cccf1d63..0df6e0ece4c 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -1244,7 +1244,7 @@ public abstract class ClassUtils { * target class may be {@code DefaultFoo}. In this case, the method may be * {@code DefaultFoo.bar()}. This enables attributes on that method to be found. *

NOTE: In contrast to {@link org.springframework.aop.support.AopUtils#getMostSpecificMethod}, - * this method does not resolve Java 5 bridge methods automatically. + * this method does not resolve bridge methods automatically. * Call {@link org.springframework.core.BridgeMethodResolver#findBridgedMethod} * if bridge method resolution is desirable (e.g. for obtaining metadata from * the original method definition). diff --git a/spring-core/src/main/java/org/springframework/util/TypeUtils.java b/spring-core/src/main/java/org/springframework/util/TypeUtils.java index 4a959aef52f..b4643c35571 100644 --- a/spring-core/src/main/java/org/springframework/util/TypeUtils.java +++ b/spring-core/src/main/java/org/springframework/util/TypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -24,8 +24,9 @@ import java.lang.reflect.WildcardType; import org.springframework.lang.Nullable; /** - * Utility to work with Java 5 generic type parameters. - * Mainly for internal use within the framework. + * Utility to work with generic type parameters. + * + *

Mainly for internal use within the framework. * * @author Ramnivas Laddad * @author Juergen Hoeller diff --git a/spring-oxm/src/main/java/org/springframework/oxm/GenericMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/GenericMarshaller.java index e88bf743306..530f53e5ee6 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/GenericMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/GenericMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2022 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. @@ -19,7 +19,7 @@ package org.springframework.oxm; import java.lang.reflect.Type; /** - * Subinterface of {@link Marshaller} that has support for Java 5 generics. + * Subinterface of {@link Marshaller} that has support for generics. * * @author Arjen Poutsma * @since 3.0.1 diff --git a/spring-oxm/src/main/java/org/springframework/oxm/GenericUnmarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/GenericUnmarshaller.java index ab25d8d81a1..e7c16a2c445 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/GenericUnmarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/GenericUnmarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2022 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. @@ -19,7 +19,7 @@ package org.springframework.oxm; import java.lang.reflect.Type; /** - * Subinterface of {@link Unmarshaller} that has support for Java 5 generics. + * Subinterface of {@link Unmarshaller} that has support for generics. * * @author Arjen Poutsma * @since 3.0.1 diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSource.java index 66b61096e2b..329f5342052 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -24,7 +24,7 @@ import org.springframework.lang.Nullable; * Strategy interface used by {@link TransactionInterceptor} for metadata retrieval. * *

Implementations know how to source transaction attributes, whether from configuration, - * metadata attributes at source level (such as Java 5 annotations), or anywhere else. + * metadata attributes at source level (such as annotations), or anywhere else. * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-web/src/main/java/org/springframework/http/HttpMethod.java b/spring-web/src/main/java/org/springframework/http/HttpMethod.java index b1039145cf4..7a09278f5c5 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpMethod.java +++ b/spring-web/src/main/java/org/springframework/http/HttpMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -22,7 +22,7 @@ import java.util.Map; import org.springframework.lang.Nullable; /** - * Java 5 enumeration of HTTP request methods. Intended for use + * Enumeration of HTTP request methods. Intended for use * with {@link org.springframework.http.client.ClientHttpRequest} * and {@link org.springframework.web.client.RestTemplate}. * diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMethod.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMethod.java index 3c7d700f5d1..bc95c85695d 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMethod.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2022 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. @@ -17,11 +17,11 @@ package org.springframework.web.bind.annotation; /** - * Java 5 enumeration of HTTP request methods. Intended for use with the + * Enumeration of HTTP request methods. Intended for use with the * {@link RequestMapping#method()} attribute of the {@link RequestMapping} annotation. * *

Note that, by default, {@link org.springframework.web.servlet.DispatcherServlet} - * supports GET, HEAD, POST, PUT, PATCH and DELETE only. DispatcherServlet will + * supports GET, HEAD, POST, PUT, PATCH, and DELETE only. DispatcherServlet will * process TRACE and OPTIONS with the default HttpServlet behavior unless explicitly * told to dispatch those request types as well: Check out the "dispatchOptionsRequest" * and "dispatchTraceRequest" properties, switching them to "true" if necessary. diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 1ef6724c198..e2b0d0df92e 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -1788,7 +1788,7 @@ a parent collection definition is redundant and does not result in the desired m [[beans-collection-elements-strongly-typed]] ===== Strongly-typed collection -With the introduction of generic types in Java 5, you can use strongly typed collections. +Thanks to Java's support for generic types, you can use strongly typed collections. That is, it is possible to declare a `Collection` type such that it can only contain (for example) `String` elements. If you use Spring to dependency-inject a strongly-typed `Collection` into a bean, you can take advantage of Spring's