mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cedb5874b7 | |||
| a7cf19cec5 | |||
| 0cf7f7bd89 | |||
| 949c3d450c | |||
| 3b4ae7b028 | |||
| 8b39698553 | |||
| 6fad00ed22 | |||
| 5f6d8df34b | |||
| 35de7e19ee | |||
| 10e979e58b | |||
| 4143b445d6 | |||
| eefdd2c768 | |||
| 9f91168396 | |||
| 7aed6279a2 | |||
| c3fe112fd7 | |||
| 90103b0ae9 | |||
| 0cf15c0fdd | |||
| 4e9af3e277 | |||
| 01fd489b47 | |||
| 270b167e08 | |||
| b158110801 | |||
| 17f7a24118 | |||
| d518a7d8c8 | |||
| 24cd3c1f4c | |||
| 2a8c369cff | |||
| 002546b3e4 | |||
| 1627f57f1f | |||
| 3811cd4c0a | |||
| d927e37364 | |||
| 1d302bf384 | |||
| 4b150fd451 | |||
| 3a6016d356 | |||
| 135506f672 | |||
| cb36ca31f6 | |||
| edd66d96dd | |||
| 35610a535d | |||
| acf2955b96 | |||
| 8fc744f4f4 | |||
| 9a5891e6e6 | |||
| 64b64d9ba0 | |||
| 1419172fbd | |||
| 420e0ba25f |
+12
-12
@@ -29,10 +29,10 @@ configure(allprojects) { project ->
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
|
||||
mavenBom "io.netty:netty-bom:4.1.75.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.18"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.2"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.46.v20220331"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
|
||||
@@ -96,7 +96,7 @@ configure(allprojects) { project ->
|
||||
|
||||
dependency "com.h2database:h2:2.1.210"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
|
||||
dependency "com.github.librepdf:openpdf:1.3.26"
|
||||
dependency "com.github.librepdf:openpdf:1.3.27"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
@@ -128,18 +128,18 @@ configure(allprojects) { project ->
|
||||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.62') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.62') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.17.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
|
||||
@@ -150,7 +150,7 @@ configure(allprojects) { project ->
|
||||
}
|
||||
}
|
||||
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.11"
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.60.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.60.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "9.3"
|
||||
toolVersion = "10.1"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220302
|
||||
FROM ubuntu:focal-20220404
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
|
||||
@@ -12,7 +12,7 @@ case "$1" in
|
||||
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
|
||||
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18%2B36/OpenJDK18U-jdk_x64_linux_hotspot_18_36.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
|
||||
@@ -41,6 +41,11 @@ anchors:
|
||||
GITHUB_TOKEN: ((github-ci-release-token))
|
||||
|
||||
resource_types:
|
||||
- name: registry-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/registry-image-resource
|
||||
tag: 1.5.0
|
||||
- name: artifactory-resource
|
||||
type: registry-image
|
||||
source:
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=5.3.17-SNAPSHOT
|
||||
version=5.3.19
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+3
-3
@@ -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.
|
||||
* <p>Re-resolved on deserialization since it isn't serializable itself.
|
||||
*/
|
||||
private transient AjType<?> ajType;
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ public abstract class AopProxyUtils {
|
||||
if (targetClass.isInterface()) {
|
||||
advised.setInterfaces(targetClass);
|
||||
}
|
||||
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
|
||||
else if (Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
advised.setInterfaces(targetClass.getInterfaces());
|
||||
}
|
||||
specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
@@ -245,18 +245,4 @@ public abstract class AopProxyUtils {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied {@link Class} is a JVM-generated implementation
|
||||
* class for a lambda expression or method reference.
|
||||
* <p>This method makes a best-effort attempt at determining this, based on
|
||||
* checks that work on modern, main stream JVMs.
|
||||
* @param clazz the class to check
|
||||
* @return {@code true} if the class is a lambda implementation class
|
||||
* @since 5.3.16
|
||||
*/
|
||||
static boolean isLambda(Class<?> clazz) {
|
||||
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
|
||||
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -375,6 +375,22 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
|
||||
* to a plain reflection invocation in case of a fast-class generation failure.
|
||||
*/
|
||||
@Nullable
|
||||
private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)
|
||||
throws Throwable {
|
||||
try {
|
||||
return methodProxy.invoke(target, args);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a return value. Wraps a return of {@code this} if necessary to be the
|
||||
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
||||
@@ -425,7 +441,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
@Override
|
||||
@Nullable
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
}
|
||||
@@ -450,7 +466,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object oldProxy = null;
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -478,7 +494,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -508,7 +524,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -685,13 +701,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// it does nothing but a reflective operation on the target, and no hot
|
||||
// swapping or fancy proxying.
|
||||
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
|
||||
try {
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
|
||||
}
|
||||
retVal = invokeMethod(target, method, argsToUse, methodProxy);
|
||||
}
|
||||
else {
|
||||
// We need to create a method invocation...
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.core.NativeDetector;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
|
||||
@@ -60,7 +61,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
"Either an interface or a target is required for proxy creation.");
|
||||
}
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
}
|
||||
return new ObjenesisCglibAopProxy(config);
|
||||
|
||||
+5
-3
@@ -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.
|
||||
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostP
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Sam Brannen
|
||||
* @since 13.10.2003
|
||||
* @see #setInterceptorNames
|
||||
* @see #getAdvicesAndAdvisorsForBean
|
||||
@@ -442,8 +444,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
proxyFactory.copyFrom(this);
|
||||
|
||||
if (proxyFactory.isProxyTargetClass()) {
|
||||
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass)) {
|
||||
// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
|
||||
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
|
||||
for (Class<?> ifc : beanClass.getInterfaces()) {
|
||||
proxyFactory.addInterface(ifc);
|
||||
|
||||
@@ -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.
|
||||
* <p><b>NOTE:</b> In contrast to {@link org.springframework.util.ClassUtils#getMostSpecificMethod},
|
||||
* this method resolves Java 5 bridge methods in order to retrieve attributes
|
||||
* from the <i>original</i> method definition.
|
||||
* this method resolves bridge methods in order to retrieve attributes from
|
||||
* the <i>original</i> 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.
|
||||
|
||||
+2
-3
@@ -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
|
||||
|
||||
+3
-4
@@ -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
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
-44
@@ -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 {}
|
||||
|
||||
}
|
||||
+259
-195
@@ -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.
|
||||
*
|
||||
* <p>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
|
||||
void noArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void twoJoinPoints() {
|
||||
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
|
||||
@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
|
||||
void throwableNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
|
||||
@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
|
||||
void thisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
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
|
||||
void targetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
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
|
||||
void argsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
void argsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"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
|
||||
void thisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@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
|
||||
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 testJoinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
/**
|
||||
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
*/
|
||||
@Nested
|
||||
class AnnotationTests {
|
||||
|
||||
@Test
|
||||
public void testJoinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
@Test
|
||||
void atThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@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 atTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
@Test
|
||||
void atArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
@Test
|
||||
void atWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@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 atWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@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 atAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
@Test
|
||||
void ambiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
|
||||
@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 ambiguousAnnotationOneVar() {
|
||||
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 testReturningNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
@Test
|
||||
void annotationMedley() {
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
@Test
|
||||
void annotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
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
|
||||
public void testTargetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
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
|
||||
public void testArgsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@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
|
||||
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
|
||||
public void testArgsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@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
|
||||
public void testThisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowingAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllTogetherNow() {
|
||||
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
|
||||
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"});
|
||||
}
|
||||
|
||||
|
||||
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<? extends Throwable> exceptionType, String message) {
|
||||
private void assertException(Method method, String pointcut, Class<? extends Throwable> 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<? extends Throwable> 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 {}
|
||||
|
||||
}
|
||||
|
||||
+286
-1
@@ -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<String, Method> 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<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
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<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
-89
@@ -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 {}
|
||||
|
||||
}
|
||||
-330
@@ -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<String, Method> 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<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
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<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.framework;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -134,61 +133,4 @@ public class AopProxyUtilsTests {
|
||||
AopProxyUtils.proxiedUserInterfaces(proxy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLambda() {
|
||||
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
|
||||
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
|
||||
|
||||
assertIsLambda(this.instanceLambdaExpression);
|
||||
assertIsLambda(this::instanceStringFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLambda() {
|
||||
assertIsNotLambda(new EnigmaSupplier());
|
||||
|
||||
assertIsNotLambda(new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return "anonymous inner class";
|
||||
}
|
||||
});
|
||||
|
||||
assertIsNotLambda(new Fake$$LambdaSupplier());
|
||||
}
|
||||
|
||||
private static void assertIsLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
|
||||
}
|
||||
|
||||
private static void assertIsNotLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
|
||||
}
|
||||
|
||||
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
|
||||
|
||||
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
|
||||
|
||||
private static String staticStringFactory() {
|
||||
return "static string factory";
|
||||
}
|
||||
|
||||
private String instanceStringFactory() {
|
||||
return "instance string factory";
|
||||
}
|
||||
|
||||
private static class EnigmaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "enigma";
|
||||
}
|
||||
}
|
||||
|
||||
private static class Fake$$LambdaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "fake lambda";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
-7
@@ -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.
|
||||
@@ -22,6 +22,7 @@ import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -286,9 +287,15 @@ public final class CachedIntrospectionResults {
|
||||
// This call is slow so we do it once.
|
||||
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (Class.class == beanClass &&
|
||||
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
|
||||
// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those
|
||||
if (Class.class == beanClass && !("name".equals(pd.getName()) ||
|
||||
(pd.getName().endsWith("Name") && String.class == pd.getPropertyType()))) {
|
||||
// Only allow all name variants of Class properties
|
||||
continue;
|
||||
}
|
||||
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
|
||||
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
|
||||
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
|
||||
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
|
||||
continue;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
@@ -337,6 +344,12 @@ public final class CachedIntrospectionResults {
|
||||
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
|
||||
// against a declared read method, so we prefer read method descriptors here.
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
|
||||
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
|
||||
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
|
||||
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
|
||||
continue;
|
||||
}
|
||||
this.propertyDescriptors.put(pd.getName(), pd);
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
@@ -354,7 +367,7 @@ public final class CachedIntrospectionResults {
|
||||
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (!this.propertyDescriptors.containsKey(method.getName()) &&
|
||||
!readMethodNames.contains((method.getName())) && isPlainAccessor(method)) {
|
||||
!readMethodNames.contains(method.getName()) && isPlainAccessor(method)) {
|
||||
this.propertyDescriptors.put(method.getName(),
|
||||
new GenericTypeAwarePropertyDescriptor(beanClass, method.getName(), method, null, null));
|
||||
readMethodNames.add(method.getName());
|
||||
@@ -363,8 +376,11 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
|
||||
private boolean isPlainAccessor(Method method) {
|
||||
if (method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())) {
|
||||
if (Modifier.isStatic(method.getModifiers()) ||
|
||||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
|
||||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
ClassLoader.class.isAssignableFrom(method.getReturnType()) ||
|
||||
ProtectionDomain.class.isAssignableFrom(method.getReturnType())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -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.
|
||||
@@ -23,8 +23,9 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Common interface for classes that can access named properties
|
||||
* (such as bean properties of an object or fields in an object)
|
||||
* Serves as base interface for {@link BeanWrapper}.
|
||||
* (such as bean properties of an object or fields in an object).
|
||||
*
|
||||
* <p>Serves as base interface for {@link BeanWrapper}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support package for beans-style handling of Java 5 annotations.
|
||||
* Support package for beans-style handling of annotations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+2
-2
@@ -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.
|
||||
*
|
||||
* <p>The motivation for the existence of this BeanPostProcessor is to allow
|
||||
|
||||
+7
-6
@@ -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.
|
||||
@@ -20,8 +20,8 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving a value through evaluating it
|
||||
* as an expression, if applicable.
|
||||
* Strategy interface for resolving a value by evaluating it as an expression,
|
||||
* if applicable.
|
||||
*
|
||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||
* contain a default implementation of this strategy. However,
|
||||
@@ -36,12 +36,13 @@ public interface BeanExpressionResolver {
|
||||
/**
|
||||
* Evaluate the given value as an expression, if applicable;
|
||||
* return the value as-is otherwise.
|
||||
* @param value the value to check
|
||||
* @param evalContext the evaluation context
|
||||
* @param value the value to evaluate as an expression
|
||||
* @param beanExpressionContext the bean expression context to use when
|
||||
* evaluating the expression
|
||||
* @return the resolved value (potentially the given value as-is)
|
||||
* @throws BeansException if evaluation failed
|
||||
*/
|
||||
@Nullable
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException;
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException;
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -23,6 +23,8 @@ import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
@@ -105,7 +107,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
.satisfies(ex -> assertThat(ex.getPossibleMatches()).containsExactly("age"));
|
||||
}
|
||||
|
||||
@Test // Can't be shared; there is no such thing as a read-only field
|
||||
@Test // Can't be shared; there is no such thing as a read-only field
|
||||
void setReadOnlyMapProperty() {
|
||||
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
|
||||
TypedReadOnlyMapClient target = new TypedReadOnlyMapClient();
|
||||
@@ -157,12 +159,34 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("name", "a");
|
||||
accessor.setPropertyValue("spouse.name", "b");
|
||||
|
||||
assertThat(target.getName()).isEqualTo("a");
|
||||
assertThat(target.getSpouse().getName()).isEqualTo("b");
|
||||
assertThat(accessor.getPropertyValue("name")).isEqualTo("a");
|
||||
assertThat(accessor.getPropertyValue("spouse.name")).isEqualTo("b");
|
||||
assertThat(accessor.getPropertyDescriptor("name").getPropertyType()).isEqualTo(String.class);
|
||||
assertThat(accessor.getPropertyDescriptor("spouse.name").getPropertyType()).isEqualTo(String.class);
|
||||
|
||||
assertThat(accessor.isReadableProperty("class.package")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.module")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.name")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
|
||||
assertThat(accessor.getPropertyValue("class.name")).isEqualTo(TestBean.class.getName());
|
||||
assertThat(accessor.getPropertyValue("class.simpleName")).isEqualTo(TestBean.class.getSimpleName());
|
||||
assertThat(accessor.getPropertyDescriptor("class.name").getPropertyType()).isEqualTo(String.class);
|
||||
assertThat(accessor.getPropertyDescriptor("class.simpleName").getPropertyType()).isEqualTo(String.class);
|
||||
|
||||
accessor = createAccessor(new DefaultResourceLoader());
|
||||
|
||||
assertThat(accessor.isReadableProperty("class.package")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.module")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("classLoader")).isTrue();
|
||||
assertThat(accessor.isWritableProperty("classLoader")).isTrue();
|
||||
OverridingClassLoader ocl = new OverridingClassLoader(getClass().getClassLoader());
|
||||
accessor.setPropertyValue("classLoader", ocl);
|
||||
assertThat(accessor.getPropertyValue("classLoader")).isSameAs(ocl);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+90
-28
@@ -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.
|
||||
@@ -31,6 +31,7 @@ import java.util.Set;
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.ConstraintValidatorFactory;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Payload;
|
||||
import javax.validation.Valid;
|
||||
@@ -43,6 +44,7 @@ import org.hibernate.validator.HibernateValidatorFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
@@ -52,18 +54,18 @@ import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class ValidatorFactoryTests {
|
||||
class ValidatorFactoryTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("cast")
|
||||
public void testSimpleValidation() {
|
||||
void simpleValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -78,15 +80,15 @@ public class ValidatorFactoryTests {
|
||||
|
||||
Validator nativeValidator = validator.unwrap(Validator.class);
|
||||
assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("cast")
|
||||
public void testSimpleValidationWithCustomProvider() {
|
||||
void simpleValidationWithCustomProvider() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setProviderClass(HibernateValidator.class);
|
||||
validator.afterPropertiesSet();
|
||||
@@ -102,14 +104,15 @@ public class ValidatorFactoryTests {
|
||||
|
||||
Validator nativeValidator = validator.unwrap(Validator.class);
|
||||
assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleValidationWithClassLevel() {
|
||||
void simpleValidationWithClassLevel() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -122,10 +125,13 @@ public class ValidatorFactoryTests {
|
||||
ConstraintViolation<?> cv = iterator.next();
|
||||
assertThat(cv.getPropertyPath().toString()).isEqualTo("");
|
||||
assertThat(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidationFieldType() {
|
||||
void springValidationFieldType() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -135,11 +141,16 @@ public class ValidatorFactoryTests {
|
||||
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(person, "person");
|
||||
validator.validate(person, errors);
|
||||
assertThat(errors.getErrorCount()).isEqualTo(1);
|
||||
assertThat(errors.getFieldError("address").getRejectedValue()).isInstanceOf(ValidAddress.class);
|
||||
assertThat(errors.getFieldError("address").getRejectedValue())
|
||||
.as("Field/Value type mismatch")
|
||||
.isInstanceOf(ValidAddress.class);
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidation() {
|
||||
void springValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -164,10 +175,13 @@ public class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.contains("NotNull.street")).isTrue();
|
||||
assertThat(errorCodes.contains("NotNull.java.lang.String")).isTrue();
|
||||
assertThat(errorCodes.contains("NotNull")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidationWithClassLevel() {
|
||||
void springValidationWithClassLevel() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -182,10 +196,12 @@ public class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.size()).isEqualTo(2);
|
||||
assertThat(errorCodes.contains("NameAddressValid.person")).isTrue();
|
||||
assertThat(errorCodes.contains("NameAddressValid")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidationWithAutowiredValidator() {
|
||||
void springValidationWithAutowiredValidator() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LocalValidatorFactoryBean.class);
|
||||
LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class);
|
||||
@@ -202,11 +218,14 @@ public class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.size()).isEqualTo(2);
|
||||
assertThat(errorCodes.contains("NameAddressValid.person")).isTrue();
|
||||
assertThat(errorCodes.contains("NameAddressValid")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidationWithErrorInListElement() {
|
||||
void springValidationWithErrorInListElement() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -221,10 +240,13 @@ public class ValidatorFactoryTests {
|
||||
assertThat(fieldError.getField()).isEqualTo("address.street");
|
||||
fieldError = result.getFieldError("addressList[0].street");
|
||||
assertThat(fieldError.getField()).isEqualTo("addressList[0].street");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringValidationWithErrorInSetElement() {
|
||||
void springValidationWithErrorInSetElement() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -239,10 +261,13 @@ public class ValidatorFactoryTests {
|
||||
assertThat(fieldError.getField()).isEqualTo("address.street");
|
||||
fieldError = result.getFieldError("addressSet[].street");
|
||||
assertThat(fieldError.getField()).isEqualTo("addressSet[].street");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInnerBeanValidation() {
|
||||
void innerBeanValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -251,10 +276,13 @@ public class ValidatorFactoryTests {
|
||||
validator.validate(mainBean, errors);
|
||||
Object rejected = errors.getFieldValue("inner.value");
|
||||
assertThat(rejected).isNull();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidationWithOptionalField() {
|
||||
void validationWithOptionalField() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -263,10 +291,13 @@ public class ValidatorFactoryTests {
|
||||
validator.validate(mainBean, errors);
|
||||
Object rejected = errors.getFieldValue("inner.value");
|
||||
assertThat(rejected).isNull();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListValidation() {
|
||||
void listValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -282,6 +313,34 @@ public class ValidatorFactoryTests {
|
||||
assertThat(fieldError).isNotNull();
|
||||
assertThat(fieldError.getRejectedValue()).isEqualTo("X");
|
||||
assertThat(errors.getFieldValue("list[1]")).isEqualTo("X");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withConstraintValidatorFactory() {
|
||||
ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory(new DefaultListableBeanFactory());
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setConstraintValidatorFactory(cvf);
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
assertThat(validator.getConstraintValidatorFactory()).isSameAs(cvf);
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withCustomInitializer() {
|
||||
ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory(new DefaultListableBeanFactory());
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setConfigurationInitializer(configuration -> configuration.constraintValidatorFactory(cvf));
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
assertThat(validator.getConstraintValidatorFactory()).isSameAs(cvf);
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -380,8 +439,8 @@ public class ValidatorFactoryTests {
|
||||
}
|
||||
boolean valid = (value.name == null || !value.address.street.contains(value.name));
|
||||
if (!valid && "Phil".equals(value.name)) {
|
||||
context.buildConstraintViolationWithTemplate(
|
||||
context.getDefaultConstraintMessageTemplate()).addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
|
||||
.addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation();
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@@ -417,6 +476,7 @@ public class ValidatorFactoryTests {
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
@@ -425,8 +485,8 @@ public class ValidatorFactoryTests {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Constraint(validatedBy=InnerValidator.class)
|
||||
public static @interface InnerValid {
|
||||
@Constraint(validatedBy = InnerValidator.class)
|
||||
public @interface InnerValid {
|
||||
|
||||
String message() default "NOT VALID";
|
||||
|
||||
@@ -446,7 +506,8 @@ public class ValidatorFactoryTests {
|
||||
public boolean isValid(InnerBean bean, ConstraintValidatorContext context) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
if (bean.getValue() == null) {
|
||||
context.buildConstraintViolationWithTemplate("NULL").addPropertyNode("value").addConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("NULL")
|
||||
.addPropertyNode("value").addConstraintViolation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -494,7 +555,8 @@ public class ValidatorFactoryTests {
|
||||
boolean valid = true;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if ("X".equals(list.get(i))) {
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addBeanNode().inIterable().atIndex(i).addConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
|
||||
.addBeanNode().inIterable().atIndex(i).addConstraintViolation();
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ import org.springframework.util.StringValueResolver;
|
||||
*
|
||||
* <p>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).
|
||||
*
|
||||
* <p>For default usage, resolving resource names as Spring bean names,
|
||||
* simply define the following in your application context:
|
||||
|
||||
+7
-7
@@ -138,7 +138,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {
|
||||
public Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException {
|
||||
if (!StringUtils.hasLength(value)) {
|
||||
return value;
|
||||
}
|
||||
@@ -148,21 +148,21 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
||||
this.expressionCache.put(value, expr);
|
||||
}
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(beanExpressionContext);
|
||||
if (sec == null) {
|
||||
sec = new StandardEvaluationContext(evalContext);
|
||||
sec = new StandardEvaluationContext(beanExpressionContext);
|
||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
sec.addPropertyAccessor(new EnvironmentAccessor());
|
||||
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||
sec.setBeanResolver(new BeanFactoryResolver(beanExpressionContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(beanExpressionContext.getBeanFactory().getBeanClassLoader()));
|
||||
sec.setTypeConverter(new StandardTypeConverter(() -> {
|
||||
ConversionService cs = evalContext.getBeanFactory().getConversionService();
|
||||
ConversionService cs = beanExpressionContext.getBeanFactory().getConversionService();
|
||||
return (cs != null ? cs : DefaultConversionService.getSharedInstance());
|
||||
}));
|
||||
customizeEvaluationContext(sec);
|
||||
this.evaluationCache.put(evalContext, sec);
|
||||
this.evaluationCache.put(beanExpressionContext, sec);
|
||||
}
|
||||
return expr.getValue(sec);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -46,7 +46,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* Implementation of the {@code JmxAttributeSource} interface that
|
||||
* Implementation of the {@link JmxAttributeSource} interface that
|
||||
* reads annotations and exposes the corresponding attributes.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -23,7 +23,7 @@ import org.springframework.jmx.export.naming.MetadataNamingStrategy;
|
||||
|
||||
/**
|
||||
* Convenient subclass of Spring's standard {@link MBeanExporter},
|
||||
* activating Java 5 annotation usage for JMX exposure of Spring beans:
|
||||
* activating annotation usage for JMX exposure of Spring beans:
|
||||
* {@link ManagedResource}, {@link ManagedAttribute}, {@link ManagedOperation}, etc.
|
||||
*
|
||||
* <p>Sets a {@link MetadataNamingStrategy} and a {@link MetadataMBeanInfoAssembler}
|
||||
|
||||
+2
-1
@@ -27,7 +27,8 @@ import org.springframework.jmx.support.MetricType;
|
||||
/**
|
||||
* Method-level annotation that indicates to expose a given bean property as a
|
||||
* JMX attribute, with added descriptor properties to indicate that it is a metric.
|
||||
* Only valid when used on a JavaBean getter.
|
||||
*
|
||||
* <p>Only valid when used on a JavaBean getter.
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
* @since 3.0
|
||||
|
||||
+4
-2
@@ -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.
|
||||
@@ -27,10 +27,12 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Type-level annotation that indicates a JMX notification emitted by a bean.
|
||||
*
|
||||
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
|
||||
* <p>This annotation is a {@linkplain java.lang.annotation.Repeatable repeatable}
|
||||
* annotation.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
* @see ManagedNotifications
|
||||
* @see org.springframework.jmx.export.metadata.ManagedNotification
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
+7
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Type-level annotation that indicates JMX notifications emitted by a bean,
|
||||
* containing multiple {@link ManagedNotification ManagedNotifications}.
|
||||
* Type-level annotation used as a container for one or more
|
||||
* {@code @ManagedNotification} declarations.
|
||||
*
|
||||
* <p>Note, however, that use of the {@code @ManagedNotifications} container
|
||||
* is completely optional since {@code @ManagedNotification} is a
|
||||
* {@linkplain java.lang.annotation.Repeatable repeatable} annotation.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
|
||||
+6
-4
@@ -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.
|
||||
@@ -23,9 +23,11 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation that indicates to expose a given method as a
|
||||
* JMX operation, corresponding to the {@code ManagedOperation} attribute.
|
||||
* Only valid when used on a method that is not a JavaBean getter or setter.
|
||||
* Method-level annotation that indicates to expose a given method as a JMX operation,
|
||||
* corresponding to the {@link org.springframework.jmx.export.metadata.ManagedOperation}
|
||||
* attribute.
|
||||
*
|
||||
* <p>Only valid when used on a method that is not a JavaBean getter or setter.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
|
||||
+6
-6
@@ -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.
|
||||
@@ -24,15 +24,15 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation used to provide metadata about operation parameters,
|
||||
* corresponding to a {@code ManagedOperationParameter} attribute.
|
||||
* Used as part of a {@link ManagedOperationParameters} annotation.
|
||||
* Method-level annotation used to provide metadata about operation parameters, corresponding
|
||||
* to a {@link org.springframework.jmx.export.metadata.ManagedOperationParameter} attribute.
|
||||
*
|
||||
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
|
||||
* <p>This annotation is a {@linkplain java.lang.annotation.Repeatable repeatable}
|
||||
* annotation.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
* @see ManagedOperationParameters#value
|
||||
* @see ManagedOperationParameters
|
||||
* @see org.springframework.jmx.export.metadata.ManagedOperationParameter
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
|
||||
+7
-3
@@ -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.
|
||||
@@ -23,8 +23,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation used to provide metadata about operation parameters,
|
||||
* corresponding to an array of {@code ManagedOperationParameter} attributes.
|
||||
* Method-level annotation used as a container for one or more
|
||||
* {@code @ManagedOperationParameter} declarations.
|
||||
*
|
||||
* <p>Note, however, that use of the {@code @ManagedOperationParameters} container
|
||||
* is completely optional since {@code @ManagedOperationParameter} is a
|
||||
* {@linkplain java.lang.annotation.Repeatable repeatable} annotation.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
|
||||
+3
-3
@@ -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.
|
||||
@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
/**
|
||||
* Class-level annotation that indicates to register instances of a class
|
||||
* with a JMX server, corresponding to the {@code ManagedResource} attribute.
|
||||
* Class-level annotation that indicates to register instances of a class with a JMX server,
|
||||
* corresponding to the {@link org.springframework.jmx.export.metadata.ManagedResource} attribute.
|
||||
*
|
||||
* <p><b>Note:</b> This annotation is marked as inherited, allowing for generic
|
||||
* management-aware base classes. In such a scenario, it is recommended to
|
||||
|
||||
+4
-3
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Java 5 annotations for MBean exposure.
|
||||
* Hooked into Spring's JMX export infrastructure
|
||||
* via a special JmxAttributeSource implementation.
|
||||
* Annotations for MBean exposure.
|
||||
*
|
||||
* <p>Hooked into Spring's JMX export infrastructure via a special
|
||||
* {@link org.springframework.jmx.export.metadata.JmxAttributeSource} implementation.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+2
-2
@@ -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;
|
||||
* <p>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
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Java 5 annotation for asynchronous method execution.
|
||||
* Annotation support for asynchronous method execution.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+16
-2
@@ -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.
|
||||
@@ -29,6 +29,7 @@ import org.springframework.lang.Nullable;
|
||||
* @see ScheduledTaskRegistrar#scheduleCronTask(CronTask)
|
||||
* @see ScheduledTaskRegistrar#scheduleFixedRateTask(FixedRateTask)
|
||||
* @see ScheduledTaskRegistrar#scheduleFixedDelayTask(FixedDelayTask)
|
||||
* @see ScheduledFuture
|
||||
*/
|
||||
public final class ScheduledTask {
|
||||
|
||||
@@ -54,11 +55,24 @@ public final class ScheduledTask {
|
||||
|
||||
/**
|
||||
* Trigger cancellation of this scheduled task.
|
||||
* <p>This variant will force interruption of the task if still running.
|
||||
* @see #cancel(boolean)
|
||||
*/
|
||||
public void cancel() {
|
||||
cancel(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger cancellation of this scheduled task.
|
||||
* @param mayInterruptIfRunning whether to force interruption of the task
|
||||
* if still running (specify {@code false} to allow the task to complete)
|
||||
* @since 5.3.18
|
||||
* @see ScheduledFuture#cancel(boolean)
|
||||
*/
|
||||
public void cancel(boolean mayInterruptIfRunning) {
|
||||
ScheduledFuture<?> future = this.future;
|
||||
if (future != null) {
|
||||
future.cancel(true);
|
||||
future.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>Primarily designed for adding attributes to the model.
|
||||
*
|
||||
* <p>Allows for accessing the overall model as a {@code java.util.Map}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.1
|
||||
|
||||
@@ -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.
|
||||
@@ -51,18 +51,20 @@ import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Binder that allows for setting property values onto a target object,
|
||||
* including support for validation and binding result analysis.
|
||||
* The binding process can be customized through specifying allowed fields,
|
||||
* Binder that allows for setting property values on a target object, including
|
||||
* support for validation and binding result analysis.
|
||||
*
|
||||
* <p>The binding process can be customized by specifying allowed field patterns,
|
||||
* required fields, custom editors, etc.
|
||||
*
|
||||
* <p>Note that there are potential security implications in failing to set an array
|
||||
* of allowed fields. In the case of HTTP form POST data for example, malicious clients
|
||||
* can attempt to subvert an application by supplying values for fields or properties
|
||||
* that do not exist on the form. In some cases this could lead to illegal data being
|
||||
* set on command objects <i>or their nested objects</i>. For this reason, it is
|
||||
* <b>highly recommended to specify the {@link #setAllowedFields allowedFields} property</b>
|
||||
* on the DataBinder.
|
||||
* <p><strong>WARNING</strong>: Data binding can lead to security issues by exposing
|
||||
* parts of the object graph that are not meant to be accessed or modified by
|
||||
* external clients. Therefore the design and use of data binding should be considered
|
||||
* carefully with regard to security. For more details, please refer to the dedicated
|
||||
* sections on data binding for
|
||||
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder-model-design">Spring Web MVC</a> and
|
||||
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-ann-initbinder-model-design">Spring WebFlux</a>
|
||||
* in the reference manual.
|
||||
*
|
||||
* <p>The binding results can be examined via the {@link BindingResult} interface,
|
||||
* extending the {@link Errors} interface: see the {@link #getBindingResult()} method.
|
||||
@@ -96,6 +98,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Rob Harrop
|
||||
* @author Stephane Nicoll
|
||||
* @author Kazuki Shimizu
|
||||
* @author Sam Brannen
|
||||
* @see #setAllowedFields
|
||||
* @see #setRequiredFields
|
||||
* @see #registerCustomEditor
|
||||
@@ -418,15 +421,21 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register fields that should be allowed for binding. Default is all fields.
|
||||
* Restrict this for example to avoid unwanted modifications by malicious
|
||||
* Register field patterns that should be allowed for binding.
|
||||
* <p>Default is all fields.
|
||||
* <p>Restrict this for example to avoid unwanted modifications by malicious
|
||||
* users when binding HTTP request parameters.
|
||||
* <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
|
||||
* arbitrary number of pattern parts), as well as direct equality. More
|
||||
* sophisticated matching can be implemented by overriding the
|
||||
* {@code isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>disallowed</i> fields.
|
||||
* @param allowedFields array of field names
|
||||
* <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality.
|
||||
* <p>The default implementation of this method stores allowed field patterns
|
||||
* in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
|
||||
* form. Subclasses which override this method must therefore take this into
|
||||
* account.
|
||||
* <p>More sophisticated matching can be implemented by overriding the
|
||||
* {@link #isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>disallowed</i> field patterns.
|
||||
* @param allowedFields array of allowed field patterns
|
||||
* @see #setDisallowedFields
|
||||
* @see #isAllowed(String)
|
||||
*/
|
||||
@@ -435,8 +444,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fields that should be allowed for binding.
|
||||
* @return array of field names
|
||||
* Return the field patterns that should be allowed for binding.
|
||||
* @return array of allowed field patterns
|
||||
* @see #setAllowedFields(String...)
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getAllowedFields() {
|
||||
@@ -444,25 +454,44 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register fields that should <i>not</i> be allowed for binding. Default
|
||||
* is none. Mark fields as disallowed for example to avoid unwanted
|
||||
* Register field patterns that should <i>not</i> be allowed for binding.
|
||||
* <p>Default is none.
|
||||
* <p>Mark fields as disallowed, for example to avoid unwanted
|
||||
* modifications by malicious users when binding HTTP request parameters.
|
||||
* <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
|
||||
* arbitrary number of pattern parts), as well as direct equality.
|
||||
* More sophisticated matching can be implemented by overriding the
|
||||
* {@code isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>allowed</i> fields.
|
||||
* @param disallowedFields array of field names
|
||||
* <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality.
|
||||
* <p>The default implementation of this method stores disallowed field patterns
|
||||
* in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
|
||||
* form. As of Spring Framework 5.2.21, the default implementation also transforms
|
||||
* disallowed field patterns to {@linkplain String#toLowerCase() lowercase} to
|
||||
* support case-insensitive pattern matching in {@link #isAllowed}. Subclasses
|
||||
* which override this method must therefore take both of these transformations
|
||||
* into account.
|
||||
* <p>More sophisticated matching can be implemented by overriding the
|
||||
* {@link #isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>allowed</i> field patterns.
|
||||
* @param disallowedFields array of disallowed field patterns
|
||||
* @see #setAllowedFields
|
||||
* @see #isAllowed(String)
|
||||
*/
|
||||
public void setDisallowedFields(@Nullable String... disallowedFields) {
|
||||
this.disallowedFields = PropertyAccessorUtils.canonicalPropertyNames(disallowedFields);
|
||||
if (disallowedFields == null) {
|
||||
this.disallowedFields = null;
|
||||
}
|
||||
else {
|
||||
String[] fieldPatterns = new String[disallowedFields.length];
|
||||
for (int i = 0; i < fieldPatterns.length; i++) {
|
||||
fieldPatterns[i] = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]).toLowerCase();
|
||||
}
|
||||
this.disallowedFields = fieldPatterns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fields that should <i>not</i> be allowed for binding.
|
||||
* @return array of field names
|
||||
* Return the field patterns that should <i>not</i> be allowed for binding.
|
||||
* @return array of disallowed field patterns
|
||||
* @see #setDisallowedFields(String...)
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getDisallowedFields() {
|
||||
@@ -774,16 +803,20 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the given field is allowed for binding.
|
||||
* Invoked for each passed-in property value.
|
||||
* <p>The default implementation checks for "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
|
||||
* matches (with an arbitrary number of pattern parts), as well as direct equality,
|
||||
* in the specified lists of allowed fields and disallowed fields. A field matching
|
||||
* a disallowed pattern will not be accepted even if it also happens to match a
|
||||
* pattern in the allowed list.
|
||||
* <p>Can be overridden in subclasses.
|
||||
* Determine if the given field is allowed for binding.
|
||||
* <p>Invoked for each passed-in property value.
|
||||
* <p>Checks for {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality, in the configured lists of allowed field patterns
|
||||
* and disallowed field patterns.
|
||||
* <p>Matching against allowed field patterns is case-sensitive; whereas,
|
||||
* matching against disallowed field patterns is case-insensitive.
|
||||
* <p>A field matching a disallowed pattern will not be accepted even if it
|
||||
* also happens to match a pattern in the allowed list.
|
||||
* <p>Can be overridden in subclasses, but care must be taken to honor the
|
||||
* aforementioned contract.
|
||||
* @param field the field to check
|
||||
* @return if the field is allowed
|
||||
* @return {@code true} if the field is allowed
|
||||
* @see #setAllowedFields
|
||||
* @see #setDisallowedFields
|
||||
* @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String)
|
||||
@@ -792,7 +825,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
String[] allowed = getAllowedFields();
|
||||
String[] disallowed = getDisallowedFields();
|
||||
return ((ObjectUtils.isEmpty(allowed) || PatternMatchUtils.simpleMatch(allowed, field)) &&
|
||||
(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field)));
|
||||
(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field.toLowerCase())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+20
-1
@@ -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.
|
||||
@@ -26,6 +26,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.validation.Configuration;
|
||||
import javax.validation.ConstraintValidatorFactory;
|
||||
@@ -113,6 +114,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
|
||||
private final Map<String, String> validationPropertyMap = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
private Consumer<Configuration<?>> configurationInitializer;
|
||||
|
||||
@Nullable
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@@ -234,6 +238,18 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
return this.validationPropertyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a callback for customizing the Bean Validation {@code Configuration} instance,
|
||||
* as an alternative to overriding the {@link #postProcessConfiguration(Configuration)}
|
||||
* method in custom {@code LocalValidatorFactoryBean} subclasses.
|
||||
* <p>This enables convenient customizations for application purposes. Infrastructure
|
||||
* extensions may keep overriding the {@link #postProcessConfiguration} template method.
|
||||
* @since 5.3.19
|
||||
*/
|
||||
public void setConfigurationInitializer(Consumer<Configuration<?>> configurationInitializer) {
|
||||
this.configurationInitializer = configurationInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
@@ -312,6 +328,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
this.validationPropertyMap.forEach(configuration::addProperty);
|
||||
|
||||
// Allow for custom post-processing before we actually build the ValidatorFactory.
|
||||
if (this.configurationInitializer != null) {
|
||||
this.configurationInitializer.accept(configuration);
|
||||
}
|
||||
postProcessConfiguration(configuration);
|
||||
|
||||
try {
|
||||
|
||||
+18
-11
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -37,7 +38,9 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AfterAdviceBindingTests {
|
||||
class AfterAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private AdviceBindingCollaborator mockCollaborator;
|
||||
|
||||
@@ -47,9 +50,8 @@ public class AfterAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() throws Exception {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
AdviceBindingTestAspect afterAdviceAspect = (AdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
|
||||
testBeanProxy = (ITestBean) ctx.getBean("testBean");
|
||||
@@ -62,39 +64,44 @@ public class AfterAdviceBindingTests {
|
||||
afterAdviceAspect.setCollaborator(mockCollaborator);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOneIntArg() {
|
||||
void oneIntArg() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntArg(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneObjectArgBindingProxyWithThis() {
|
||||
void oneObjectArgBindingProxyWithThis() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneObjectArgBindingTarget() {
|
||||
void oneObjectArgBindingTarget() {
|
||||
testBeanProxy.getDoctor();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneIntAndOneObjectArgs() {
|
||||
void oneIntAndOneObjectArgs() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntAndOneObject(5,this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPoint() {
|
||||
void needsJoinPoint() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPoint("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPointStaticPart() {
|
||||
void needsJoinPointStaticPart() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPointStaticPart("getAge");
|
||||
}
|
||||
|
||||
+24
-17
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -39,7 +40,9 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AfterReturningAdviceBindingTests {
|
||||
class AfterReturningAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private AfterReturningAdviceBindingTestAspect afterAdviceAspect;
|
||||
|
||||
@@ -51,9 +54,8 @@ public class AfterReturningAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() throws Exception {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
afterAdviceAspect = (AfterReturningAdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
|
||||
@@ -67,58 +69,63 @@ public class AfterReturningAdviceBindingTests {
|
||||
this.testBeanTarget = (TestBean) ((Advised)testBeanProxy).getTargetSource().getTarget();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOneIntArg() {
|
||||
void oneIntArg() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntArg(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneObjectArg() {
|
||||
void oneObjectArg() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneIntAndOneObjectArgs() {
|
||||
void oneIntAndOneObjectArgs() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntAndOneObject(5,this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPoint() {
|
||||
void needsJoinPoint() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPoint("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPointStaticPart() {
|
||||
void needsJoinPointStaticPart() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPointStaticPart("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningString() {
|
||||
void returningString() {
|
||||
testBeanProxy.setName("adrian");
|
||||
testBeanProxy.getName();
|
||||
verify(mockCollaborator).oneString("adrian");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningObject() {
|
||||
void returningObject() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningBean() {
|
||||
void returningBean() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).oneTestBeanArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningBeanArray() {
|
||||
void returningBeanArray() {
|
||||
this.testBeanTarget.setSpouse(new TestBean());
|
||||
ITestBean[] spouses = this.testBeanTarget.getSpouses();
|
||||
testBeanProxy.getSpouses();
|
||||
@@ -126,20 +133,20 @@ public class AfterReturningAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoInvokeWhenReturningParameterTypeDoesNotMatch() {
|
||||
void noInvokeWhenReturningParameterTypeDoesNotMatch() {
|
||||
testBeanProxy.setSpouse(this.testBeanProxy);
|
||||
testBeanProxy.getSpouse();
|
||||
verifyNoInteractions(mockCollaborator);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningByType() {
|
||||
void returningByType() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).objectMatchNoArgs();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningPrimitive() {
|
||||
void returningPrimitive() {
|
||||
testBeanProxy.setAge(20);
|
||||
testBeanProxy.haveBirthday();
|
||||
verify(mockCollaborator).oneInt(20);
|
||||
|
||||
+18
-11
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -33,7 +34,9 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AfterThrowingAdviceBindingTests {
|
||||
class AfterThrowingAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private ITestBean testBean;
|
||||
|
||||
@@ -43,9 +46,8 @@ public class AfterThrowingAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
afterThrowingAdviceAspect = (AfterThrowingAdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
@@ -54,16 +56,21 @@ public class AfterThrowingAdviceBindingTests {
|
||||
afterThrowingAdviceAspect.setCollaborator(mockCollaborator);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimpleAfterThrowing() throws Throwable {
|
||||
void simpleAfterThrowing() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new Throwable()));
|
||||
verify(mockCollaborator).noArgs();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterThrowingWithBinding() throws Throwable {
|
||||
void afterThrowingWithBinding() throws Throwable {
|
||||
Throwable t = new Throwable();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(t));
|
||||
@@ -71,7 +78,7 @@ public class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterThrowingWithNamedTypeRestriction() throws Throwable {
|
||||
void afterThrowingWithNamedTypeRestriction() throws Throwable {
|
||||
Throwable t = new Throwable();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(t));
|
||||
@@ -81,7 +88,7 @@ public class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterThrowingWithRuntimeExceptionBinding() throws Throwable {
|
||||
void afterThrowingWithRuntimeExceptionBinding() throws Throwable {
|
||||
RuntimeException ex = new RuntimeException();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(ex));
|
||||
@@ -89,14 +96,14 @@ public class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterThrowingWithTypeSpecified() throws Throwable {
|
||||
void afterThrowingWithTypeSpecified() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new Throwable()));
|
||||
verify(mockCollaborator).noArgsOnThrowableMatch();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterThrowingWithRuntimeTypeSpecified() throws Throwable {
|
||||
void afterThrowingWithRuntimeTypeSpecified() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new RuntimeException()));
|
||||
verify(mockCollaborator).noArgsOnRuntimeExceptionMatch();
|
||||
|
||||
+13
-6
@@ -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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.aspectj;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -33,7 +34,9 @@ import org.springframework.lang.Nullable;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AspectAndAdvicePrecedenceTests {
|
||||
class AspectAndAdvicePrecedenceTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private PrecedenceTestAspect highPrecedenceAspect;
|
||||
|
||||
@@ -47,9 +50,8 @@ public class AspectAndAdvicePrecedenceTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
highPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("highPrecedenceAspect");
|
||||
lowPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("lowPrecedenceAspect");
|
||||
highPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("highPrecedenceSpringAdvice");
|
||||
@@ -57,9 +59,14 @@ public class AspectAndAdvicePrecedenceTests {
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAdviceOrder() {
|
||||
void testAdviceOrder() {
|
||||
PrecedenceTestAspect.Collaborator collaborator = new PrecedenceVerifyingCollaborator();
|
||||
this.highPrecedenceAspect.setCollaborator(collaborator);
|
||||
this.lowPrecedenceAspect.setCollaborator(collaborator);
|
||||
|
||||
+13
-21
@@ -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.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
@@ -31,29 +30,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AspectJExpressionPointcutAdvisorTests {
|
||||
|
||||
private ITestBean testBean;
|
||||
|
||||
private CallCountingInterceptor interceptor;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
interceptor = (CallCountingInterceptor) ctx.getBean("interceptor");
|
||||
}
|
||||
|
||||
class AspectJExpressionPointcutAdvisorTests {
|
||||
|
||||
@Test
|
||||
public void testPointcutting() {
|
||||
assertThat(interceptor.getCount()).as("Count should be 0").isEqualTo(0);
|
||||
void pointcutting() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
ITestBean testBean = ctx.getBean("testBean", ITestBean.class);
|
||||
CallCountingInterceptor interceptor = ctx.getBean("interceptor", CallCountingInterceptor.class);
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(0);
|
||||
testBean.getSpouses();
|
||||
assertThat(interceptor.getCount()).as("Count should be 1").isEqualTo(1);
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(1);
|
||||
testBean.getSpouse();
|
||||
assertThat(interceptor.getCount()).as("Count should be 1").isEqualTo(1);
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(1);
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
-9
@@ -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.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
|
||||
@@ -35,7 +37,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class BeanNamePointcutAtAspectTests {
|
||||
class BeanNamePointcutAtAspectTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private ITestBean testBean1;
|
||||
|
||||
@@ -44,19 +48,24 @@ public class BeanNamePointcutAtAspectTests {
|
||||
private CounterAspect counterAspect;
|
||||
|
||||
|
||||
@org.junit.jupiter.api.BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
counterAspect = (CounterAspect) ctx.getBean("counterAspect");
|
||||
testBean1 = (ITestBean) ctx.getBean("testBean1");
|
||||
testBean3 = (ITestBean) ctx.getBean("testBean3");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchingBeanName() {
|
||||
void matchingBeanName() {
|
||||
boolean condition = testBean1 instanceof Advised;
|
||||
assertThat(condition).as("Expected a proxy").isTrue();
|
||||
|
||||
@@ -67,7 +76,7 @@ public class BeanNamePointcutAtAspectTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMatchingBeanName() {
|
||||
void nonMatchingBeanName() {
|
||||
boolean condition = testBean3 instanceof Advised;
|
||||
assertThat(condition).as("Didn't expect a proxy").isFalse();
|
||||
|
||||
@@ -76,7 +85,7 @@ public class BeanNamePointcutAtAspectTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgrammaticProxyCreation() {
|
||||
void programmaticProxyCreation() {
|
||||
ITestBean testBean = new TestBean();
|
||||
|
||||
AspectJProxyFactory factory = new AspectJProxyFactory();
|
||||
|
||||
+18
-11
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -37,7 +38,9 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class BeforeAdviceBindingTests {
|
||||
class BeforeAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private AdviceBindingCollaborator mockCollaborator;
|
||||
|
||||
@@ -47,9 +50,8 @@ public class BeforeAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() throws Exception {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
testBeanProxy = (ITestBean) ctx.getBean("testBean");
|
||||
assertThat(AopUtils.isAopProxy(testBeanProxy)).isTrue();
|
||||
@@ -63,38 +65,43 @@ public class BeforeAdviceBindingTests {
|
||||
beforeAdviceAspect.setCollaborator(mockCollaborator);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testOneIntArg() {
|
||||
void oneIntArg() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntArg(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneObjectArgBoundToProxyUsingThis() {
|
||||
void oneObjectArgBoundToProxyUsingThis() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneIntAndOneObjectArgs() {
|
||||
void oneIntAndOneObjectArgs() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntAndOneObject(5,this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPoint() {
|
||||
void needsJoinPoint() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPoint("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeedsJoinPointStaticPart() {
|
||||
void needsJoinPointStaticPart() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPointStaticPart("getAge");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-10
@@ -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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.aspectj;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -31,7 +32,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class DeclarationOrderIndependenceTests {
|
||||
class DeclarationOrderIndependenceTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private TopsyTurvyAspect aspect;
|
||||
|
||||
@@ -39,28 +42,32 @@ public class DeclarationOrderIndependenceTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
aspect = (TopsyTurvyAspect) ctx.getBean("topsyTurvyAspect");
|
||||
target = (TopsyTurvyTarget) ctx.getBean("topsyTurvyTarget");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTargetIsSerializable() {
|
||||
void testTargetIsSerializable() {
|
||||
boolean condition = this.target instanceof Serializable;
|
||||
assertThat(condition).as("target bean is serializable").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetIsBeanNameAware() {
|
||||
void testTargetIsBeanNameAware() {
|
||||
boolean condition = this.target instanceof BeanNameAware;
|
||||
assertThat(condition).as("target bean is bean name aware").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeforeAdviceFiringOk() {
|
||||
void testBeforeAdviceFiringOk() {
|
||||
AspectCollaborator collab = new AspectCollaborator();
|
||||
this.aspect.setCollaborator(collab);
|
||||
this.target.doSomething();
|
||||
@@ -68,7 +75,7 @@ public class DeclarationOrderIndependenceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAroundAdviceFiringOk() {
|
||||
void testAroundAdviceFiringOk() {
|
||||
AspectCollaborator collab = new AspectCollaborator();
|
||||
this.aspect.setCollaborator(collab);
|
||||
this.target.getX();
|
||||
@@ -76,7 +83,7 @@ public class DeclarationOrderIndependenceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterReturningFiringOk() {
|
||||
void testAfterReturningFiringOk() {
|
||||
AspectCollaborator collab = new AspectCollaborator();
|
||||
this.aspect.setCollaborator(collab);
|
||||
this.target.getX();
|
||||
|
||||
+17
-12
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -27,31 +28,35 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class DeclareParentsDelegateRefTests {
|
||||
class DeclareParentsDelegateRefTests {
|
||||
|
||||
protected NoMethodsBean noMethodsBean;
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
protected Counter counter;
|
||||
private NoMethodsBean noMethodsBean;
|
||||
|
||||
private Counter counter;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
noMethodsBean = (NoMethodsBean) ctx.getBean("noMethodsBean");
|
||||
counter = (Counter) ctx.getBean("counter");
|
||||
counter.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIntroductionWasMade() {
|
||||
boolean condition = noMethodsBean instanceof ICounter;
|
||||
assertThat(condition).as("Introduction must have been made").isTrue();
|
||||
void introductionWasMade() {
|
||||
assertThat(noMethodsBean).as("Introduction must have been made").isInstanceOf(ICounter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntroductionDelegation() {
|
||||
void introductionDelegation() {
|
||||
((ICounter)noMethodsBean).increment();
|
||||
assertThat(counter.getCount()).as("Delegate's counter should be updated").isEqualTo(1);
|
||||
}
|
||||
|
||||
+16
-11
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import test.mixin.Lockable;
|
||||
@@ -31,7 +32,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class DeclareParentsTests {
|
||||
class DeclareParentsTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private ITestBean testBeanProxy;
|
||||
|
||||
@@ -39,20 +42,23 @@ public class DeclareParentsTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBeanProxy = (ITestBean) ctx.getBean("testBean");
|
||||
introductionObject = ctx.getBean("introduction");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIntroductionWasMade() {
|
||||
void introductionWasMade() {
|
||||
assertThat(AopUtils.isAopProxy(testBeanProxy)).isTrue();
|
||||
assertThat(AopUtils.isAopProxy(introductionObject)).as("Introduction should not be proxied").isFalse();
|
||||
boolean condition = testBeanProxy instanceof Lockable;
|
||||
assertThat(condition).as("Introduction must have been made").isTrue();
|
||||
assertThat(testBeanProxy).as("Introduction must have been made").isInstanceOf(Lockable.class);
|
||||
}
|
||||
|
||||
// TODO if you change type pattern from org.springframework.beans..*
|
||||
@@ -60,7 +66,7 @@ public class DeclareParentsTests {
|
||||
// Perhaps generated advisor bean definition could be made to depend
|
||||
// on the introduction, in which case this would not be a problem.
|
||||
@Test
|
||||
public void testLockingWorks() {
|
||||
void lockingWorks() {
|
||||
Lockable lockable = (Lockable) testBeanProxy;
|
||||
assertThat(lockable.locked()).isFalse();
|
||||
|
||||
@@ -69,8 +75,7 @@ public class DeclareParentsTests {
|
||||
|
||||
testBeanProxy.setName("");
|
||||
lockable.lock();
|
||||
assertThatIllegalStateException().as("should be locked").isThrownBy(() ->
|
||||
testBeanProxy.setName(" "));
|
||||
assertThatIllegalStateException().as("should be locked").isThrownBy(() -> testBeanProxy.setName(" "));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -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.
|
||||
@@ -28,10 +28,11 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ImplicitJPArgumentMatchingTests {
|
||||
class ImplicitJPArgumentMatchingTests {
|
||||
|
||||
@Test
|
||||
public void testAspect() {
|
||||
@SuppressWarnings("resource")
|
||||
void testAspect() {
|
||||
// nothing to really test; it is enough if we don't get error while creating app context
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
}
|
||||
|
||||
+17
-23
@@ -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.
|
||||
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for overloaded advice.
|
||||
@@ -29,32 +29,26 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class OverloadedAdviceTests {
|
||||
class OverloadedAdviceTests {
|
||||
|
||||
@Test
|
||||
public void testExceptionOnConfigParsingWithMismatchedAdviceMethod() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable cause = ex.getRootCause();
|
||||
boolean condition = cause instanceof IllegalArgumentException;
|
||||
assertThat(condition).as("Should be IllegalArgumentException").isTrue();
|
||||
assertThat(cause.getMessage().contains("invalidAbsoluteTypeName")).as("invalidAbsoluteTypeName should be detected by AJ").isTrue();
|
||||
}
|
||||
@SuppressWarnings("resource")
|
||||
void testExceptionOnConfigParsingWithMismatchedAdviceMethod() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() -> new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass()))
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.as("invalidAbsoluteTypeName should be detected by AJ").withMessageContaining("invalidAbsoluteTypeName");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionOnConfigParsingWithAmbiguousAdviceMethod() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ambiguous.xml", getClass());
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable cause = ex.getRootCause();
|
||||
boolean condition = cause instanceof IllegalArgumentException;
|
||||
assertThat(condition).as("Should be IllegalArgumentException").isTrue();
|
||||
assertThat(cause.getMessage().contains("Cannot resolve method 'myBeforeAdvice' to a unique method")).as("Cannot resolve method 'myBeforeAdvice' to a unique method").isTrue();
|
||||
}
|
||||
@SuppressWarnings("resource")
|
||||
void testExceptionOnConfigParsingWithAmbiguousAdviceMethod() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() -> new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ambiguous.xml", getClass()))
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("Cannot resolve method 'myBeforeAdvice' to a unique method");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -33,7 +34,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ProceedTests {
|
||||
class ProceedTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private SimpleBean testBean;
|
||||
|
||||
@@ -43,43 +46,46 @@ public class ProceedTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBean = (SimpleBean) ctx.getBean("testBean");
|
||||
firstTestAspect = (ProceedTestingAspect) ctx.getBean("firstTestAspect");
|
||||
secondTestAspect = (ProceedTestingAspect) ctx.getBean("secondTestAspect");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimpleProceedWithChangedArgs() {
|
||||
void testSimpleProceedWithChangedArgs() {
|
||||
this.testBean.setName("abc");
|
||||
assertThat(this.testBean.getName()).as("Name changed in around advice").isEqualTo("ABC");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetArgsIsDefensive() {
|
||||
void testGetArgsIsDefensive() {
|
||||
this.testBean.setAge(5);
|
||||
assertThat(this.testBean.getAge()).as("getArgs is defensive").isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProceedWithArgsInSameAspect() {
|
||||
void testProceedWithArgsInSameAspect() {
|
||||
this.testBean.setMyFloat(1.0F);
|
||||
assertThat(this.testBean.getMyFloat() > 1.9F).as("value changed in around advice").isTrue();
|
||||
assertThat(this.firstTestAspect.getLastBeforeFloatValue() > 1.9F).as("changed value visible to next advice in chain").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProceedWithArgsAcrossAspects() {
|
||||
void testProceedWithArgsAcrossAspects() {
|
||||
this.testBean.setSex("male");
|
||||
assertThat(this.testBean.getSex()).as("value changed in around advice").isEqualTo("MALE");
|
||||
assertThat(this.secondTestAspect.getLastBeforeStringValue()).as("changed value visible to next before advice in chain").isEqualTo("MALE");
|
||||
assertThat(this.secondTestAspect.getLastAroundStringValue()).as("changed value visible to next around advice in chain").isEqualTo("MALE");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -214,4 +220,3 @@ class ProceedTestingAspect implements Ordered {
|
||||
return this.lastBeforeFloatValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-34
@@ -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.
|
||||
@@ -16,53 +16,52 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* See SPR-1682.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class SharedPointcutWithArgsMismatchTests {
|
||||
class SharedPointcutWithArgsMismatchTests {
|
||||
|
||||
private ToBeAdvised toBeAdvised;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
toBeAdvised = (ToBeAdvised) ctx.getBean("toBeAdvised");
|
||||
}
|
||||
private static final List<String> messages = new ArrayList<>();
|
||||
|
||||
|
||||
@Test
|
||||
public void testMismatchedArgBinding() {
|
||||
this.toBeAdvised.foo("Hello");
|
||||
void mismatchedArgBinding() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
ToBeAdvised toBeAdvised = ctx.getBean(ToBeAdvised.class);
|
||||
toBeAdvised.foo("test");
|
||||
assertThat(messages).containsExactly("doBefore(String): test", "foo(String): test");
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
static class ToBeAdvised {
|
||||
|
||||
public void foo(String s) {
|
||||
messages.add("foo(String): " + s);
|
||||
}
|
||||
}
|
||||
|
||||
static class MyAspect {
|
||||
|
||||
public void doBefore(int x) {
|
||||
messages.add("doBefore(int): " + x);
|
||||
}
|
||||
|
||||
public void doBefore(String x) {
|
||||
messages.add("doBefore(String): " + x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ToBeAdvised {
|
||||
|
||||
public void foo(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MyAspect {
|
||||
|
||||
public void doBefore(int x) {
|
||||
System.out.println(x);
|
||||
}
|
||||
|
||||
public void doBefore(String x) {
|
||||
System.out.println(x);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-14
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -30,7 +31,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class SubtypeSensitiveMatchingTests {
|
||||
class SubtypeSensitiveMatchingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private NonSerializableFoo nonSerializableBean;
|
||||
|
||||
@@ -40,31 +43,38 @@ public class SubtypeSensitiveMatchingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
nonSerializableBean = (NonSerializableFoo) ctx.getBean("testClassA");
|
||||
serializableBean = (SerializableFoo) ctx.getBean("testClassB");
|
||||
bar = (Bar) ctx.getBean("testClassC");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBeansAreProxiedOnStaticMatch() {
|
||||
boolean condition = this.serializableBean instanceof Advised;
|
||||
assertThat(condition).as("bean with serializable type should be proxied").isTrue();
|
||||
void beansAreProxiedOnStaticMatch() {
|
||||
assertThat(this.serializableBean)
|
||||
.as("bean with serializable type should be proxied")
|
||||
.isInstanceOf(Advised.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeansThatDoNotMatchBasedSolelyOnRuntimeTypeAreNotProxied() {
|
||||
boolean condition = this.nonSerializableBean instanceof Advised;
|
||||
assertThat(condition).as("bean with non-serializable type should not be proxied").isFalse();
|
||||
void beansThatDoNotMatchBasedSolelyOnRuntimeTypeAreNotProxied() {
|
||||
assertThat(this.nonSerializableBean)
|
||||
.as("bean with non-serializable type should not be proxied")
|
||||
.isNotInstanceOf(Advised.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeansThatDoNotMatchBasedOnOtherTestAreProxied() {
|
||||
boolean condition = this.bar instanceof Advised;
|
||||
assertThat(condition).as("bean with args check should be proxied").isTrue();
|
||||
void beansThatDoNotMatchBasedOnOtherTestAreProxied() {
|
||||
assertThat(this.bar)
|
||||
.as("bean with args check should be proxied")
|
||||
.isInstanceOf(Advised.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
-32
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -32,37 +33,39 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TargetPointcutSelectionTests {
|
||||
class TargetPointcutSelectionTests {
|
||||
|
||||
public TestInterface testImpl1;
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
public TestInterface testImpl2;
|
||||
private TestInterface testImpl1;
|
||||
|
||||
public TestAspect testAspectForTestImpl1;
|
||||
private TestInterface testImpl2;
|
||||
|
||||
public TestAspect testAspectForAbstractTestImpl;
|
||||
private TestAspect testAspectForTestImpl1;
|
||||
|
||||
public TestInterceptor testInterceptor;
|
||||
private TestAspect testAspectForAbstractTestImpl;
|
||||
|
||||
private TestInterceptor testInterceptor;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testImpl1 = (TestInterface) ctx.getBean("testImpl1");
|
||||
testImpl2 = (TestInterface) ctx.getBean("testImpl2");
|
||||
testAspectForTestImpl1 = (TestAspect) ctx.getBean("testAspectForTestImpl1");
|
||||
testAspectForAbstractTestImpl = (TestAspect) ctx.getBean("testAspectForAbstractTestImpl");
|
||||
testInterceptor = (TestInterceptor) ctx.getBean("testInterceptor");
|
||||
}
|
||||
|
||||
testAspectForTestImpl1.count = 0;
|
||||
testAspectForAbstractTestImpl.count = 0;
|
||||
testInterceptor.count = 0;
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void targetSelectionForMatchedType() {
|
||||
void targetSelectionForMatchedType() {
|
||||
testImpl1.interfaceMethod();
|
||||
assertThat(testAspectForTestImpl1.count).as("Should have been advised by POJO advice for impl").isEqualTo(1);
|
||||
assertThat(testAspectForAbstractTestImpl.count).as("Should have been advised by POJO advice for base type").isEqualTo(1);
|
||||
@@ -70,49 +73,43 @@ public class TargetPointcutSelectionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void targetNonSelectionForMismatchedType() {
|
||||
void targetNonSelectionForMismatchedType() {
|
||||
testImpl2.interfaceMethod();
|
||||
assertThat(testAspectForTestImpl1.count).as("Shouldn't have been advised by POJO advice for impl").isEqualTo(0);
|
||||
assertThat(testAspectForTestImpl1.count).as("Shouldn't have been advised by POJO advice for impl").isZero();
|
||||
assertThat(testAspectForAbstractTestImpl.count).as("Should have been advised by POJO advice for base type").isEqualTo(1);
|
||||
assertThat(testInterceptor.count).as("Shouldn't have been advised by advisor").isEqualTo(0);
|
||||
assertThat(testInterceptor.count).as("Shouldn't have been advised by advisor").isZero();
|
||||
}
|
||||
|
||||
|
||||
public static interface TestInterface {
|
||||
|
||||
public void interfaceMethod();
|
||||
interface TestInterface {
|
||||
void interfaceMethod();
|
||||
}
|
||||
|
||||
|
||||
// Reproducing bug requires that the class specified in target() pointcut doesn't
|
||||
// include the advised method's implementation (instead a base class should include it)
|
||||
public static abstract class AbstractTestImpl implements TestInterface {
|
||||
static abstract class AbstractTestImpl implements TestInterface {
|
||||
|
||||
@Override
|
||||
public void interfaceMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TestImpl1 extends AbstractTestImpl {
|
||||
static class TestImpl1 extends AbstractTestImpl {
|
||||
}
|
||||
|
||||
|
||||
public static class TestImpl2 extends AbstractTestImpl {
|
||||
static class TestImpl2 extends AbstractTestImpl {
|
||||
}
|
||||
|
||||
static class TestAspect {
|
||||
|
||||
public static class TestAspect {
|
||||
int count;
|
||||
|
||||
public int count;
|
||||
|
||||
public void increment() {
|
||||
void increment() {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TestInterceptor extends TestAspect implements MethodInterceptor {
|
||||
static class TestInterceptor extends TestAspect implements MethodInterceptor {
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
|
||||
+25
-16
@@ -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.
|
||||
@@ -21,6 +21,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -30,8 +32,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private TestInterface testBean;
|
||||
|
||||
@@ -42,10 +47,9 @@ public class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
private Counter counter;
|
||||
|
||||
|
||||
@org.junit.jupiter.api.BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBean = (TestInterface) ctx.getBean("testBean");
|
||||
testAnnotatedClassBean = (TestInterface) ctx.getBean("testAnnotatedClassBean");
|
||||
testAnnotatedMethodBean = (TestInterface) ctx.getBean("testAnnotatedMethodBean");
|
||||
@@ -53,58 +57,63 @@ public class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
counter.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void thisAsClassDoesNotMatch() {
|
||||
void thisAsClassDoesNotMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.thisAsClassCounter).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void thisAsInterfaceMatch() {
|
||||
void thisAsInterfaceMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.thisAsInterfaceCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void targetAsClassDoesMatch() {
|
||||
void targetAsClassDoesMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.targetAsClassCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void targetAsInterfaceMatch() {
|
||||
void targetAsInterfaceMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.targetAsInterfaceCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void thisAsClassAndTargetAsClassCounterNotMatch() {
|
||||
void thisAsClassAndTargetAsClassCounterNotMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.thisAsClassAndTargetAsClassCounter).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void thisAsInterfaceAndTargetAsInterfaceCounterMatch() {
|
||||
void thisAsInterfaceAndTargetAsInterfaceCounterMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.thisAsInterfaceAndTargetAsInterfaceCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void thisAsInterfaceAndTargetAsClassCounterMatch() {
|
||||
void thisAsInterfaceAndTargetAsClassCounterMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(counter.thisAsInterfaceAndTargetAsInterfaceCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void atTargetClassAnnotationMatch() {
|
||||
void atTargetClassAnnotationMatch() {
|
||||
testAnnotatedClassBean.doIt();
|
||||
assertThat(counter.atTargetClassAnnotationCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void atAnnotationMethodAnnotationMatch() {
|
||||
void atAnnotationMethodAnnotationMatch() {
|
||||
testAnnotatedMethodBean.doIt();
|
||||
assertThat(counter.atAnnotationMethodAnnotationCounter).isEqualTo(1);
|
||||
}
|
||||
@@ -121,7 +130,6 @@ public class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public static @interface TestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation
|
||||
@@ -211,4 +219,5 @@ public class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+25
-27
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -26,8 +27,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class ThisAndTargetSelectionOnlyPointcutsTests {
|
||||
class ThisAndTargetSelectionOnlyPointcutsTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private TestInterface testBean;
|
||||
|
||||
@@ -37,70 +41,64 @@ public class ThisAndTargetSelectionOnlyPointcutsTests {
|
||||
private Counter targetAsInterfaceCounter;
|
||||
private Counter thisAsClassAndTargetAsClassCounter;
|
||||
private Counter thisAsInterfaceAndTargetAsInterfaceCounter;
|
||||
private Counter thisAsInterfaceAndTargetAsClassCounter;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBean = (TestInterface) ctx.getBean("testBean");
|
||||
thisAsClassCounter = (Counter) ctx.getBean("thisAsClassCounter");
|
||||
thisAsInterfaceCounter = (Counter) ctx.getBean("thisAsInterfaceCounter");
|
||||
targetAsClassCounter = (Counter) ctx.getBean("targetAsClassCounter");
|
||||
targetAsInterfaceCounter = (Counter) ctx.getBean("targetAsInterfaceCounter");
|
||||
thisAsClassAndTargetAsClassCounter = (Counter) ctx.getBean("thisAsClassAndTargetAsClassCounter");
|
||||
thisAsInterfaceAndTargetAsInterfaceCounter = (Counter) ctx.getBean("thisAsInterfaceAndTargetAsInterfaceCounter");
|
||||
thisAsInterfaceAndTargetAsClassCounter = (Counter) ctx.getBean("thisAsInterfaceAndTargetAsClassCounter");
|
||||
thisAsClassCounter = ctx.getBean("thisAsClassCounter", Counter.class);
|
||||
thisAsInterfaceCounter = ctx.getBean("thisAsInterfaceCounter", Counter.class);
|
||||
targetAsClassCounter = ctx.getBean("targetAsClassCounter", Counter.class);
|
||||
targetAsInterfaceCounter = ctx.getBean("targetAsInterfaceCounter", Counter.class);
|
||||
thisAsClassAndTargetAsClassCounter = ctx.getBean("thisAsClassAndTargetAsClassCounter", Counter.class);
|
||||
thisAsInterfaceAndTargetAsInterfaceCounter = ctx.getBean("thisAsInterfaceAndTargetAsInterfaceCounter", Counter.class);
|
||||
}
|
||||
|
||||
thisAsClassCounter.reset();
|
||||
thisAsInterfaceCounter.reset();
|
||||
targetAsClassCounter.reset();
|
||||
targetAsInterfaceCounter.reset();
|
||||
thisAsClassAndTargetAsClassCounter.reset();
|
||||
thisAsInterfaceAndTargetAsInterfaceCounter.reset();
|
||||
thisAsInterfaceAndTargetAsClassCounter.reset();
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testThisAsClassDoesNotMatch() {
|
||||
void thisAsClassDoesNotMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(thisAsClassCounter.getCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAsInterfaceMatch() {
|
||||
void thisAsInterfaceMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(thisAsInterfaceCounter.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAsClassDoesMatch() {
|
||||
void targetAsClassDoesMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(targetAsClassCounter.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAsInterfaceMatch() {
|
||||
void targetAsInterfaceMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(targetAsInterfaceCounter.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAsClassAndTargetAsClassCounterNotMatch() {
|
||||
void thisAsClassAndTargetAsClassCounterNotMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(thisAsClassAndTargetAsClassCounter.getCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAsInterfaceAndTargetAsInterfaceCounterMatch() {
|
||||
void thisAsInterfaceAndTargetAsInterfaceCounterMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(thisAsInterfaceAndTargetAsInterfaceCounter.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAsInterfaceAndTargetAsClassCounterMatch() {
|
||||
void thisAsInterfaceAndTargetAsClassCounterMatch() {
|
||||
testBean.doIt();
|
||||
assertThat(thisAsInterfaceAndTargetAsInterfaceCounter.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
+14
-7
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -27,27 +28,33 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AnnotationBindingTests {
|
||||
class AnnotationBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private AnnotatedTestBean testBean;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
testBean = (AnnotatedTestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAnnotationBindingInAroundAdvice() {
|
||||
void annotationBindingInAroundAdvice() {
|
||||
assertThat(testBean.doThis()).isEqualTo("this value");
|
||||
assertThat(testBean.doThat()).isEqualTo("that value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingWithoutAnnotationPresent() {
|
||||
void noMatchingWithoutAnnotationPresent() {
|
||||
assertThat(testBean.doTheOther()).isEqualTo("doTheOther");
|
||||
}
|
||||
|
||||
|
||||
+14
-8
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -29,27 +30,32 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AnnotationPointcutTests {
|
||||
class AnnotationPointcutTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private AnnotatedTestBean testBean;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
this.testBean = ctx.getBean("testBean", AnnotatedTestBean.class);
|
||||
}
|
||||
|
||||
testBean = (AnnotatedTestBean) ctx.getBean("testBean");
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAnnotationBindingInAroundAdvice() {
|
||||
void annotationBindingInAroundAdvice() {
|
||||
assertThat(testBean.doThis()).isEqualTo("this value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingWithoutAnnotationPresent() {
|
||||
void noMatchingWithoutAnnotationPresent() {
|
||||
assertThat(testBean.doTheOther()).isEqualTo("doTheOther");
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -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.
|
||||
@@ -30,21 +30,21 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class AspectImplementingInterfaceTests {
|
||||
class AspectImplementingInterfaceTests {
|
||||
|
||||
@Test
|
||||
public void testProxyCreation() {
|
||||
void proxyCreation() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
ITestBean testBean = (ITestBean) ctx.getBean("testBean");
|
||||
AnInterface interfaceExtendingAspect = (AnInterface) ctx.getBean("interfaceExtendingAspect");
|
||||
ITestBean testBean = ctx.getBean("testBean", ITestBean.class);
|
||||
AnInterface interfaceExtendingAspect = ctx.getBean("interfaceExtendingAspect", AnInterface.class);
|
||||
|
||||
boolean condition = testBean instanceof Advised;
|
||||
assertThat(condition).isTrue();
|
||||
boolean condition1 = interfaceExtendingAspect instanceof Advised;
|
||||
assertThat(condition1).isFalse();
|
||||
assertThat(testBean).isInstanceOf(Advised.class);
|
||||
assertThat(interfaceExtendingAspect).isNotInstanceOf(Advised.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -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.
|
||||
@@ -29,10 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AspectJAutoProxyCreatorAndLazyInitTargetSourceTests {
|
||||
class AspectJAutoProxyCreatorAndLazyInitTargetSourceTests {
|
||||
|
||||
@Test
|
||||
public void testAdrian() {
|
||||
void testAdrian() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
@@ -42,6 +42,7 @@ public class AspectJAutoProxyCreatorAndLazyInitTargetSourceTests {
|
||||
adrian.getAge();
|
||||
assertThat(adrian.getAge()).isEqualTo(68);
|
||||
assertThat(LazyTestBean.instantiations).isEqualTo(1);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+103
-2
@@ -21,6 +21,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
@@ -31,11 +33,17 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.IntroductionAdvisor;
|
||||
import org.springframework.aop.IntroductionInterceptor;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
|
||||
import org.springframework.aop.aspectj.annotation.AspectMetadata;
|
||||
import org.springframework.aop.config.AopConfigUtils;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.ProxyConfig;
|
||||
import org.springframework.aop.support.AbstractPointcutAdvisor;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
@@ -52,6 +60,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.DecoratingProxy;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -304,10 +313,26 @@ public class AspectJAutoProxyCreatorTests {
|
||||
@ValueSource(classes = {ProxyTargetClassFalseConfig.class, ProxyTargetClassTrueConfig.class})
|
||||
void lambdaIsAlwaysProxiedWithJdkProxy(Class<?> configClass) {
|
||||
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(configClass)) {
|
||||
Supplier<?> supplier = context.getBean(Supplier.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<String> supplier = context.getBean(Supplier.class);
|
||||
assertThat(AopUtils.isAopProxy(supplier)).as("AOP proxy").isTrue();
|
||||
assertThat(AopUtils.isJdkDynamicProxy(supplier)).as("JDK Dynamic proxy").isTrue();
|
||||
assertThat(supplier.get()).asString().isEqualTo("advised: lambda");
|
||||
assertThat(supplier.getClass().getInterfaces())
|
||||
.containsExactlyInAnyOrder(Supplier.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
|
||||
assertThat(supplier.get()).isEqualTo("advised: lambda");
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@ValueSource(classes = {MixinProxyTargetClassFalseConfig.class, MixinProxyTargetClassTrueConfig.class})
|
||||
void lambdaIsAlwaysProxiedWithJdkProxyWithIntroductions(Class<?> configClass) {
|
||||
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(configClass)) {
|
||||
MessageGenerator messageGenerator = context.getBean(MessageGenerator.class);
|
||||
assertThat(AopUtils.isAopProxy(messageGenerator)).as("AOP proxy").isTrue();
|
||||
assertThat(AopUtils.isJdkDynamicProxy(messageGenerator)).as("JDK Dynamic proxy").isTrue();
|
||||
assertThat(messageGenerator.getClass().getInterfaces())
|
||||
.containsExactlyInAnyOrder(MessageGenerator.class, Mixin.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
|
||||
assertThat(messageGenerator.generateMessage()).isEqualTo("mixin: lambda");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,3 +641,79 @@ class ProxyTargetClassFalseConfig extends AbstractProxyTargetClassConfig {
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
class ProxyTargetClassTrueConfig extends AbstractProxyTargetClassConfig {
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface MessageGenerator {
|
||||
String generateMessage();
|
||||
}
|
||||
|
||||
interface Mixin {
|
||||
}
|
||||
|
||||
class MixinIntroductionInterceptor implements IntroductionInterceptor {
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
return "mixin: " + invocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean implementsInterface(Class<?> intf) {
|
||||
return Mixin.class.isAssignableFrom(intf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class MixinAdvisor extends AbstractPointcutAdvisor implements IntroductionAdvisor {
|
||||
|
||||
@Override
|
||||
public org.springframework.aop.Pointcut getPointcut() {
|
||||
return org.springframework.aop.Pointcut.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
return new MixinIntroductionInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getInterfaces() {
|
||||
return new Class[] { Mixin.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassFilter getClassFilter() {
|
||||
return MessageGenerator.class::isAssignableFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateInterfaces() {
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class AbstractMixinConfig {
|
||||
|
||||
@Bean
|
||||
MessageGenerator messageGenerator() {
|
||||
return () -> "lambda";
|
||||
}
|
||||
|
||||
@Bean
|
||||
MixinAdvisor mixinAdvisor() {
|
||||
return new MixinAdvisor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = false)
|
||||
class MixinProxyTargetClassFalseConfig extends AbstractMixinConfig {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
class MixinProxyTargetClassTrueConfig extends AbstractMixinConfig {
|
||||
}
|
||||
|
||||
+5
-3
@@ -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.
|
||||
@@ -33,10 +33,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AtAspectJAfterThrowingTests {
|
||||
class AtAspectJAfterThrowingTests {
|
||||
|
||||
@Test
|
||||
public void testAccessThrowable() {
|
||||
void accessThrowable() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
@@ -54,6 +54,8 @@ public class AtAspectJAfterThrowingTests {
|
||||
|
||||
assertThat(aspect.handled).isEqualTo(1);
|
||||
assertThat(aspect.lastException).isSameAs(exceptionThrown);
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+25
-21
@@ -45,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class BenchmarkTests {
|
||||
class BenchmarkTests {
|
||||
|
||||
private static final Class<?> CLASS = BenchmarkTests.class;
|
||||
|
||||
@@ -54,42 +54,42 @@ public class BenchmarkTests {
|
||||
private static final String SPRING_AOP_CONTEXT = CLASS.getSimpleName() + "-springAop.xml";
|
||||
|
||||
@Test
|
||||
public void testRepeatedAroundAdviceInvocationsWithAspectJ() {
|
||||
void repeatedAroundAdviceInvocationsWithAspectJ() {
|
||||
testRepeatedAroundAdviceInvocations(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAroundAdviceInvocationsWithSpringAop() {
|
||||
void repeatedAroundAdviceInvocationsWithSpringAop() {
|
||||
testRepeatedAroundAdviceInvocations(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedBeforeAdviceInvocationsWithAspectJ() {
|
||||
void repeatedBeforeAdviceInvocationsWithAspectJ() {
|
||||
testBeforeAdviceWithoutJoinPoint(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedBeforeAdviceInvocationsWithSpringAop() {
|
||||
void repeatedBeforeAdviceInvocationsWithSpringAop() {
|
||||
testBeforeAdviceWithoutJoinPoint(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAfterReturningAdviceInvocationsWithAspectJ() {
|
||||
void repeatedAfterReturningAdviceInvocationsWithAspectJ() {
|
||||
testAfterReturningAdviceWithoutJoinPoint(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAfterReturningAdviceInvocationsWithSpringAop() {
|
||||
void repeatedAfterReturningAdviceInvocationsWithSpringAop() {
|
||||
testAfterReturningAdviceWithoutJoinPoint(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedMixWithAspectJ() {
|
||||
void repeatedMixWithAspectJ() {
|
||||
testMix(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedMixWithSpringAop() {
|
||||
void repeatedMixWithSpringAop() {
|
||||
testMix(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@@ -101,11 +101,11 @@ public class BenchmarkTests {
|
||||
}
|
||||
|
||||
private long testRepeatedAroundAdviceInvocations(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated around advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
ITestBean adrian = (ITestBean) ac.getBean("adrian");
|
||||
|
||||
assertThat(AopUtils.isAopProxy(adrian)).isTrue();
|
||||
assertThat(adrian.getAge()).isEqualTo(68);
|
||||
@@ -115,16 +115,17 @@ public class BenchmarkTests {
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
// System.out.println(sw.prettyPrint());
|
||||
ac.close();
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testBeforeAdviceWithoutJoinPoint(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated before advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
ITestBean adrian = (ITestBean) ac.getBean("adrian");
|
||||
|
||||
assertThat(AopUtils.isAopProxy(adrian)).isTrue();
|
||||
Advised a = (Advised) adrian;
|
||||
@@ -136,16 +137,17 @@ public class BenchmarkTests {
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
// System.out.println(sw.prettyPrint());
|
||||
ac.close();
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testAfterReturningAdviceWithoutJoinPoint(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated after returning advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
ITestBean adrian = (ITestBean) ac.getBean("adrian");
|
||||
|
||||
assertThat(AopUtils.isAopProxy(adrian)).isTrue();
|
||||
Advised a = (Advised) adrian;
|
||||
@@ -158,16 +160,17 @@ public class BenchmarkTests {
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
// System.out.println(sw.prettyPrint());
|
||||
ac.close();
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testMix(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated mixed invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
ITestBean adrian = (ITestBean) ac.getBean("adrian");
|
||||
|
||||
assertThat(AopUtils.isAopProxy(adrian)).isTrue();
|
||||
Advised a = (Advised) adrian;
|
||||
@@ -186,7 +189,8 @@ public class BenchmarkTests {
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
// System.out.println(sw.prettyPrint());
|
||||
ac.close();
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
+9
-10
@@ -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.
|
||||
@@ -32,20 +32,19 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class SPR3064Tests {
|
||||
|
||||
private Service service;
|
||||
|
||||
class SPR3064Tests {
|
||||
|
||||
@Test
|
||||
public void testServiceIsAdvised() {
|
||||
void testServiceIsAdvised() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
service = (Service) ctx.getBean("service");
|
||||
assertThatExceptionOfType(RuntimeException.class).isThrownBy(
|
||||
this.service::serveMe)
|
||||
.withMessageContaining("advice invoked");
|
||||
Service service = ctx.getBean(Service.class);
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(service::serveMe)
|
||||
.withMessage("advice invoked");
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-9
@@ -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,6 +22,7 @@ import java.util.Collection;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -40,7 +41,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AfterReturningGenericTypeMatchingTests {
|
||||
class AfterReturningGenericTypeMatchingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private GenericReturnTypeVariationClass testBean;
|
||||
|
||||
@@ -48,9 +51,8 @@ public class AfterReturningGenericTypeMatchingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
counterAspect = (CounterAspect) ctx.getBean("counterAspect");
|
||||
counterAspect.reset();
|
||||
@@ -58,9 +60,14 @@ public class AfterReturningGenericTypeMatchingTests {
|
||||
testBean = (GenericReturnTypeVariationClass) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReturnTypeExactMatching() {
|
||||
void returnTypeExactMatching() {
|
||||
testBean.getStrings();
|
||||
assertThat(counterAspect.getStringsInvocationsCount).isEqualTo(1);
|
||||
assertThat(counterAspect.getIntegersInvocationsCount).isEqualTo(0);
|
||||
@@ -73,7 +80,7 @@ public class AfterReturningGenericTypeMatchingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnTypeRawMatching() {
|
||||
void returnTypeRawMatching() {
|
||||
testBean.getStrings();
|
||||
assertThat(counterAspect.getRawsInvocationsCount).isEqualTo(1);
|
||||
|
||||
@@ -84,13 +91,13 @@ public class AfterReturningGenericTypeMatchingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnTypeUpperBoundMatching() {
|
||||
void returnTypeUpperBoundMatching() {
|
||||
testBean.getIntegers();
|
||||
assertThat(counterAspect.getNumbersInvocationsCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnTypeLowerBoundMatching() {
|
||||
void returnTypeLowerBoundMatching() {
|
||||
testBean.getTestBeans();
|
||||
assertThat(counterAspect.getTestBeanInvocationsCount).isEqualTo(1);
|
||||
|
||||
|
||||
+5
-5
@@ -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.
|
||||
@@ -25,21 +25,21 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* <p>This class focuses on class proxying.
|
||||
*
|
||||
* <p>See GenericBridgeMethodMatchingTests for more details.
|
||||
* <p>See {@link GenericBridgeMethodMatchingTests} for more details.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class GenericBridgeMethodMatchingClassProxyTests extends GenericBridgeMethodMatchingTests {
|
||||
class GenericBridgeMethodMatchingClassProxyTests extends GenericBridgeMethodMatchingTests {
|
||||
|
||||
@Test
|
||||
public void testGenericDerivedInterfaceMethodThroughClass() {
|
||||
void testGenericDerivedInterfaceMethodThroughClass() {
|
||||
((DerivedStringParameterizedClass) testBean).genericDerivedInterfaceMethod("");
|
||||
assertThat(counterAspect.count).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericBaseInterfaceMethodThroughClass() {
|
||||
void testGenericBaseInterfaceMethodThroughClass() {
|
||||
((DerivedStringParameterizedClass) testBean).genericBaseInterfaceMethod("");
|
||||
assertThat(counterAspect.count).isEqualTo(1);
|
||||
}
|
||||
|
||||
+18
-10
@@ -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.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.aop.aspectj.generic;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -39,34 +41,40 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class GenericBridgeMethodMatchingTests {
|
||||
class GenericBridgeMethodMatchingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
protected DerivedInterface<String> testBean;
|
||||
|
||||
protected GenericCounterAspect counterAspect;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("unchecked")
|
||||
@org.junit.jupiter.api.BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
counterAspect = (GenericCounterAspect) ctx.getBean("counterAspect");
|
||||
counterAspect = ctx.getBean("counterAspect", GenericCounterAspect.class);
|
||||
counterAspect.count = 0;
|
||||
|
||||
testBean = (DerivedInterface<String>) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGenericDerivedInterfaceMethodThroughInterface() {
|
||||
void testGenericDerivedInterfaceMethodThroughInterface() {
|
||||
testBean.genericDerivedInterfaceMethod("");
|
||||
assertThat(counterAspect.count).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericBaseInterfaceMethodThroughInterface() {
|
||||
void testGenericBaseInterfaceMethodThroughInterface() {
|
||||
testBean.genericBaseInterfaceMethod("");
|
||||
assertThat(counterAspect.count).isEqualTo(1);
|
||||
}
|
||||
@@ -82,7 +90,7 @@ interface BaseInterface<T> {
|
||||
|
||||
interface DerivedInterface<T> extends BaseInterface<T> {
|
||||
|
||||
public void genericDerivedInterfaceMethod(T t);
|
||||
void genericDerivedInterfaceMethod(T t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+19
-13
@@ -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.
|
||||
@@ -21,6 +21,8 @@ import java.util.Collection;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -34,40 +36,44 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class GenericParameterMatchingTests {
|
||||
class GenericParameterMatchingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
private CounterAspect counterAspect;
|
||||
|
||||
private GenericInterface<String> testBean;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("unchecked")
|
||||
@org.junit.jupiter.api.BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
counterAspect = (CounterAspect) ctx.getBean("counterAspect");
|
||||
counterAspect.reset();
|
||||
|
||||
testBean = (GenericInterface<String>) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGenericInterfaceGenericArgExecution() {
|
||||
void testGenericInterfaceGenericArgExecution() {
|
||||
testBean.save("");
|
||||
assertThat(counterAspect.genericInterfaceGenericArgExecutionCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericInterfaceGenericCollectionArgExecution() {
|
||||
void testGenericInterfaceGenericCollectionArgExecution() {
|
||||
testBean.saveAll(null);
|
||||
assertThat(counterAspect.genericInterfaceGenericCollectionArgExecutionCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericInterfaceSubtypeGenericCollectionArgExecution() {
|
||||
void testGenericInterfaceSubtypeGenericCollectionArgExecution() {
|
||||
testBean.saveAll(null);
|
||||
assertThat(counterAspect.genericInterfaceSubtypeGenericCollectionArgExecutionCount).isEqualTo(1);
|
||||
}
|
||||
@@ -75,9 +81,9 @@ public class GenericParameterMatchingTests {
|
||||
|
||||
static interface GenericInterface<T> {
|
||||
|
||||
public void save(T bean);
|
||||
void save(T bean);
|
||||
|
||||
public void saveAll(Collection<T> beans);
|
||||
void saveAll(Collection<T> beans);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
public class AopNamespaceHandlerAdviceTypeTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testParsingOfAdviceTypes() {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ok.xml", getClass());
|
||||
}
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
public class AopNamespaceHandlerArgNamesTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testArgNamesOK() {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ok.xml", getClass());
|
||||
}
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
public class AopNamespaceHandlerReturningTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testReturningOnReturningAdvice() {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ok.xml", getClass());
|
||||
}
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
public class AopNamespaceHandlerThrowingTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testThrowingOnThrowingAdvice() {
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ok.xml", getClass());
|
||||
}
|
||||
|
||||
+8
-7
@@ -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.
|
||||
@@ -40,33 +40,34 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Dmitriy Kopylenko
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AdvisorAdapterRegistrationTests {
|
||||
class AdvisorAdapterRegistrationTests {
|
||||
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
public void resetGlobalAdvisorAdapterRegistry() {
|
||||
void resetGlobalAdvisorAdapterRegistry() {
|
||||
GlobalAdvisorAdapterRegistry.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdvisorAdapterRegistrationManagerNotPresentInContext() {
|
||||
void advisorAdapterRegistrationManagerNotPresentInContext() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-without-bpp.xml", getClass());
|
||||
ITestBean tb = (ITestBean) ctx.getBean("testBean");
|
||||
// just invoke any method to see if advice fired
|
||||
assertThatExceptionOfType(UnknownAdviceTypeException.class).isThrownBy(
|
||||
tb::getName);
|
||||
assertThatExceptionOfType(UnknownAdviceTypeException.class).isThrownBy(tb::getName);
|
||||
assertThat(getAdviceImpl(tb).getInvocationCounter()).isZero();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdvisorAdapterRegistrationManagerPresentInContext() {
|
||||
void advisorAdapterRegistrationManagerPresentInContext() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-with-bpp.xml", getClass());
|
||||
ITestBean tb = (ITestBean) ctx.getBean("testBean");
|
||||
// just invoke any method to see if advice fired
|
||||
tb.getName();
|
||||
getAdviceImpl(tb).getInvocationCounter();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
private SimpleBeforeAdviceImpl getAdviceImpl(ITestBean tb) {
|
||||
|
||||
+11
-6
@@ -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.
|
||||
@@ -32,18 +32,23 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
* @author Juergen Hoeller
|
||||
* @author Dave Syer
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class BeanNameAutoProxyCreatorInitTests {
|
||||
class BeanNameAutoProxyCreatorInitTests {
|
||||
|
||||
@Test
|
||||
public void testIgnoreAdvisorThatIsCurrentlyInCreation() {
|
||||
void ignoreAdvisorThatIsCurrentlyInCreation() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
TestBean bean = (TestBean) ctx.getBean("bean");
|
||||
|
||||
TestBean bean = ctx.getBean(TestBean.class);
|
||||
bean.setName("foo");
|
||||
assertThat(bean.getName()).isEqualTo("foo");
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
bean.setName(null));
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> bean.setName(null))
|
||||
.withMessage("Null argument at position 0");
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-6
@@ -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,14 +26,13 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BridgeMethodAutowiringTests {
|
||||
class BridgeMethodAutowiringTests {
|
||||
|
||||
@Test
|
||||
public void SPR8434() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(UserServiceImpl.class, Foo.class);
|
||||
ctx.refresh();
|
||||
void SPR8434() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserServiceImpl.class, Foo.class);
|
||||
assertThat(ctx.getBean(UserServiceImpl.class).object).isNotNull();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-7
@@ -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.
|
||||
@@ -19,28 +19,31 @@ package org.springframework.beans.factory.xml;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for combining the expression language and the p namespace. Due to the required EL dependency, this test is in
|
||||
* context module rather than the beans module.
|
||||
* Tests for combining the expression language and the p namespace.
|
||||
*
|
||||
* <p>Due to the required EL dependency, this test is in context module rather
|
||||
* than the beans module.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class SimplePropertyNamespaceHandlerWithExpressionLanguageTests {
|
||||
class SimplePropertyNamespaceHandlerWithExpressionLanguageTests {
|
||||
|
||||
@Test
|
||||
public void combineWithExpressionLanguage() {
|
||||
ApplicationContext applicationContext =
|
||||
void combineWithExpressionLanguage() {
|
||||
ConfigurableApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext("simplePropertyNamespaceHandlerWithExpressionLanguageTests.xml",
|
||||
getClass());
|
||||
ITestBean foo = applicationContext.getBean("foo", ITestBean.class);
|
||||
ITestBean bar = applicationContext.getBean("bar", ITestBean.class);
|
||||
assertThat(foo.getName()).as("Invalid name").isEqualTo("Baz");
|
||||
assertThat(bar.getName()).as("Invalid name").isEqualTo("Baz");
|
||||
applicationContext.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-14
@@ -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.
|
||||
@@ -53,10 +53,10 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CacheReproTests {
|
||||
class CacheReproTests {
|
||||
|
||||
@Test
|
||||
public void spr11124MultipleAnnotations() {
|
||||
void spr11124MultipleAnnotations() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11124Config.class);
|
||||
Spr11124Service bean = context.getBean(Spr11124Service.class);
|
||||
bean.single(2);
|
||||
@@ -67,7 +67,7 @@ public class CacheReproTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr11249PrimitiveVarargs() {
|
||||
void spr11249PrimitiveVarargs() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11249Config.class);
|
||||
Spr11249Service bean = context.getBean(Spr11249Service.class);
|
||||
Object result = bean.doSomething("op", 2, 3);
|
||||
@@ -76,7 +76,7 @@ public class CacheReproTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr11592GetSimple() {
|
||||
void spr11592GetSimple() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11592Config.class);
|
||||
Spr11592Service bean = context.getBean(Spr11592Service.class);
|
||||
Cache cache = context.getBean("cache", Cache.class);
|
||||
@@ -93,7 +93,7 @@ public class CacheReproTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr11592GetNeverCache() {
|
||||
void spr11592GetNeverCache() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11592Config.class);
|
||||
Spr11592Service bean = context.getBean(Spr11592Service.class);
|
||||
Cache cache = context.getBean("cache", Cache.class);
|
||||
@@ -110,7 +110,7 @@ public class CacheReproTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr13081ConfigNoCacheNameIsRequired() {
|
||||
void spr13081ConfigNoCacheNameIsRequired() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr13081Config.class);
|
||||
MyCacheResolver cacheResolver = context.getBean(MyCacheResolver.class);
|
||||
Spr13081Service bean = context.getBean(Spr13081Service.class);
|
||||
@@ -118,20 +118,21 @@ public class CacheReproTests {
|
||||
assertThat(cacheResolver.getCache("foo").get("foo")).isNull();
|
||||
Object result = bean.getSimple("foo"); // cache name = id
|
||||
assertThat(cacheResolver.getCache("foo").get("foo").get()).isEqualTo(result);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr13081ConfigFailIfCacheResolverReturnsNullCacheName() {
|
||||
void spr13081ConfigFailIfCacheResolverReturnsNullCacheName() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr13081Config.class);
|
||||
Spr13081Service bean = context.getBean(Spr13081Service.class);
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
bean.getSimple(null))
|
||||
assertThatIllegalStateException().isThrownBy(() -> bean.getSimple(null))
|
||||
.withMessageContaining(MyCacheResolver.class.getName());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr14230AdaptsToOptional() {
|
||||
void spr14230AdaptsToOptional() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr14230Config.class);
|
||||
Spr14230Service bean = context.getBean(Spr14230Service.class);
|
||||
Cache cache = context.getBean(CacheManager.class).getCache("itemCache");
|
||||
@@ -145,10 +146,11 @@ public class CacheReproTests {
|
||||
TestBean tb2 = bean.findById("tb1").get();
|
||||
assertThat(tb2).isNotSameAs(tb);
|
||||
assertThat(cache.get("tb1").get()).isSameAs(tb2);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr14853AdaptsToOptionalWithSync() {
|
||||
void spr14853AdaptsToOptionalWithSync() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr14853Config.class);
|
||||
Spr14853Service bean = context.getBean(Spr14853Service.class);
|
||||
Cache cache = context.getBean(CacheManager.class).getCache("itemCache");
|
||||
@@ -162,10 +164,11 @@ public class CacheReproTests {
|
||||
TestBean tb2 = bean.findById("tb1").get();
|
||||
assertThat(tb2).isNotSameAs(tb);
|
||||
assertThat(cache.get("tb1").get()).isSameAs(tb2);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr15271FindsOnInterfaceWithInterfaceProxy() {
|
||||
void spr15271FindsOnInterfaceWithInterfaceProxy() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr15271ConfigA.class);
|
||||
Spr15271Interface bean = context.getBean(Spr15271Interface.class);
|
||||
Cache cache = context.getBean(CacheManager.class).getCache("itemCache");
|
||||
@@ -174,10 +177,11 @@ public class CacheReproTests {
|
||||
bean.insertItem(tb);
|
||||
assertThat(bean.findById("tb1").get()).isSameAs(tb);
|
||||
assertThat(cache.get("tb1").get()).isSameAs(tb);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr15271FindsOnInterfaceWithCglibProxy() {
|
||||
void spr15271FindsOnInterfaceWithCglibProxy() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr15271ConfigB.class);
|
||||
Spr15271Interface bean = context.getBean(Spr15271Interface.class);
|
||||
Cache cache = context.getBean(CacheManager.class).getCache("itemCache");
|
||||
@@ -186,6 +190,7 @@ public class CacheReproTests {
|
||||
bean.insertItem(tb);
|
||||
assertThat(bean.findById("tb1").get()).isSameAs(tb);
|
||||
assertThat(cache.get("tb1").get()).isSameAs(tb);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-11
@@ -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.
|
||||
@@ -52,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
|
||||
/** hook into superclass suite of tests */
|
||||
@Override
|
||||
@@ -61,26 +61,28 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStrategy() {
|
||||
void keyStrategy() {
|
||||
CacheInterceptor ci = this.ctx.getBean(CacheInterceptor.class);
|
||||
assertThat(ci.getKeyGenerator()).isSameAs(this.ctx.getBean("keyGenerator", KeyGenerator.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheErrorHandler() {
|
||||
void cacheErrorHandler() {
|
||||
CacheInterceptor ci = this.ctx.getBean(CacheInterceptor.class);
|
||||
assertThat(ci.getErrorHandler()).isSameAs(this.ctx.getBean("errorHandler", CacheErrorHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCacheManagerBean() {
|
||||
void singleCacheManagerBean() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(SingleCacheManagerConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCacheManagerBeans() {
|
||||
void multipleCacheManagerBeans() {
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(MultiCacheManagerConfig.class);
|
||||
try {
|
||||
@@ -93,14 +95,16 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCacheManagerBeans_implementsCachingConfigurer() {
|
||||
void multipleCacheManagerBeans_implementsCachingConfigurer() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(MultiCacheManagerConfigurer.class);
|
||||
ctx.refresh(); // does not throw an exception
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCachingConfigurers() {
|
||||
void multipleCachingConfigurers() {
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
|
||||
try {
|
||||
@@ -112,7 +116,8 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noCacheManagerBeans() {
|
||||
void noCacheManagerBeans() {
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(EmptyConfig.class);
|
||||
try {
|
||||
@@ -125,7 +130,7 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyConfigSupport() {
|
||||
void emptyConfigSupport() {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(EmptyConfigSupportConfig.class);
|
||||
CacheInterceptor ci = context.getBean(CacheInterceptor.class);
|
||||
assertThat(ci.getCacheResolver()).isNotNull();
|
||||
@@ -135,7 +140,7 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bothSetOnlyResolverIsUsed() {
|
||||
void bothSetOnlyResolverIsUsed() {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(FullCachingConfig.class);
|
||||
CacheInterceptor ci = context.getBean(CacheInterceptor.class);
|
||||
assertThat(ci.getCacheResolver()).isSameAs(context.getBean("cacheResolver"));
|
||||
|
||||
Vendored
+21
-13
@@ -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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cache.interceptor;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -47,7 +48,9 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CacheErrorHandlerTests {
|
||||
class CacheErrorHandlerTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
private Cache cache;
|
||||
|
||||
@@ -58,16 +61,21 @@ public class CacheErrorHandlerTests {
|
||||
private SimpleService simpleService;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
|
||||
void setup() {
|
||||
this.context = new AnnotationConfigApplicationContext(Config.class);
|
||||
this.cache = context.getBean("mockCache", Cache.class);
|
||||
this.cacheInterceptor = context.getBean(CacheInterceptor.class);
|
||||
this.errorHandler = context.getBean(CacheErrorHandler.class);
|
||||
this.simpleService = context.getBean(SimpleService.class);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFail() {
|
||||
void getFail() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get");
|
||||
willThrow(exception).given(this.cache).get(0L);
|
||||
|
||||
@@ -78,7 +86,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAndPutFail() {
|
||||
void getAndPutFail() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get");
|
||||
willThrow(exception).given(this.cache).get(0L);
|
||||
willThrow(exception).given(this.cache).put(0L, 0L); // Update of the cache will fail as well
|
||||
@@ -93,7 +101,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFailProperException() {
|
||||
void getFailProperException() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get");
|
||||
willThrow(exception).given(this.cache).get(0L);
|
||||
|
||||
@@ -105,7 +113,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putFail() {
|
||||
void putFail() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on put");
|
||||
willThrow(exception).given(this.cache).put(0L, 0L);
|
||||
|
||||
@@ -114,7 +122,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putFailProperException() {
|
||||
void putFailProperException() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on put");
|
||||
willThrow(exception).given(this.cache).put(0L, 0L);
|
||||
|
||||
@@ -126,7 +134,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictFail() {
|
||||
void evictFail() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict");
|
||||
willThrow(exception).given(this.cache).evict(0L);
|
||||
|
||||
@@ -135,7 +143,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictFailProperException() {
|
||||
void evictFailProperException() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict");
|
||||
willThrow(exception).given(this.cache).evict(0L);
|
||||
|
||||
@@ -147,7 +155,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearFail() {
|
||||
void clearFail() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict");
|
||||
willThrow(exception).given(this.cache).clear();
|
||||
|
||||
@@ -156,7 +164,7 @@ public class CacheErrorHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearFailProperException() {
|
||||
void clearFailProperException() {
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on clear");
|
||||
willThrow(exception).given(this.cache).clear();
|
||||
|
||||
|
||||
+20
-12
@@ -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.
|
||||
@@ -21,6 +21,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -31,7 +32,7 @@ import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.CachingConfigurer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -51,7 +52,9 @@ import static org.springframework.context.testfixture.cache.CacheTestUtils.asser
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
*/
|
||||
public class CacheResolverCustomizationTests {
|
||||
class CacheResolverCustomizationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@@ -61,16 +64,21 @@ public class CacheResolverCustomizationTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
|
||||
void setup() {
|
||||
this.context = new AnnotationConfigApplicationContext(Config.class);
|
||||
this.cacheManager = context.getBean("cacheManager", CacheManager.class);
|
||||
this.anotherCacheManager = context.getBean("anotherCacheManager", CacheManager.class);
|
||||
this.simpleService = context.getBean(SimpleService.class);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void noCustomization() {
|
||||
void noCustomization() {
|
||||
Cache cache = this.cacheManager.getCache("default");
|
||||
|
||||
Object key = new Object();
|
||||
@@ -81,7 +89,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customCacheResolver() {
|
||||
void customCacheResolver() {
|
||||
Cache cache = this.cacheManager.getCache("primary");
|
||||
|
||||
Object key = new Object();
|
||||
@@ -92,7 +100,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customCacheManager() {
|
||||
void customCacheManager() {
|
||||
Cache cache = this.anotherCacheManager.getCache("default");
|
||||
|
||||
Object key = new Object();
|
||||
@@ -103,7 +111,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runtimeResolution() {
|
||||
void runtimeResolution() {
|
||||
Cache defaultCache = this.cacheManager.getCache("default");
|
||||
Cache primaryCache = this.cacheManager.getCache("primary");
|
||||
|
||||
@@ -121,7 +129,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedResolution() {
|
||||
void namedResolution() {
|
||||
Cache cache = this.cacheManager.getCache("secondary");
|
||||
|
||||
Object key = new Object();
|
||||
@@ -132,7 +140,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noCacheResolved() {
|
||||
void noCacheResolved() {
|
||||
Method method = ReflectionUtils.findMethod(SimpleService.class, "noCacheResolved", Object.class);
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
this.simpleService.noCacheResolved(new Object()))
|
||||
@@ -140,7 +148,7 @@ public class CacheResolverCustomizationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownCacheResolver() {
|
||||
void unknownCacheResolver() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
|
||||
this.simpleService.unknownCacheResolver(new Object()))
|
||||
.satisfies(ex -> assertThat(ex.getBeanName()).isEqualTo("unknownCacheResolver"));
|
||||
|
||||
+52
-40
@@ -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.
|
||||
@@ -63,7 +63,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ClassPathScanningCandidateComponentProviderTests {
|
||||
class ClassPathScanningCandidateComponentProviderTests {
|
||||
|
||||
private static final String TEST_BASE_PACKAGE = "example.scannable";
|
||||
private static final String TEST_PROFILE_PACKAGE = "example.profilescan";
|
||||
@@ -75,7 +75,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void defaultsWithScan() {
|
||||
void defaultsWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -83,7 +83,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultsWithIndex() {
|
||||
void defaultsWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testDefault(provider);
|
||||
@@ -103,7 +103,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void antStylePackageWithScan() {
|
||||
void antStylePackageWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -111,7 +111,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void antStylePackageWithIndex() {
|
||||
void antStylePackageWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testAntStyle(provider);
|
||||
@@ -125,7 +125,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bogusPackageWithScan() {
|
||||
void bogusPackageWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -134,7 +134,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bogusPackageWithIndex() {
|
||||
void bogusPackageWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents("bogus");
|
||||
@@ -142,7 +142,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customFiltersFollowedByResetUseIndex() {
|
||||
void customFiltersFollowedByResetUseIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
@@ -152,7 +152,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAnnotationTypeIncludeFilterWithScan() {
|
||||
void customAnnotationTypeIncludeFilterWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -160,7 +160,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAnnotationTypeIncludeFilterWithIndex() {
|
||||
void customAnnotationTypeIncludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomAnnotationTypeIncludeFilter(provider);
|
||||
@@ -172,7 +172,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAssignableTypeIncludeFilterWithScan() {
|
||||
void customAssignableTypeIncludeFilterWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -180,7 +180,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAssignableTypeIncludeFilterWithIndex() {
|
||||
void customAssignableTypeIncludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomAssignableTypeIncludeFilter(provider);
|
||||
@@ -198,7 +198,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSupportedIncludeAndExcludedFilterWithScan() {
|
||||
void customSupportedIncludeAndExcludedFilterWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -206,7 +206,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSupportedIncludeAndExcludeFilterWithIndex() {
|
||||
void customSupportedIncludeAndExcludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomSupportedIncludeAndExcludeFilter(provider);
|
||||
@@ -225,7 +225,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSupportIncludeFilterWithNonIndexedTypeUseScan() {
|
||||
void customSupportIncludeFilterWithNonIndexedTypeUseScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
// This annotation type is not directly annotated with Indexed so we can use
|
||||
@@ -238,7 +238,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customNotSupportedIncludeFilterUseScan() {
|
||||
void customNotSupportedIncludeFilterUseScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(FooDao.class));
|
||||
@@ -249,7 +249,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void excludeFilterWithScan() {
|
||||
void excludeFilterWithScan() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
@@ -258,7 +258,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void excludeFilterWithIndex() {
|
||||
void excludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
provider.addExcludeFilter(new RegexPatternTypeFilter(Pattern.compile(TEST_BASE_PACKAGE + ".*Named.*")));
|
||||
@@ -276,14 +276,14 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithNoFilters() {
|
||||
void withNoFilters() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertThat(candidates.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithComponentAnnotationOnly() {
|
||||
void withComponentAnnotationOnly() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
provider.addExcludeFilter(new AnnotationTypeFilter(Repository.class));
|
||||
@@ -300,7 +300,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAspectAnnotationOnly() {
|
||||
void withAspectAnnotationOnly() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Aspect.class));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
@@ -309,7 +309,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInterfaceType() {
|
||||
void withInterfaceType() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(FooDao.class));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
@@ -318,7 +318,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithClassType() {
|
||||
void withClassType() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(MessageBean.class));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
@@ -327,7 +327,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithMultipleMatchingFilters() {
|
||||
void withMultipleMatchingFilters() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(FooServiceImpl.class));
|
||||
@@ -340,7 +340,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeTakesPrecedence() {
|
||||
void excludeTakesPrecedence() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(FooServiceImpl.class));
|
||||
@@ -354,14 +354,14 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithNullEnvironment() {
|
||||
void withNullEnvironment() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_PROFILE_PACKAGE);
|
||||
assertThat(containsBeanClass(candidates, ProfileAnnotatedComponent.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInactiveProfile() {
|
||||
void withInactiveProfile() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
ConfigurableEnvironment env = new StandardEnvironment();
|
||||
env.setActiveProfiles("other");
|
||||
@@ -371,7 +371,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithActiveProfile() {
|
||||
void withActiveProfile() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
ConfigurableEnvironment env = new StandardEnvironment();
|
||||
env.setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
|
||||
@@ -381,61 +381,67 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_noProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_noProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ProfileAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME)).isFalse();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_validProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_validProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.getEnvironment().setActiveProfiles(ProfileAnnotatedComponent.PROFILE_NAME);
|
||||
ctx.register(ProfileAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_validMetaAnnotatedProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_validMetaAnnotatedProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.getEnvironment().setActiveProfiles(DevComponent.PROFILE_NAME);
|
||||
ctx.register(ProfileMetaAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(ProfileMetaAnnotatedComponent.BEAN_NAME)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_invalidProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_invalidProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.getEnvironment().setActiveProfiles("other");
|
||||
ctx.register(ProfileAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(ProfileAnnotatedComponent.BEAN_NAME)).isFalse();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_invalidMetaAnnotatedProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_invalidMetaAnnotatedProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.getEnvironment().setActiveProfiles("other");
|
||||
ctx.register(ProfileMetaAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(ProfileMetaAnnotatedComponent.BEAN_NAME)).isFalse();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_defaultProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_defaultProfile() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.getEnvironment().setDefaultProfiles(TEST_DEFAULT_PROFILE_NAME);
|
||||
// no active profiles are set
|
||||
ctx.register(DefaultProfileAnnotatedComponent.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(DefaultProfileAnnotatedComponent.BEAN_NAME)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_defaultAndDevProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_defaultAndDevProfile() {
|
||||
Class<?> beanClass = DefaultAndDevProfileAnnotatedComponent.class;
|
||||
String beanName = DefaultAndDevProfileAnnotatedComponent.BEAN_NAME;
|
||||
{
|
||||
@@ -445,6 +451,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
{
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -453,6 +460,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
{
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -461,11 +469,12 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isFalse();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegrationWithAnnotationConfigApplicationContext_metaProfile() {
|
||||
void integrationWithAnnotationConfigApplicationContext_metaProfile() {
|
||||
Class<?> beanClass = MetaProfileAnnotatedComponent.class;
|
||||
String beanName = MetaProfileAnnotatedComponent.BEAN_NAME;
|
||||
{
|
||||
@@ -475,6 +484,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
{
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -483,6 +493,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
{
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -491,11 +502,12 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ctx.register(beanClass);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean(beanName)).isFalse();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void componentScanningFindsComponentsAnnotatedWithAnnotationsContainingNestedAnnotations() {
|
||||
void componentScanningFindsComponentsAnnotatedWithAnnotationsContainingNestedAnnotations() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
Set<BeanDefinition> components = provider.findCandidateComponents(AnnotatedComponent.class.getPackage().getName());
|
||||
assertThat(components).hasSize(1);
|
||||
@@ -539,12 +551,12 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
|
||||
@Profile(TEST_DEFAULT_PROFILE_NAME)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultProfile {
|
||||
@interface DefaultProfile {
|
||||
}
|
||||
|
||||
@Profile("dev")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DevProfile {
|
||||
@interface DevProfile {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -31,53 +31,59 @@ import org.springframework.context.annotation.componentscan.simple.SimpleCompone
|
||||
public class ComponentScanAndImportAnnotationInteractionTests {
|
||||
|
||||
@Test
|
||||
public void componentScanOverlapsWithImport() {
|
||||
void componentScanOverlapsWithImport() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(Config1.class);
|
||||
ctx.register(Config2.class);
|
||||
ctx.refresh(); // no conflicts found trying to register SimpleComponent
|
||||
ctx.getBean(SimpleComponent.class); // succeeds -> there is only one bean of type SimpleComponent
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void componentScanOverlapsWithImportUsingAsm() {
|
||||
void componentScanOverlapsWithImportUsingAsm() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.registerBeanDefinition("config1", new RootBeanDefinition(Config1.class.getName()));
|
||||
ctx.registerBeanDefinition("config2", new RootBeanDefinition(Config2.class.getName()));
|
||||
ctx.refresh(); // no conflicts found trying to register SimpleComponent
|
||||
ctx.getBean(SimpleComponent.class); // succeeds -> there is only one bean of type SimpleComponent
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void componentScanViaImport() {
|
||||
void componentScanViaImport() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(Config3.class);
|
||||
ctx.refresh();
|
||||
ctx.getBean(SimpleComponent.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void componentScanViaImportUsingAsm() {
|
||||
void componentScanViaImportUsingAsm() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.registerBeanDefinition("config", new RootBeanDefinition(Config3.class.getName()));
|
||||
ctx.refresh();
|
||||
ctx.getBean(SimpleComponent.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void componentScanViaImportUsingScan() {
|
||||
void componentScanViaImportUsingScan() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.scan("org.springframework.context.annotation.componentscan.importing");
|
||||
ctx.refresh();
|
||||
ctx.getBean(SimpleComponent.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void circularImportViaComponentScan() {
|
||||
void circularImportViaComponentScan() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.registerBeanDefinition("config", new RootBeanDefinition(ImportingConfig.class.getName()));
|
||||
ctx.refresh();
|
||||
ctx.getBean(SimpleComponent.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
-5
@@ -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.
|
||||
@@ -25,7 +25,6 @@ import org.springframework.context.annotation.componentscan.level3.Level3Compone
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* Tests ensuring that configuration classes marked with @ComponentScan
|
||||
* may be processed recursively
|
||||
@@ -33,10 +32,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ComponentScanAnnotationRecursionTests {
|
||||
class ComponentScanAnnotationRecursionTests {
|
||||
|
||||
@Test
|
||||
public void recursion() {
|
||||
void recursion() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(Level1Config.class);
|
||||
ctx.refresh();
|
||||
@@ -49,14 +48,19 @@ public class ComponentScanAnnotationRecursionTests {
|
||||
// assert that enhancement is working
|
||||
assertThat(ctx.getBean("level1Bean")).isSameAs(ctx.getBean("level1Bean"));
|
||||
assertThat(ctx.getBean("level2Bean")).isSameAs(ctx.getBean("level2Bean"));
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
public void evenCircularScansAreSupported() {
|
||||
@Test
|
||||
void evenCircularScansAreSupported() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(LeftConfig.class); // left scans right, and right scans left
|
||||
ctx.refresh();
|
||||
ctx.getBean("leftConfig"); // but this is handled gracefully
|
||||
ctx.getBean("rightConfig"); // and beans from both packages are available
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-8
@@ -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.
|
||||
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -29,33 +28,35 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ComponentScanParserWithUserDefinedStrategiesTests {
|
||||
class ComponentScanParserWithUserDefinedStrategiesTests {
|
||||
|
||||
@Test
|
||||
public void testCustomBeanNameGenerator() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
void customBeanNameGenerator() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/customNameGeneratorTests.xml");
|
||||
assertThat(context.containsBean("testing.fooServiceImpl")).isTrue();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomScopeMetadataResolver() {
|
||||
void customScopeMetadataResolver() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/customScopeResolverTests.xml");
|
||||
BeanDefinition bd = context.getBeanFactory().getBeanDefinition("fooServiceImpl");
|
||||
assertThat(bd.getScope()).isEqualTo("myCustomScope");
|
||||
assertThat(bd.isSingleton()).isFalse();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidConstructorBeanNameGenerator() {
|
||||
void invalidConstructorBeanNameGenerator() {
|
||||
assertThatExceptionOfType(BeansException.class).isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/invalidConstructorNameGeneratorTests.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidClassNameScopeMetadataResolver() {
|
||||
void invalidClassNameScopeMetadataResolver() {
|
||||
assertThatExceptionOfType(BeansException.class).isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/invalidClassNameScopeResolverTests.xml"));
|
||||
|
||||
+13
-17
@@ -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,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* Tests semantics of declaring {@link BeanFactoryPostProcessor}-returning @Bean
|
||||
* methods, specifically as regards static @Bean methods and the avoidance of
|
||||
@@ -33,25 +32,34 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ConfigurationClassAndBFPPTests {
|
||||
class ConfigurationClassAndBFPPTests {
|
||||
|
||||
@Test
|
||||
public void autowiringFailsWithBFPPAsInstanceMethod() {
|
||||
void autowiringFailsWithBFPPAsInstanceMethod() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(TestBeanConfig.class, AutowiredConfigWithBFPPAsInstanceMethod.class);
|
||||
ctx.refresh();
|
||||
// instance method BFPP interferes with lifecycle -> autowiring fails!
|
||||
// WARN-level logging should have been issued about returning BFPP from non-static @Bean method
|
||||
assertThat(ctx.getBean(AutowiredConfigWithBFPPAsInstanceMethod.class).autowiredTestBean).isNull();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autowiringSucceedsWithBFPPAsStaticMethod() {
|
||||
void autowiringSucceedsWithBFPPAsStaticMethod() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(TestBeanConfig.class, AutowiredConfigWithBFPPAsStaticMethod.class);
|
||||
ctx.refresh();
|
||||
// static method BFPP does not interfere with lifecycle -> autowiring succeeds
|
||||
assertThat(ctx.getBean(AutowiredConfigWithBFPPAsStaticMethod.class).autowiredTestBean).isNotNull();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void staticBeanMethodsDoNotRespectScoping() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithStaticBeanMethod.class);
|
||||
assertThat(ConfigWithStaticBeanMethod.testBean()).isNotSameAs(ConfigWithStaticBeanMethod.testBean());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +71,6 @@ public class ConfigurationClassAndBFPPTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class AutowiredConfigWithBFPPAsInstanceMethod {
|
||||
@Autowired TestBean autowiredTestBean;
|
||||
@@ -76,7 +83,6 @@ public class ConfigurationClassAndBFPPTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class AutowiredConfigWithBFPPAsStaticMethod {
|
||||
@Autowired TestBean autowiredTestBean;
|
||||
@@ -89,16 +95,6 @@ public class ConfigurationClassAndBFPPTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void staticBeanMethodsDoNotRespectScoping() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithStaticBeanMethod.class);
|
||||
ctx.refresh();
|
||||
assertThat(ConfigWithStaticBeanMethod.testBean()).isNotSameAs(ConfigWithStaticBeanMethod.testBean());
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithStaticBeanMethod {
|
||||
@Bean
|
||||
|
||||
+34
-22
@@ -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.
|
||||
@@ -54,7 +54,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -389,6 +389,7 @@ class ConfigurationClassPostProcessorTests {
|
||||
.withMessageContaining("alias 'taskExecutor'")
|
||||
.withMessageContaining("name 'applicationTaskExecutor'")
|
||||
.withMessageContaining("bean definition 'taskExecutor'");
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -998,118 +999,129 @@ class ConfigurationClassPostProcessorTests {
|
||||
|
||||
@Test
|
||||
void testPrototypeArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithPrototype.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithPrototype.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSingletonArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithSingleton.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithSingleton.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithNull.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithNull.class);
|
||||
ctx.getBean("aFoo");
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectionPointMatchForNarrowTargetReturnType() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(FooBarConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(FooBarConfiguration.class);
|
||||
assertThat(ctx.getBean(FooImpl.class).bar).isSameAs(ctx.getBean(BarImpl.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class, TestBean.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class, TestBean.class);
|
||||
VarargConfiguration bean = ctx.getBean(VarargConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.length).isEqualTo(1);
|
||||
assertThat(bean.testBeans[0]).isSameAs(ctx.getBean(TestBean.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyVarargOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class);
|
||||
VarargConfiguration bean = ctx.getBean(VarargConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.length).isEqualTo(0);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCollectionArgumentOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class, TestBean.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class, TestBean.class);
|
||||
CollectionArgumentConfiguration bean = ctx.getBean(CollectionArgumentConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.size()).isEqualTo(1);
|
||||
assertThat(bean.testBeans.get(0)).isSameAs(ctx.getBean(TestBean.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyCollectionArgumentOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class);
|
||||
CollectionArgumentConfiguration bean = ctx.getBean(CollectionArgumentConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.isEmpty()).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMapArgumentOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class, DummyRunnable.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class, DummyRunnable.class);
|
||||
MapArgumentConfiguration bean = ctx.getBean(MapArgumentConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.size()).isEqualTo(1);
|
||||
assertThat(bean.testBeans.values().iterator().next()).isSameAs(ctx.getBean(Runnable.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyMapArgumentOnBeanMethod() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class);
|
||||
MapArgumentConfiguration bean = ctx.getBean(MapArgumentConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.isEmpty()).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCollectionInjectionFromSameConfigurationClass() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionInjectionConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionInjectionConfiguration.class);
|
||||
CollectionInjectionConfiguration bean = ctx.getBean(CollectionInjectionConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.size()).isEqualTo(1);
|
||||
assertThat(bean.testBeans.get(0)).isSameAs(ctx.getBean(TestBean.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMapInjectionFromSameConfigurationClass() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapInjectionConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(MapInjectionConfiguration.class);
|
||||
MapInjectionConfiguration bean = ctx.getBean(MapInjectionConfiguration.class);
|
||||
assertThat(bean.testBeans).isNotNull();
|
||||
assertThat(bean.testBeans.size()).isEqualTo(1);
|
||||
assertThat(bean.testBeans.get("testBean")).isSameAs(ctx.getBean(Runnable.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBeanLookupFromSameConfigurationClass() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanLookupConfiguration.class);
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(BeanLookupConfiguration.class);
|
||||
BeanLookupConfiguration bean = ctx.getBean(BeanLookupConfiguration.class);
|
||||
assertThat(bean.getTestBean()).isNotNull();
|
||||
assertThat(bean.getTestBean()).isSameAs(ctx.getBean(TestBean.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameClashBetweenConfigurationClassAndBean() {
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() -> {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyTestBean.class);
|
||||
ctx.getBean("myTestBean", TestBean.class);
|
||||
});
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class)
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(MyTestBean.class).getBean("myTestBean", TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBeanDefinitionRegistryPostProcessorConfig() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanDefinitionRegistryPostProcessorConfig.class);
|
||||
boolean condition = ctx.getBean("myTestBean") instanceof TestBean;
|
||||
assertThat(condition).isTrue();
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(BeanDefinitionRegistryPostProcessorConfig.class);
|
||||
assertThat(ctx.getBean("myTestBean")).isInstanceOf(TestBean.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-9
@@ -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.
|
||||
@@ -32,63 +32,70 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ConfigurationWithFactoryBeanAndAutowiringTests {
|
||||
class ConfigurationWithFactoryBeanAndAutowiringTests {
|
||||
|
||||
@Test
|
||||
public void withConcreteFactoryBeanImplementationAsReturnType() {
|
||||
void withConcreteFactoryBeanImplementationAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(ConcreteFactoryBeanImplementationConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withParameterizedFactoryBeanImplementationAsReturnType() {
|
||||
void withParameterizedFactoryBeanImplementationAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(ParameterizedFactoryBeanImplementationConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
void withParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(ParameterizedFactoryBeanInterfaceConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withNonPublicParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
void withNonPublicParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(NonPublicParameterizedFactoryBeanInterfaceConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRawFactoryBeanInterfaceAsReturnType() {
|
||||
void withRawFactoryBeanInterfaceAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(RawFactoryBeanInterfaceConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withWildcardParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
void withWildcardParameterizedFactoryBeanInterfaceAsReturnType() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(WildcardParameterizedFactoryBeanInterfaceConfig.class);
|
||||
ctx.refresh();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withFactoryBeanCallingBean() {
|
||||
void withFactoryBeanCallingBean() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AppConfig.class);
|
||||
ctx.register(FactoryBeanCallingConfig.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.getBean("myString")).isEqualTo("true");
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-8
@@ -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.
|
||||
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -33,12 +33,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ConfigurationWithFactoryBeanAndParametersTests {
|
||||
class ConfigurationWithFactoryBeanAndParametersTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class, Bar.class);
|
||||
void test() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class, Bar.class);
|
||||
assertThat(ctx.getBean(Bar.class).foo).isNotNull();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +52,9 @@ public class ConfigurationWithFactoryBeanAndParametersTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class Foo {
|
||||
}
|
||||
|
||||
|
||||
static class Bar {
|
||||
|
||||
Foo foo;
|
||||
@@ -66,7 +65,6 @@ public class ConfigurationWithFactoryBeanAndParametersTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class FooFactoryBean implements FactoryBean<Foo> {
|
||||
|
||||
@Override
|
||||
|
||||
+20
-15
@@ -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.
|
||||
@@ -38,30 +38,33 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class EnableAspectJAutoProxyTests {
|
||||
class EnableAspectJAutoProxyTests {
|
||||
|
||||
@Test
|
||||
public void withJdkProxy() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithJdkProxy.class);
|
||||
void withJdkProxy() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithJdkProxy.class);
|
||||
|
||||
aspectIsApplied(ctx);
|
||||
assertThat(AopUtils.isJdkDynamicProxy(ctx.getBean(FooService.class))).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withCglibProxy() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithCglibProxy.class);
|
||||
void withCglibProxy() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithCglibProxy.class);
|
||||
|
||||
aspectIsApplied(ctx);
|
||||
assertThat(AopUtils.isCglibProxy(ctx.getBean(FooService.class))).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withExposedProxy() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithExposedProxy.class);
|
||||
void withExposedProxy() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithExposedProxy.class);
|
||||
|
||||
aspectIsApplied(ctx);
|
||||
assertThat(AopUtils.isJdkDynamicProxy(ctx.getBean(FooService.class))).isTrue();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
private void aspectIsApplied(ApplicationContext ctx) {
|
||||
@@ -82,7 +85,7 @@ public class EnableAspectJAutoProxyTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAnnotationOnArgumentAndJdkProxy() {
|
||||
void withAnnotationOnArgumentAndJdkProxy() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
ConfigWithJdkProxy.class, SampleService.class, LoggingAspect.class);
|
||||
|
||||
@@ -91,10 +94,11 @@ public class EnableAspectJAutoProxyTests {
|
||||
sampleService.execute(new SampleInputBean());
|
||||
sampleService.execute((SampleDto) null);
|
||||
sampleService.execute((SampleInputBean) null);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAnnotationOnArgumentAndCglibProxy() {
|
||||
void withAnnotationOnArgumentAndCglibProxy() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
ConfigWithCglibProxy.class, SampleService.class, LoggingAspect.class);
|
||||
|
||||
@@ -103,6 +107,7 @@ public class EnableAspectJAutoProxyTests {
|
||||
sampleService.execute(new SampleInputBean());
|
||||
sampleService.execute((SampleDto) null);
|
||||
sampleService.execute((SampleInputBean) null);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +128,7 @@ public class EnableAspectJAutoProxyTests {
|
||||
static class ConfigWithExposedProxy {
|
||||
|
||||
@Bean
|
||||
public FooService fooServiceImpl(final ApplicationContext context) {
|
||||
FooService fooServiceImpl(final ApplicationContext context) {
|
||||
return new FooServiceImpl() {
|
||||
@Override
|
||||
public String foo(int id) {
|
||||
@@ -140,20 +145,20 @@ public class EnableAspectJAutoProxyTests {
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Loggable {
|
||||
@interface Loggable {
|
||||
}
|
||||
|
||||
|
||||
@Loggable
|
||||
public static class SampleDto {
|
||||
static class SampleDto {
|
||||
}
|
||||
|
||||
|
||||
public static class SampleInputBean {
|
||||
static class SampleInputBean {
|
||||
}
|
||||
|
||||
|
||||
public static class SampleService {
|
||||
static class SampleService {
|
||||
|
||||
// Not matched method on {@link LoggingAspect}.
|
||||
public void execute(SampleInputBean inputBean) {
|
||||
|
||||
+10
-6
@@ -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.
|
||||
@@ -35,26 +35,28 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class EnableLoadTimeWeavingTests {
|
||||
class EnableLoadTimeWeavingTests {
|
||||
|
||||
@Test
|
||||
public void control() {
|
||||
void control() {
|
||||
GenericXmlApplicationContext ctx =
|
||||
new GenericXmlApplicationContext(getClass(), "EnableLoadTimeWeavingTests-context.xml");
|
||||
ctx.getBean("loadTimeWeaver", LoadTimeWeaver.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLTW_withAjWeavingDisabled() {
|
||||
void enableLTW_withAjWeavingDisabled() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(EnableLTWConfig_withAjWeavingDisabled.class);
|
||||
ctx.refresh();
|
||||
LoadTimeWeaver loadTimeWeaver = ctx.getBean("loadTimeWeaver", LoadTimeWeaver.class);
|
||||
verifyNoInteractions(loadTimeWeaver);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLTW_withAjWeavingAutodetect() {
|
||||
void enableLTW_withAjWeavingAutodetect() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(EnableLTWConfig_withAjWeavingAutodetect.class);
|
||||
ctx.refresh();
|
||||
@@ -62,15 +64,17 @@ public class EnableLoadTimeWeavingTests {
|
||||
// no expectations -> a class file transformer should NOT be added
|
||||
// because no META-INF/aop.xml is present on the classpath
|
||||
verifyNoInteractions(loadTimeWeaver);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableLTW_withAjWeavingEnabled() {
|
||||
void enableLTW_withAjWeavingEnabled() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(EnableLTWConfig_withAjWeavingEnabled.class);
|
||||
ctx.refresh();
|
||||
LoadTimeWeaver loadTimeWeaver = ctx.getBean("loadTimeWeaver", LoadTimeWeaver.class);
|
||||
verify(loadTimeWeaver).addTransformer(isA(ClassFileTransformer.class));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+21
-12
@@ -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.
|
||||
@@ -39,17 +39,18 @@ import org.springframework.util.Assert;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests that an ImportAware @Configuration classes gets injected with the
|
||||
* Tests that an ImportAware @Configuration class gets injected with the
|
||||
* annotation metadata of the @Configuration class that imported it.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ImportAwareTests {
|
||||
class ImportAwareTests {
|
||||
|
||||
@Test
|
||||
public void directlyAnnotatedWithImport() {
|
||||
@SuppressWarnings("resource")
|
||||
void directlyAnnotatedWithImport() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ImportingConfig.class);
|
||||
ctx.refresh();
|
||||
@@ -65,7 +66,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indirectlyAnnotatedWithImport() {
|
||||
@SuppressWarnings("resource")
|
||||
void indirectlyAnnotatedWithImport() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(IndirectlyImportingConfig.class);
|
||||
ctx.refresh();
|
||||
@@ -81,7 +83,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directlyAnnotatedWithImportLite() {
|
||||
@SuppressWarnings("resource")
|
||||
void directlyAnnotatedWithImportLite() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ImportingConfigLite.class);
|
||||
ctx.refresh();
|
||||
@@ -97,7 +100,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importRegistrar() {
|
||||
@SuppressWarnings("resource")
|
||||
void importRegistrar() {
|
||||
ImportedRegistrar.called = false;
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ImportingRegistrarConfig.class);
|
||||
@@ -107,7 +111,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importRegistrarWithImport() {
|
||||
@SuppressWarnings("resource")
|
||||
void importRegistrarWithImport() {
|
||||
ImportedRegistrar.called = false;
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ImportingRegistrarConfigWithImport.class);
|
||||
@@ -119,7 +124,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataFromImportsOneThenTwo() {
|
||||
@SuppressWarnings("resource")
|
||||
void metadataFromImportsOneThenTwo() {
|
||||
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
|
||||
ConfigurationOne.class, ConfigurationTwo.class)
|
||||
.getBean(MetadataHolder.class).importMetadata;
|
||||
@@ -127,7 +133,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataFromImportsTwoThenOne() {
|
||||
@SuppressWarnings("resource")
|
||||
void metadataFromImportsTwoThenOne() {
|
||||
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
|
||||
ConfigurationTwo.class, ConfigurationOne.class)
|
||||
.getBean(MetadataHolder.class).importMetadata;
|
||||
@@ -135,7 +142,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataFromImportsOneThenThree() {
|
||||
@SuppressWarnings("resource")
|
||||
void metadataFromImportsOneThenThree() {
|
||||
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
|
||||
ConfigurationOne.class, ConfigurationThree.class)
|
||||
.getBean(MetadataHolder.class).importMetadata;
|
||||
@@ -143,7 +151,8 @@ public class ImportAwareTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importAwareWithAnnotationAttributes() {
|
||||
@SuppressWarnings("resource")
|
||||
void importAwareWithAnnotationAttributes() {
|
||||
new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user