mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f19fa5d8e | |||
| 208d52d852 | |||
| 18c3b637e4 | |||
| 34c69bfc67 | |||
| 37d7af42ac | |||
| cc986cd2e8 | |||
| 0141725638 | |||
| 0c2ba4e38e | |||
| c6a9aa59a3 | |||
| ad949a7450 | |||
| 86b2617c7f | |||
| 760376c318 | |||
| 5b6abe4c13 | |||
| 7a839e988a | |||
| 46859d6391 | |||
| 573e74b8bd | |||
| 6c231804a0 | |||
| 7c3913050a | |||
| ec488282a8 | |||
| 911cdb2ad0 | |||
| 0f83c483bb | |||
| c9050607bc | |||
| 5e82ee6bd7 |
+1
-1
@@ -102,7 +102,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
// TODO Uncomment link to JUnit 5 docs once we execute Gradle with Java 18+.
|
||||
// See https://github.com/spring-projects/spring-framework/issues/27497
|
||||
//
|
||||
// "https://junit.org/junit5/docs/5.12.0/api/",
|
||||
// "https://junit.org/junit5/docs/5.12.1/api/",
|
||||
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
|
||||
//"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
|
||||
"https://r2dbc.io/spec/1.0.0.RELEASE/api/",
|
||||
|
||||
@@ -45,6 +45,7 @@ dependencies {
|
||||
api(project(":spring-aspects"))
|
||||
api(project(":spring-context"))
|
||||
api(project(":spring-context-support"))
|
||||
api(project(":spring-core-test"))
|
||||
api(project(":spring-jdbc"))
|
||||
api(project(":spring-jms"))
|
||||
api(project(":spring-test"))
|
||||
@@ -66,9 +67,9 @@ dependencies {
|
||||
api("org.apache.activemq:activemq-ra:6.1.2")
|
||||
api("org.apache.commons:commons-dbcp2:2.11.0")
|
||||
api("org.aspectj:aspectjweaver")
|
||||
api("org.assertj:assertj-core")
|
||||
api("org.eclipse.jetty.websocket:jetty-websocket-jetty-api")
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
api("org.junit.jupiter:junit-jupiter-api")
|
||||
|
||||
implementation(project(":spring-core-test"))
|
||||
implementation("org.assertj:assertj-core")
|
||||
}
|
||||
|
||||
@@ -47,8 +47,7 @@ out-of-container tests for code that depends on environment-specific properties.
|
||||
The `org.springframework.mock.web` package contains a comprehensive set of Servlet API
|
||||
mock objects that are useful for testing web contexts, controllers, and filters. These
|
||||
mock objects are targeted at usage with Spring's Web MVC framework and are generally more
|
||||
convenient to use than dynamic mock objects (such as https://easymock.org/[EasyMock])
|
||||
or alternative Servlet API mock objects (such as http://www.mockobjects.com[MockObjects]).
|
||||
convenient to use than dynamic mock objects (such as https://easymock.org/[EasyMock]).
|
||||
|
||||
TIP: Since Spring Framework 6.0, the mock objects in `org.springframework.mock.web` are
|
||||
based on the Servlet 6.0 API.
|
||||
|
||||
@@ -225,9 +225,9 @@ The following table shows the templating libraries that we have tested on differ
|
||||
|Scripting Library |Scripting Engine
|
||||
|https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://facebook.github.io/react/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]
|
||||
|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]
|
||||
|===
|
||||
|
||||
@@ -57,7 +57,7 @@ locale and language specific resource bundles.
|
||||
For further custom handling of method validation errors, you can extend
|
||||
`ResponseEntityExceptionHandler` or use an `@ExceptionHandler` method in a controller
|
||||
or in a `@ControllerAdvice`, and handle `HandlerMethodValidationException` directly.
|
||||
The exception contains a list of``ParameterValidationResult``s that group validation errors
|
||||
The exception contains a list of ``ParameterValidationResult``s that group validation errors
|
||||
by method parameter. You can either iterate over those, or provide a visitor with callback
|
||||
methods by controller method parameter type:
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ templating libraries on different script engines:
|
||||
|Scripting Library |Scripting Engine
|
||||
|https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://facebook.github.io/react/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]
|
||||
|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]
|
||||
|===
|
||||
|
||||
@@ -57,7 +57,7 @@ locale and language specific resource bundles.
|
||||
For further custom handling of method validation errors, you can extend
|
||||
`ResponseEntityExceptionHandler` or use an `@ExceptionHandler` method in a controller
|
||||
or in a `@ControllerAdvice`, and handle `HandlerMethodValidationException` directly.
|
||||
The exception contains a list of``ParameterValidationResult``s that group validation errors
|
||||
The exception contains a list of ``ParameterValidationResult``s that group validation errors
|
||||
by method parameter. You can either iterate over those, or provide a visitor with callback
|
||||
methods by controller method parameter type:
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ reference documentation, including:
|
||||
* {docs-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection]
|
||||
* {docs-spring-security}/features/exploits/headers.html[Security Response Headers]
|
||||
|
||||
https://hdiv.org/[HDIV] is another web security framework that integrates with Spring MVC.
|
||||
https://github.com/hdiv/hdiv[HDIV] is another web security framework that integrates with Spring MVC.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ dependencies {
|
||||
api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.17"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3"))
|
||||
api(platform("org.junit:junit-bom:5.12.0"))
|
||||
api(platform("org.mockito:mockito-bom:5.16.0"))
|
||||
api(platform("org.junit:junit-bom:5.12.1"))
|
||||
api(platform("org.mockito:mockito-bom:5.16.1"))
|
||||
|
||||
constraints {
|
||||
api("com.fasterxml:aalto-xml:1.3.2")
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=6.2.4-SNAPSHOT
|
||||
version=6.2.5
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
|
||||
+11
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -241,7 +241,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
try {
|
||||
int algorithmicStep = STEP_JOIN_POINT_BINDING;
|
||||
while ((this.numberOfRemainingUnboundArguments > 0) && algorithmicStep < STEP_FINISHED) {
|
||||
while (this.numberOfRemainingUnboundArguments > 0 && algorithmicStep < STEP_FINISHED) {
|
||||
switch (algorithmicStep++) {
|
||||
case STEP_JOIN_POINT_BINDING -> {
|
||||
if (!maybeBindThisJoinPoint()) {
|
||||
@@ -373,7 +373,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
if (this.returningName != null) {
|
||||
if (this.numberOfRemainingUnboundArguments > 1) {
|
||||
throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName +
|
||||
"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates.");
|
||||
"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates. " +
|
||||
"Consider compiling with -parameters in order to make declared parameter names available.");
|
||||
}
|
||||
|
||||
// We're all set... find the unbound parameter, and bind it.
|
||||
@@ -485,8 +486,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
*/
|
||||
private void maybeBindThisOrTargetOrArgsFromPointcutExpression() {
|
||||
if (this.numberOfRemainingUnboundArguments > 1) {
|
||||
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
|
||||
+ " unbound args at this()/target()/args() binding stage, with no way to determine between them");
|
||||
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments +
|
||||
" unbound args at this()/target()/args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
List<String> varNames = new ArrayList<>();
|
||||
@@ -535,8 +536,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
private void maybeBindReferencePointcutParameter() {
|
||||
if (this.numberOfRemainingUnboundArguments > 1) {
|
||||
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
|
||||
+ " unbound args at reference pointcut binding stage, with no way to determine between them");
|
||||
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments +
|
||||
" unbound args at reference pointcut binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
List<String> varNames = new ArrayList<>();
|
||||
@@ -741,7 +742,9 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* Simple record to hold the extracted text from a pointcut body, together
|
||||
* with the number of tokens consumed in extracting it.
|
||||
*/
|
||||
private record PointcutBody(int numTokensConsumed, @Nullable String text) {}
|
||||
private record PointcutBody(int numTokensConsumed, @Nullable String text) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thrown in response to an ambiguous binding being detected when
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 +46,8 @@ public class AspectEntry implements ParseState.Entry {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'"
|
||||
: "ref='" + this.ref + "'");
|
||||
return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" :
|
||||
"ref='" + this.ref + "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -198,8 +198,8 @@ public abstract class ClassFilters {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof NegateClassFilter that
|
||||
&& this.original.equals(that.original)));
|
||||
return (this == other || (other instanceof NegateClassFilter that &&
|
||||
this.original.equals(that.original)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -378,8 +378,8 @@ public abstract class MethodMatchers {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof NegateMethodMatcher that
|
||||
&& this.original.equals(that.original)));
|
||||
return (this == other || (other instanceof NegateMethodMatcher that &&
|
||||
this.original.equals(that.original)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+31
-34
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -203,7 +203,6 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
itb.getSpouse();
|
||||
|
||||
assertThat(maaif.isMaterialized()).isTrue();
|
||||
|
||||
assertThat(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null)).isTrue();
|
||||
|
||||
assertThat(itb.getAge()).as("Around advice must apply").isEqualTo(0);
|
||||
@@ -301,7 +300,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
void bindingWithMultipleArgsDifferentlyOrdered() {
|
||||
ManyValuedArgs target = new ManyValuedArgs();
|
||||
ManyValuedArgs mva = createProxy(target, ManyValuedArgs.class,
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean")));
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean")));
|
||||
|
||||
String a = "a";
|
||||
int b = 12;
|
||||
@@ -320,7 +319,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
NotLockable notLockableTarget = new NotLockable();
|
||||
assertThat(notLockableTarget).isNotInstanceOf(Lockable.class);
|
||||
NotLockable notLockable1 = createProxy(notLockableTarget, NotLockable.class,
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
assertThat(notLockable1).isInstanceOf(Lockable.class);
|
||||
Lockable lockable = (Lockable) notLockable1;
|
||||
assertThat(lockable.locked()).isFalse();
|
||||
@@ -329,7 +328,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
NotLockable notLockable2Target = new NotLockable();
|
||||
NotLockable notLockable2 = createProxy(notLockable2Target, NotLockable.class,
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
assertThat(notLockable2).isInstanceOf(Lockable.class);
|
||||
Lockable lockable2 = (Lockable) notLockable2;
|
||||
assertThat(lockable2.locked()).isFalse();
|
||||
@@ -343,20 +342,19 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
void introductionAdvisorExcludedFromTargetImplementingInterface() {
|
||||
assertThat(AopUtils.findAdvisorsThatCanApply(
|
||||
getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
CannotBeUnlocked.class)).isEmpty();
|
||||
assertThat(AopUtils.findAdvisorsThatCanApply(getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
|
||||
aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void introductionOnTargetImplementingInterface() {
|
||||
CannotBeUnlocked target = new CannotBeUnlocked();
|
||||
Lockable proxy = createProxy(target, CannotBeUnlocked.class,
|
||||
// Ensure that we exclude
|
||||
AopUtils.findAdvisorsThatCanApply(
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
CannotBeUnlocked.class));
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
CannotBeUnlocked.class));
|
||||
assertThat(proxy).isInstanceOf(Lockable.class);
|
||||
Lockable lockable = proxy;
|
||||
assertThat(lockable.locked()).as("Already locked").isTrue();
|
||||
@@ -370,8 +368,8 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
ArrayList<Object> target = new ArrayList<>();
|
||||
List<?> proxy = createProxy(target, List.class,
|
||||
AopUtils.findAdvisorsThatCanApply(
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
List.class));
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
List.class));
|
||||
assertThat(proxy).as("Type pattern must have excluded mixin").isNotInstanceOf(Lockable.class);
|
||||
}
|
||||
|
||||
@@ -379,7 +377,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
void introductionBasedOnAnnotationMatch() { // gh-9980
|
||||
AnnotatedTarget target = new AnnotatedTargetImpl();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean"));
|
||||
aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean"));
|
||||
Object proxy = createProxy(target, AnnotatedTarget.class, advisors);
|
||||
assertThat(proxy).isInstanceOf(Lockable.class);
|
||||
Lockable lockable = (Lockable) proxy;
|
||||
@@ -393,9 +391,9 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
TestBean target = new TestBean();
|
||||
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean"));
|
||||
aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean"));
|
||||
advisors.addAll(getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
|
||||
Modifiable modifiable = (Modifiable) createProxy(target, ITestBean.class, advisors);
|
||||
assertThat(modifiable).isInstanceOf(Modifiable.class);
|
||||
@@ -426,7 +424,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
TestBean target = new TestBean();
|
||||
UnsupportedOperationException expectedException = new UnsupportedOperationException();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
assertThat(advisors).as("One advice method was found").hasSize(1);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(itb::getAge);
|
||||
@@ -439,12 +437,12 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
TestBean target = new TestBean();
|
||||
RemoteException expectedException = new RemoteException();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
assertThat(advisors).as("One advice method was found").hasSize(1);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
assertThatExceptionOfType(UndeclaredThrowableException.class)
|
||||
.isThrownBy(itb::getAge)
|
||||
.withCause(expectedException);
|
||||
.isThrownBy(itb::getAge)
|
||||
.withCause(expectedException);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -452,7 +450,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
TestBean target = new TestBean();
|
||||
TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(twoAdviceAspect, "someBean"));
|
||||
aspectInstanceFactory(twoAdviceAspect, "someBean"));
|
||||
assertThat(advisors).as("Two advice methods found").hasSize(2);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
itb.setName("");
|
||||
@@ -466,7 +464,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
void afterAdviceTypes() throws Exception {
|
||||
InvocationTrackingAspect aspect = new InvocationTrackingAspect();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(aspect, "exceptionHandlingAspect"));
|
||||
aspectInstanceFactory(aspect, "exceptionHandlingAspect"));
|
||||
Echo echo = createProxy(new Echo(), Echo.class, advisors);
|
||||
|
||||
assertThat(aspect.invocations).isEmpty();
|
||||
@@ -475,7 +473,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatExceptionOfType(FileNotFoundException.class)
|
||||
.isThrownBy(() -> echo.echo(new FileNotFoundException()));
|
||||
.isThrownBy(() -> echo.echo(new FileNotFoundException()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
|
||||
}
|
||||
|
||||
@@ -487,7 +485,6 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
assertThat(Modifier.isAbstract(aspect.getClass().getSuperclass().getModifiers())).isFalse();
|
||||
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(aspectInstanceFactory(aspect, "incrementingAspect"));
|
||||
|
||||
ITestBean proxy = createProxy(new TestBean("Jane", 42), ITestBean.class, advisors);
|
||||
assertThat(proxy.getAge()).isEqualTo(86); // (42 + 1) * 2
|
||||
}
|
||||
@@ -812,20 +809,20 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
invocations.add("before");
|
||||
}
|
||||
|
||||
@AfterReturning("echo()")
|
||||
void afterReturning() {
|
||||
invocations.add("after returning");
|
||||
}
|
||||
|
||||
@AfterThrowing("echo()")
|
||||
void afterThrowing() {
|
||||
invocations.add("after throwing");
|
||||
}
|
||||
|
||||
@After("echo()")
|
||||
void after() {
|
||||
invocations.add("after");
|
||||
}
|
||||
|
||||
@AfterReturning(pointcut = "this(target) && execution(* echo(*))", returning = "returnValue")
|
||||
void afterReturning(JoinPoint joinPoint, Echo target, Object returnValue) {
|
||||
invocations.add("after returning");
|
||||
}
|
||||
|
||||
@AfterThrowing(pointcut = "this(target) && execution(* echo(*))", throwing = "exception")
|
||||
void afterThrowing(JoinPoint joinPoint, Echo target, Throwable exception) {
|
||||
invocations.add("after throwing");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -967,7 +964,7 @@ abstract class AbstractMakeModifiable {
|
||||
class MakeITestBeanModifiable extends AbstractMakeModifiable {
|
||||
|
||||
@DeclareParents(value = "org.springframework.beans.testfixture.beans.ITestBean+",
|
||||
defaultImpl=ModifiableImpl.class)
|
||||
defaultImpl = ModifiableImpl.class)
|
||||
static MutableModifiable mixin;
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -27,13 +27,12 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link AsyncExecutionInterceptor}.
|
||||
*
|
||||
|
||||
@@ -274,7 +274,7 @@ public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
|
||||
* @see #orderedStream(Predicate)
|
||||
*/
|
||||
default Stream<T> stream(Predicate<Class<?>> customFilter) {
|
||||
return stream().filter(obj -> customFilter.test(obj.getClass()));
|
||||
return stream(customFilter, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,6 +288,44 @@ public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
|
||||
* @see #stream(Predicate)
|
||||
*/
|
||||
default Stream<T> orderedStream(Predicate<Class<?>> customFilter) {
|
||||
return orderedStream(customFilter, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a custom-filtered {@link Stream} over all matching object instances,
|
||||
* without specific ordering guarantees (but typically in registration order).
|
||||
* @param customFilter a custom type filter for selecting beans among the raw
|
||||
* bean type matches (or {@link #UNFILTERED} for all raw type matches without
|
||||
* any default filtering)
|
||||
* @param includeNonSingletons whether to include prototype or scoped beans too
|
||||
* or just singletons (also applies to FactoryBeans)
|
||||
* @since 6.2.5
|
||||
* @see #stream(Predicate)
|
||||
* @see #orderedStream(Predicate, boolean)
|
||||
*/
|
||||
default Stream<T> stream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
if (!includeNonSingletons) {
|
||||
throw new UnsupportedOperationException("Only supports includeNonSingletons=true by default");
|
||||
}
|
||||
return stream().filter(obj -> customFilter.test(obj.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a custom-filtered {@link Stream} over all matching object instances,
|
||||
* pre-ordered according to the factory's common order comparator.
|
||||
* @param customFilter a custom type filter for selecting beans among the raw
|
||||
* bean type matches (or {@link #UNFILTERED} for all raw type matches without
|
||||
* any default filtering)
|
||||
* @param includeNonSingletons whether to include prototype or scoped beans too
|
||||
* or just singletons (also applies to FactoryBeans)
|
||||
* @since 6.2.5
|
||||
* @see #orderedStream()
|
||||
* @see #stream(Predicate)
|
||||
*/
|
||||
default Stream<T> orderedStream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
if (!includeNonSingletons) {
|
||||
throw new UnsupportedOperationException("Only supports includeNonSingletons=true by default");
|
||||
}
|
||||
return orderedStream().filter(obj -> customFilter.test(obj.getClass()));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -212,9 +212,9 @@ public final class AotServices<T> implements Iterable<T> {
|
||||
}
|
||||
|
||||
private <T> Map<String, T> loadBeans(Class<T> type) {
|
||||
return (this.beanFactory != null) ? BeanFactoryUtils
|
||||
.beansOfTypeIncludingAncestors(this.beanFactory, type, true, false)
|
||||
: Collections.emptyMap();
|
||||
return (this.beanFactory != null ?
|
||||
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type, true, false) :
|
||||
Collections.emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -69,8 +69,8 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||
this.excludeFilters = loader.load(BeanRegistrationExcludeFilter.class);
|
||||
for (BeanRegistrationExcludeFilter excludeFilter : this.excludeFilters) {
|
||||
if (this.excludeFilters.getSource(excludeFilter) == Source.BEAN_FACTORY) {
|
||||
Assert.state(excludeFilter instanceof BeanRegistrationAotProcessor
|
||||
|| excludeFilter instanceof BeanFactoryInitializationAotProcessor,
|
||||
Assert.state(excludeFilter instanceof BeanRegistrationAotProcessor ||
|
||||
excludeFilter instanceof BeanFactoryInitializationAotProcessor,
|
||||
() -> "BeanRegistrationExcludeFilter bean of type %s must also implement an AOT processor interface"
|
||||
.formatted(excludeFilter.getClass().getName()));
|
||||
}
|
||||
|
||||
+2
-4
@@ -234,8 +234,7 @@ public class InstanceSupplierCodeGenerator {
|
||||
|
||||
CodeBlock arguments = hasArguments ?
|
||||
new AutowiredArgumentsCodeGenerator(actualType, constructor)
|
||||
.generateCode(constructor.getParameterTypes(), (onInnerClass ? 1 : 0))
|
||||
: NO_ARGS;
|
||||
.generateCode(constructor.getParameterTypes(), (onInnerClass ? 1 : 0)) : NO_ARGS;
|
||||
|
||||
CodeBlock newInstance = generateNewInstanceCodeForConstructor(actualType, arguments);
|
||||
code.add(generateWithGeneratorCode(hasArguments, newInstance));
|
||||
@@ -325,8 +324,7 @@ public class InstanceSupplierCodeGenerator {
|
||||
boolean hasArguments = factoryMethod.getParameterCount() > 0;
|
||||
CodeBlock arguments = hasArguments ?
|
||||
new AutowiredArgumentsCodeGenerator(ClassUtils.getUserClass(targetClass), factoryMethod)
|
||||
.generateCode(factoryMethod.getParameterTypes())
|
||||
: NO_ARGS;
|
||||
.generateCode(factoryMethod.getParameterTypes()) : NO_ARGS;
|
||||
|
||||
CodeBlock newInstance = generateNewInstanceCodeForMethod(
|
||||
factoryBeanName, ClassUtils.getUserClass(targetClass), factoryMethodName, arguments);
|
||||
|
||||
+12
-12
@@ -487,14 +487,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit))
|
||||
return Arrays.stream(beanNamesForStream(requiredType, true, allowEagerInit))
|
||||
.map(name -> (T) getBean(name))
|
||||
.filter(bean -> !(bean instanceof NullBean));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit);
|
||||
String[] beanNames = beanNamesForStream(requiredType, true, allowEagerInit);
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
@@ -510,16 +510,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> stream(Predicate<Class<?>> customFilter) {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit))
|
||||
public Stream<T> stream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
return Arrays.stream(beanNamesForStream(requiredType, includeNonSingletons, allowEagerInit))
|
||||
.filter(name -> customFilter.test(getType(name)))
|
||||
.map(name -> (T) getBean(name))
|
||||
.filter(bean -> !(bean instanceof NullBean));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> orderedStream(Predicate<Class<?>> customFilter) {
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit);
|
||||
public Stream<T> orderedStream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
String[] beanNames = beanNamesForStream(requiredType, includeNonSingletons, allowEagerInit);
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
@@ -559,8 +559,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, allowEagerInit);
|
||||
private String[] beanNamesForStream(ResolvableType requiredType, boolean includeNonSingletons, boolean allowEagerInit) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, includeNonSingletons, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2544,8 +2544,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Object> stream(Predicate<Class<?>> customFilter) {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(this.descriptor.getResolvableType(), true))
|
||||
public Stream<Object> stream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
return Arrays.stream(beanNamesForStream(this.descriptor.getResolvableType(), includeNonSingletons, true))
|
||||
.filter(name -> AutowireUtils.isAutowireCandidate(DefaultListableBeanFactory.this, name))
|
||||
.filter(name -> customFilter.test(getType(name)))
|
||||
.map(name -> getBean(name))
|
||||
@@ -2553,8 +2553,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Object> orderedStream(Predicate<Class<?>> customFilter) {
|
||||
String[] beanNames = getBeanNamesForTypedStream(this.descriptor.getResolvableType(), true);
|
||||
public Stream<Object> orderedStream(Predicate<Class<?>> customFilter, boolean includeNonSingletons) {
|
||||
String[] beanNames = beanNamesForStream(this.descriptor.getResolvableType(), includeNonSingletons, true);
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
+32
-2
@@ -66,10 +66,40 @@ public class SimpleAutowireCandidateResolver implements AutowireCandidateResolve
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
|
||||
* @see AbstractBeanDefinition#isDefaultCandidate()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Map<String, T> resolveAutowireCandidates(ConfigurableListableBeanFactory lbf, Class<T> type) {
|
||||
return resolveAutowireCandidates(lbf, type, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a map of all beans of the given type, also picking up beans defined in
|
||||
* ancestor bean factories, with the specific condition that each bean actually
|
||||
* has autowire candidate status. This matches simple injection point resolution
|
||||
* as implemented by this {@link AutowireCandidateResolver} strategy, including
|
||||
* beans which are not marked as default candidates but excluding beans which
|
||||
* are not even marked as autowire candidates.
|
||||
* @param lbf the bean factory
|
||||
* @param type the type of bean to match
|
||||
* @param includeNonSingletons whether to include prototype or scoped beans too
|
||||
* or just singletons (also applies to FactoryBeans)
|
||||
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
|
||||
* <i>objects created by FactoryBeans</i> (or by factory methods with a
|
||||
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
|
||||
* eagerly initialized to determine their type: So be aware that passing in "true"
|
||||
* for this flag will initialize FactoryBeans and "factory-bean" references.
|
||||
* @return the Map of matching bean instances, or an empty Map if none
|
||||
* @throws BeansException if a bean could not be created
|
||||
* @since 6.2.5
|
||||
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
|
||||
* @see AbstractBeanDefinition#isDefaultCandidate()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Map<String, T> resolveAutowireCandidates(ConfigurableListableBeanFactory lbf, Class<T> type,
|
||||
boolean includeNonSingletons, boolean allowEagerInit) {
|
||||
|
||||
Map<String, T> candidates = new LinkedHashMap<>();
|
||||
for (String beanName : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, type)) {
|
||||
for (String beanName : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, type,
|
||||
includeNonSingletons, allowEagerInit)) {
|
||||
if (AutowireUtils.isAutowireCandidate(lbf, beanName)) {
|
||||
Object beanInstance = lbf.getBean(beanName);
|
||||
if (!(beanInstance instanceof NullBean)) {
|
||||
|
||||
+2
-2
@@ -66,8 +66,8 @@ public abstract class AbstractBeanDefinitionParser implements BeanDefinitionPars
|
||||
String id = resolveId(element, definition, parserContext);
|
||||
if (!StringUtils.hasText(id)) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Id is required for element '" + parserContext.getDelegate().getLocalName(element)
|
||||
+ "' when used as a top-level tag", element);
|
||||
"Id is required for element '" + parserContext.getDelegate().getLocalName(element) +
|
||||
"' when used as a top-level tag", element);
|
||||
}
|
||||
String[] aliases = null;
|
||||
if (shouldParseNameAsAliases()) {
|
||||
|
||||
+16
-10
@@ -1519,34 +1519,34 @@ class DefaultListableBeanFactoryTests {
|
||||
bd2.setBeanClass(DerivedTestBean.class);
|
||||
bd2.setPropertyValues(new MutablePropertyValues(List.of(new PropertyValue("name", "highest"))));
|
||||
bd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE);
|
||||
bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("bean2", bd2);
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
||||
.containsExactly("highest", "lowest");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
|
||||
.containsExactly("highest", "lowest");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz))
|
||||
.map(TestBean::getName)).containsExactly("lowest");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
|
||||
.containsExactly("highest", "lowest");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
||||
.containsExactly("lowest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderFromAttributeOverrideAnnotation() {
|
||||
void orderFromAttributeOverridesAnnotation() {
|
||||
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
|
||||
RootBeanDefinition rbd1 = new RootBeanDefinition(LowestPrecedenceTestBeanFactoryBean.class);
|
||||
rbd1.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE);
|
||||
lbf.registerBeanDefinition("lowestPrecedenceFactory", rbd1);
|
||||
RootBeanDefinition rbd2 = new RootBeanDefinition(HighestPrecedenceTestBeanFactoryBean.class);
|
||||
rbd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.LOWEST_PRECEDENCE);
|
||||
rbd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("highestPrecedenceFactory", rbd2);
|
||||
GenericBeanDefinition bd1 = new GenericBeanDefinition();
|
||||
bd1.setFactoryBeanName("highestPrecedenceFactory");
|
||||
lbf.registerBeanDefinition("bean1", bd1);
|
||||
GenericBeanDefinition bd2 = new GenericBeanDefinition();
|
||||
bd2.setFactoryBeanName("lowestPrecedenceFactory");
|
||||
lbf.registerBeanDefinition("bean2", bd2);
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
|
||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1987,7 +1987,6 @@ class DefaultListableBeanFactoryTests {
|
||||
void getBeanByTypeInstanceWithAmbiguity() {
|
||||
RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependency.class);
|
||||
bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd2.getConstructorArgumentValues().addGenericArgumentValue("43");
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
lbf.registerBeanDefinition("bd2", bd2);
|
||||
@@ -2028,6 +2027,10 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved).contains(lbf.getBean("bd1"));
|
||||
assertThat(resolved).contains(lbf.getBean("bd2"));
|
||||
|
||||
resolved = provider.stream(ObjectProvider.UNFILTERED, false).collect(Collectors.toSet());
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved).contains(lbf.getBean("bd2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2082,6 +2085,9 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved).contains(lbf.getBean("bd1"));
|
||||
assertThat(resolved).contains(lbf.getBean("bd2"));
|
||||
|
||||
resolved = provider.stream(ObjectProvider.UNFILTERED, false).collect(Collectors.toSet());
|
||||
assertThat(resolved).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+34
-2
@@ -1614,6 +1614,10 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
|
||||
testBeans = bean.allTestBeansInOrder();
|
||||
assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class));
|
||||
testBeans = bean.allSingletonBeans();
|
||||
assertThat(testBeans).isEmpty();
|
||||
testBeans = bean.allSingletonBeansInOrder();
|
||||
assertThat(testBeans).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1648,6 +1652,12 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
testBeans = bean.allTestBeansInOrder();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
|
||||
testBeans = bean.allSingletonBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
|
||||
testBeans = bean.allSingletonBeansInOrder();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1675,6 +1685,10 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(testBeans).isEmpty();
|
||||
testBeans = bean.allTestBeansInOrder();
|
||||
assertThat(testBeans).isEmpty();
|
||||
testBeans = bean.allSingletonBeans();
|
||||
assertThat(testBeans).isEmpty();
|
||||
testBeans = bean.allSingletonBeansInOrder();
|
||||
assertThat(testBeans).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1698,6 +1712,8 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allTestBeansInOrder()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allSingletonBeans()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allSingletonBeansInOrder()).containsExactly(testBean1, testBean2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1728,6 +1744,8 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean2, testBean1);
|
||||
assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allTestBeansInOrder()).containsExactly(testBean2, testBean1);
|
||||
assertThat(bean.allSingletonBeans()).containsExactly(testBean1, testBean2);
|
||||
assertThat(bean.allSingletonBeansInOrder()).containsExactly(testBean2, testBean1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1739,7 +1757,7 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.registerBeanDefinition("testBean1", tb1);
|
||||
RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class);
|
||||
tb2.setFactoryMethodName("newTestBean2");
|
||||
tb2.setLazyInit(true);
|
||||
tb2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("testBean2", tb2);
|
||||
|
||||
ObjectProviderInjectionBean bean = bf.getBean("annotatedBean", ObjectProviderInjectionBean.class);
|
||||
@@ -1747,6 +1765,7 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.getBean("testBean1", TestBean.class));
|
||||
assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
|
||||
bf.getBean("testBean1", TestBean.class));
|
||||
assertThat(bean.allSingletonBeansInOrder()).containsExactly(bf.getBean("testBean1", TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1757,6 +1776,7 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.registerBeanDefinition("testBean1", tb1);
|
||||
RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class);
|
||||
tb2.setFactoryMethodName("newTestBean2");
|
||||
tb2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("testBean2", tb2);
|
||||
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
@@ -1789,6 +1809,10 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.getBean("testBean2", TestBean.class), bf.getBean("testBean4", TestBean.class));
|
||||
assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class),
|
||||
bf.getBean("testBean1", TestBean.class), bf.getBean("testBean4", TestBean.class));
|
||||
assertThat(bean.allSingletonBeans()).containsExactly(bf.getBean("testBean1", TestBean.class),
|
||||
bf.getBean("testBean4", TestBean.class));
|
||||
assertThat(bean.allSingletonBeansInOrder()).containsExactly(bf.getBean("testBean1", TestBean.class),
|
||||
bf.getBean("testBean4", TestBean.class));
|
||||
|
||||
Map<String, TestBean> typeMatches = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, TestBean.class);
|
||||
assertThat(typeMatches.remove("testBean3")).isNotNull();
|
||||
@@ -2370,7 +2394,7 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings("unchecked")
|
||||
void genericsBasedConstructorInjectionWithNonTypedTarget() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
@@ -3393,6 +3417,14 @@ class AutowiredAnnotationBeanPostProcessorTests {
|
||||
public List<TestBean> allTestBeansInOrder() {
|
||||
return this.testBean.orderedStream(ObjectProvider.UNFILTERED).toList();
|
||||
}
|
||||
|
||||
public List<TestBean> allSingletonBeans() {
|
||||
return this.testBean.stream(ObjectProvider.UNFILTERED, false).toList();
|
||||
}
|
||||
|
||||
public List<TestBean> allSingletonBeansInOrder() {
|
||||
return this.testBean.orderedStream(ObjectProvider.UNFILTERED, false).toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -71,8 +71,8 @@ class ParameterResolutionTests {
|
||||
}
|
||||
|
||||
private void assertAutowirableParameters(Executable executable) {
|
||||
int startIndex = (executable instanceof Constructor)
|
||||
&& ClassUtils.isInnerClass(executable.getDeclaringClass()) ? 1 : 0;
|
||||
int startIndex = (executable instanceof Constructor) &&
|
||||
ClassUtils.isInnerClass(executable.getDeclaringClass()) ? 1 : 0;
|
||||
Parameter[] parameters = executable.getParameters();
|
||||
for (int parameterIndex = startIndex; parameterIndex < parameters.length; parameterIndex++) {
|
||||
Parameter parameter = parameters[parameterIndex];
|
||||
|
||||
+4
-4
@@ -103,8 +103,8 @@ class BeanInstanceSupplierTests {
|
||||
RegisteredBean registerBean = source.registerBean(this.beanFactory);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.get(registerBean)).withMessage(
|
||||
"Constructor with parameter types [java.io.InputStream] cannot be found on "
|
||||
+ SingleArgConstructor.class.getName());
|
||||
"Constructor with parameter types [java.io.InputStream] cannot be found on " +
|
||||
SingleArgConstructor.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -151,8 +151,8 @@ class BeanInstanceSupplierTests {
|
||||
RegisteredBean registerBean = source.registerBean(this.beanFactory);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.get(registerBean)).withMessage(
|
||||
"Factory method 'single' with parameter types [java.io.InputStream] declared on class "
|
||||
+ SingleArgFactory.class.getName() + " cannot be found");
|
||||
"Factory method 'single' with parameter types [java.io.InputStream] declared on class " +
|
||||
SingleArgFactory.class.getName() + " cannot be found");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -86,8 +86,8 @@ class DefaultBeanRegistrationCodeFragmentsTests {
|
||||
BeanRegistrationCodeFragments codeFragments = createInstance(registeredBean);
|
||||
assertThatExceptionOfType(AotBeanProcessingException.class)
|
||||
.isThrownBy(() -> codeFragments.getTarget(registeredBean))
|
||||
.withMessageContaining("Error processing bean with name 'testBean' defined in my test resource: "
|
||||
+ "instance supplier is not supported");
|
||||
.withMessageContaining("Error processing bean with name 'testBean' defined in my test resource: " +
|
||||
"instance supplier is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -93,8 +93,8 @@ class MetadataCollector {
|
||||
|
||||
private boolean shouldBeMerged(ItemMetadata itemMetadata) {
|
||||
String sourceType = itemMetadata.getType();
|
||||
return (sourceType != null && !deletedInCurrentBuild(sourceType)
|
||||
&& !processedInCurrentBuild(sourceType));
|
||||
return (sourceType != null && !deletedInCurrentBuild(sourceType) &&
|
||||
!processedInCurrentBuild(sourceType));
|
||||
}
|
||||
|
||||
private boolean deletedInCurrentBuild(String sourceType) {
|
||||
|
||||
+2
-2
@@ -42,8 +42,8 @@ class Metadata {
|
||||
ItemMetadata itemMetadata = metadata.getItems().stream()
|
||||
.filter(item -> item.getType().equals(type))
|
||||
.findFirst().orElse(null);
|
||||
return itemMetadata != null && itemMetadata.getStereotypes().size() == stereotypes.size()
|
||||
&& itemMetadata.getStereotypes().containsAll(stereotypes);
|
||||
return (itemMetadata != null && itemMetadata.getStereotypes().size() == stereotypes.size() &&
|
||||
itemMetadata.getStereotypes().containsAll(stereotypes));
|
||||
}, "Candidates with type %s and stereotypes %s", type, stereotypes);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -79,8 +79,8 @@ abstract class AbstractJCacheKeyOperation<A extends Annotation> extends Abstract
|
||||
for (CacheParameterDetail keyParameterDetail : this.keyParameterDetails) {
|
||||
int parameterPosition = keyParameterDetail.getParameterPosition();
|
||||
if (parameterPosition >= values.length) {
|
||||
throw new IllegalStateException("Values mismatch, key parameter at position "
|
||||
+ parameterPosition + " cannot be matched against " + values.length + " value(s)");
|
||||
throw new IllegalStateException("Values mismatch, key parameter at position " +
|
||||
parameterPosition + " cannot be matched against " + values.length + " value(s)");
|
||||
}
|
||||
result.add(keyParameterDetail.toCacheInvocationParameter(values[parameterPosition]));
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,7 +17,6 @@
|
||||
package org.springframework.cache.jcache.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.cache.annotation.CacheDefaults;
|
||||
@@ -150,9 +149,9 @@ class JCacheKeyGeneratorTests {
|
||||
|
||||
@Override
|
||||
public Object generate(Object target, Method method, Object... params) {
|
||||
assertThat(Arrays.equals(expectedParams, params)).as("Unexpected parameters: expected: "
|
||||
+ Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params)).isTrue();
|
||||
assertThat(params).as("Unexpected parameters").isEqualTo(expectedParams);
|
||||
return new SimpleKey(params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -288,8 +288,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
throw new NoSuchBeanDefinitionException(CacheManager.class, "no CacheResolver specified - "
|
||||
+ "register a CacheManager bean or remove the @EnableCaching annotation from your configuration.");
|
||||
throw new NoSuchBeanDefinitionException(CacheManager.class, "no CacheResolver specified - " +
|
||||
"register a CacheManager bean or remove the @EnableCaching annotation from your configuration.");
|
||||
}
|
||||
}
|
||||
this.initialized = true;
|
||||
|
||||
+2
-2
@@ -85,8 +85,8 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri
|
||||
// Look for most specific name match.
|
||||
String bestNameMatch = null;
|
||||
for (String mappedName : this.nameMap.keySet()) {
|
||||
if (isMatch(methodName, mappedName)
|
||||
&& (bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
|
||||
if (isMatch(methodName, mappedName) &&
|
||||
(bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
|
||||
ops = this.nameMap.get(mappedName);
|
||||
bestNameMatch = mappedName;
|
||||
}
|
||||
|
||||
+2
-2
@@ -105,8 +105,8 @@ class ConfigurationClassParser {
|
||||
(className.startsWith("java.lang.annotation.") || className.startsWith("org.springframework.stereotype."));
|
||||
|
||||
private static final Predicate<Condition> REGISTER_BEAN_CONDITION_FILTER = condition ->
|
||||
(condition instanceof ConfigurationCondition configurationCondition
|
||||
&& ConfigurationPhase.REGISTER_BEAN.equals(configurationCondition.getConfigurationPhase()));
|
||||
(condition instanceof ConfigurationCondition configurationCondition &&
|
||||
ConfigurationPhase.REGISTER_BEAN.equals(configurationCondition.getConfigurationPhase()));
|
||||
|
||||
private static final Comparator<DeferredImportSelectorHolder> DEFERRED_IMPORT_COMPARATOR =
|
||||
(o1, o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getImportSelector(), o2.getImportSelector());
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -150,12 +150,12 @@ class ApplicationContextInitializationCodeGenerator implements BeanFactoryInitia
|
||||
@Nullable
|
||||
private CodeBlock apply(ClassName className) {
|
||||
String name = className.canonicalName();
|
||||
if (name.equals(DefaultListableBeanFactory.class.getName())
|
||||
|| name.equals(ConfigurableListableBeanFactory.class.getName())) {
|
||||
if (name.equals(DefaultListableBeanFactory.class.getName()) ||
|
||||
name.equals(ConfigurableListableBeanFactory.class.getName())) {
|
||||
return CodeBlock.of(BEAN_FACTORY_VARIABLE);
|
||||
}
|
||||
else if (name.equals(ConfigurableEnvironment.class.getName())
|
||||
|| name.equals(Environment.class.getName())) {
|
||||
else if (name.equals(ConfigurableEnvironment.class.getName()) ||
|
||||
name.equals(Environment.class.getName())) {
|
||||
return CodeBlock.of("$L.getEnvironment()", APPLICATION_CONTEXT_VARIABLE);
|
||||
}
|
||||
else if (name.equals(ResourceLoader.class.getName())) {
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -201,8 +201,8 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
|
||||
try {
|
||||
int maxLength = Integer.parseInt(value.trim());
|
||||
Assert.isTrue(maxLength > 0, () -> "Value [" + maxLength + "] for system property ["
|
||||
+ MAX_SPEL_EXPRESSION_LENGTH_PROPERTY_NAME + "] must be positive");
|
||||
Assert.isTrue(maxLength > 0, () -> "Value [" + maxLength + "] for system property [" +
|
||||
MAX_SPEL_EXPRESSION_LENGTH_PROPERTY_NAME + "] must be positive");
|
||||
return maxLength;
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
|
||||
+2
-2
@@ -493,8 +493,8 @@ final class PostProcessorRegistrationDelegate {
|
||||
|
||||
private void postProcessValue(List<MergedBeanDefinitionPostProcessor> postProcessors,
|
||||
BeanDefinitionValueResolver valueResolver, @Nullable Object value) {
|
||||
if (value instanceof BeanDefinitionHolder bdh
|
||||
&& bdh.getBeanDefinition() instanceof AbstractBeanDefinition innerBd) {
|
||||
if (value instanceof BeanDefinitionHolder bdh &&
|
||||
bdh.getBeanDefinition() instanceof AbstractBeanDefinition innerBd) {
|
||||
|
||||
Class<?> innerBeanType = resolveBeanType(innerBd);
|
||||
resolveInnerBeanDefinition(valueResolver, innerBd, (innerBeanName, innerBeanDefinition)
|
||||
|
||||
+2
-2
@@ -143,8 +143,8 @@ public abstract class DurationFormatterUtils {
|
||||
|
||||
private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$");
|
||||
private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$");
|
||||
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?"
|
||||
+ "\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
|
||||
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" +
|
||||
"\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
|
||||
|
||||
private static Duration parseIso8601(String value) {
|
||||
try {
|
||||
|
||||
+2
-2
@@ -48,8 +48,8 @@ public class DefaultScheduledTaskObservationConvention implements ScheduledTaskO
|
||||
|
||||
@Override
|
||||
public String getContextualName(ScheduledTaskObservationContext context) {
|
||||
return "task " + StringUtils.uncapitalize(context.getTargetClass().getSimpleName())
|
||||
+ "." + context.getMethod().getName();
|
||||
return "task " + StringUtils.uncapitalize(context.getTargetClass().getSimpleName()) +
|
||||
"." + context.getMethod().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -106,8 +106,8 @@ class AspectAndAdvicePrecedenceTests {
|
||||
private void checkAdvice(String whatJustHappened) {
|
||||
//System.out.println("[" + adviceInvocationNumber + "] " + whatJustHappened + " ==> " + EXPECTED[adviceInvocationNumber]);
|
||||
if (adviceInvocationNumber > (EXPECTED.length - 1)) {
|
||||
throw new AssertionError("Too many advice invocations, expecting " + EXPECTED.length
|
||||
+ " but had " + adviceInvocationNumber);
|
||||
throw new AssertionError("Too many advice invocations, expecting " + EXPECTED.length +
|
||||
" but had " + adviceInvocationNumber);
|
||||
}
|
||||
String expecting = EXPECTED[adviceInvocationNumber++];
|
||||
if (!whatJustHappened.equals(expecting)) {
|
||||
|
||||
+16
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -277,9 +277,9 @@ public class GroovyScriptFactoryTests {
|
||||
|
||||
@Test
|
||||
void testScriptCompilationException() {
|
||||
assertThatExceptionOfType(NestedRuntimeException.class).isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("org/springframework/scripting/groovy/groovyBrokenContext.xml"))
|
||||
.matches(ex -> ex.contains(ScriptCompilationException.class));
|
||||
assertThatExceptionOfType(NestedRuntimeException.class)
|
||||
.isThrownBy(() -> new ClassPathXmlApplicationContext("org/springframework/scripting/groovy/groovyBrokenContext.xml"))
|
||||
.matches(ex -> ex.contains(ScriptCompilationException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -288,11 +288,10 @@ public class GroovyScriptFactoryTests {
|
||||
String badScript = "class Foo { public Foo(String foo) {}}";
|
||||
given(script.getScriptAsString()).willReturn(badScript);
|
||||
given(script.suggestedClassName()).willReturn("someName");
|
||||
GroovyScriptFactory factory = new GroovyScriptFactory(ScriptFactoryPostProcessor.INLINE_SCRIPT_PREFIX
|
||||
+ badScript);
|
||||
assertThatExceptionOfType(ScriptCompilationException.class).isThrownBy(() ->
|
||||
factory.getScriptedObject(script))
|
||||
.matches(ex -> ex.contains(NoSuchMethodException.class));
|
||||
GroovyScriptFactory factory = new GroovyScriptFactory(ScriptFactoryPostProcessor.INLINE_SCRIPT_PREFIX + badScript);
|
||||
assertThatExceptionOfType(ScriptCompilationException.class)
|
||||
.isThrownBy(() -> factory.getScriptedObject(script))
|
||||
.matches(ex -> ex.contains(NoSuchMethodException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -327,27 +326,24 @@ public class GroovyScriptFactoryTests {
|
||||
|
||||
@Test
|
||||
void testCtorWithNullScriptSourceLocator() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new GroovyScriptFactory(null));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCtorWithEmptyScriptSourceLocator() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new GroovyScriptFactory(""));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCtorWithWhitespacedScriptSourceLocator() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new GroovyScriptFactory("\n "));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory("\n "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWithInlineScriptWithLeadingWhitespace() {
|
||||
assertThatExceptionOfType(BeanCreationException.class).as("'inline:' prefix was preceded by whitespace").isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("lwspBadGroovyContext.xml", getClass()))
|
||||
.matches(ex -> ex.contains(FileNotFoundException.class));
|
||||
assertThatExceptionOfType(BeanCreationException.class).as("'inline:' prefix was preceded by whitespace")
|
||||
.isThrownBy(() -> new ClassPathXmlApplicationContext("lwspBadGroovyContext.xml", getClass()))
|
||||
.matches(ex -> ex.contains(FileNotFoundException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -364,8 +360,8 @@ public class GroovyScriptFactoryTests {
|
||||
@Test
|
||||
void testGetScriptedObjectDoesChokeOnNullScriptSourceBeingPassedIn() {
|
||||
GroovyScriptFactory factory = new GroovyScriptFactory("a script source locator (doesn't matter here)");
|
||||
assertThatNullPointerException().as("NullPointerException as per contract ('null' ScriptSource supplied)").isThrownBy(() ->
|
||||
factory.getScriptedObject(null));
|
||||
assertThatNullPointerException().as("NullPointerException as per contract ('null' ScriptSource supplied)")
|
||||
.isThrownBy(() -> factory.getScriptedObject(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -2,11 +2,10 @@ description = "Spring Core Test"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-core"))
|
||||
api("org.assertj:assertj-core")
|
||||
api("org.junit.jupiter:junit-jupiter-api")
|
||||
compileOnly("org.junit.jupiter:junit-jupiter")
|
||||
compileOnly("org.junit.platform:junit-platform-engine")
|
||||
compileOnly("org.junit.platform:junit-platform-launcher")
|
||||
optional("org.assertj:assertj-core")
|
||||
optional("org.junit.jupiter:junit-jupiter-api")
|
||||
compileOnly("org.junit.jupiter:junit-jupiter-params") // Used in CompileWithForkedClassLoaderExtension Javadoc
|
||||
compileOnly("org.junit.platform:junit-platform-launcher") // Used in CompileWithForkedClassLoaderExtension
|
||||
implementation("com.thoughtworks.qdox:qdox")
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -338,8 +338,8 @@ public abstract class InstrumentedBridgeMethods {
|
||||
Object result = null;
|
||||
boolean accessibilityChanged = false;
|
||||
try {
|
||||
if (!Modifier.isPublic(method.getModifiers())
|
||||
|| !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
|
||||
if (!Modifier.isPublic(method.getModifiers()) ||
|
||||
!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
|
||||
method.setAccessible(true);
|
||||
accessibilityChanged = true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -78,8 +78,8 @@ class InvocationsRecorderClassVisitor extends ClassVisitor implements Opcodes {
|
||||
static {
|
||||
for (InstrumentedMethod method : InstrumentedMethod.values()) {
|
||||
MethodReference methodReference = method.methodReference();
|
||||
instrumentedMethods.add(methodReference.getClassName().replace('.', '/')
|
||||
+ "#" + methodReference.getMethodName());
|
||||
instrumentedMethods.add(methodReference.getClassName().replace('.', '/') +
|
||||
"#" + methodReference.getMethodName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -108,8 +108,8 @@ public class RuntimeHintsInvocationsAssert extends AbstractAssert<RuntimeHintsIn
|
||||
|
||||
private String formatStackTrace(Stream<StackWalker.StackFrame> stackTraceElements) {
|
||||
return stackTraceElements
|
||||
.map(f -> f.getClassName() + "#" + f.getMethodName()
|
||||
+ ", Line " + f.getLineNumber()).collect(Collectors.joining(System.lineSeparator()));
|
||||
.map(f -> f.getClassName() + "#" + f.getMethodName() + ", Line " +
|
||||
f.getLineNumber()).collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -122,8 +122,8 @@ public class MockSpringFactoriesLoader extends SpringFactoriesLoader {
|
||||
public <T> void addInstance(String factoryType, T... factoryInstance) {
|
||||
List<String> implementations = this.factories.computeIfAbsent(factoryType, key -> new ArrayList<>());
|
||||
for (T factoryImplementation : factoryInstance) {
|
||||
String reference = "!" + factoryType + ":" + factoryImplementation.getClass().getName()
|
||||
+ this.sequence.getAndIncrement();
|
||||
String reference = "!" + factoryType + ":" + factoryImplementation.getClass().getName() +
|
||||
this.sequence.getAndIncrement();
|
||||
implementations.add(reference);
|
||||
this.implementations.put(reference, factoryImplementation);
|
||||
}
|
||||
|
||||
+2
-2
@@ -299,8 +299,8 @@ public final class TestCompiler {
|
||||
}
|
||||
|
||||
private DynamicClassLoader compile() {
|
||||
ClassLoader classLoaderToUse = (this.classLoader != null ? this.classLoader
|
||||
: Thread.currentThread().getContextClassLoader());
|
||||
ClassLoader classLoaderToUse = (this.classLoader != null ? this.classLoader :
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
List<DynamicJavaFileObject> compilationUnits = this.sourceFiles.stream().map(
|
||||
DynamicJavaFileObject::new).toList();
|
||||
StandardJavaFileManager standardFileManager = this.compiler.getStandardFileManager(
|
||||
|
||||
+2
-2
@@ -102,8 +102,8 @@ public class DefaultMethodReference implements MethodReference {
|
||||
TypeName argumentType = argumentTypes[i];
|
||||
CodeBlock argumentCode = argumentCodeGenerator.generateCode(argumentType);
|
||||
if (argumentCode == null) {
|
||||
throw new IllegalArgumentException("Could not generate code for " + this
|
||||
+ ": parameter " + i + " of type " + argumentType + " is not supported");
|
||||
throw new IllegalArgumentException("Could not generate code for " + this +
|
||||
": parameter " + i + " of type " + argumentType + " is not supported");
|
||||
}
|
||||
arguments.add(argumentCode);
|
||||
}
|
||||
|
||||
@@ -192,9 +192,9 @@ public interface GeneratedFiles {
|
||||
|
||||
private static void validatePackage(String packageName, String className) {
|
||||
if (!StringUtils.hasLength(packageName)) {
|
||||
throw new IllegalArgumentException("Could not add '" + className + "', "
|
||||
+ "processing classes in the default package is not supported. "
|
||||
+ "Did you forget to add a package statement?");
|
||||
throw new IllegalArgumentException("Could not add '" + className + "', " +
|
||||
"processing classes in the default package is not supported. " +
|
||||
"Did you forget to add a package statement?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -240,8 +240,8 @@ public abstract class ValueCodeGeneratorDelegates {
|
||||
if (escaped != null) {
|
||||
return escaped;
|
||||
}
|
||||
return (!Character.isISOControl(ch)) ? Character.toString(ch)
|
||||
: String.format("\\u%04x", (int) ch);
|
||||
return (!Character.isISOControl(ch)) ? Character.toString(ch) :
|
||||
String.format("\\u%04x", (int) ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -108,8 +108,8 @@ public class BindingReflectionHintsRegistrar {
|
||||
registerPropertyHints(hints, seen, method, 0);
|
||||
}
|
||||
else if ((methodName.startsWith("get") && method.getParameterCount() == 0 && method.getReturnType() != void.class) ||
|
||||
(methodName.startsWith("is") && method.getParameterCount() == 0
|
||||
&& ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType()) == Boolean.class)) {
|
||||
(methodName.startsWith("is") && method.getParameterCount() == 0 &&
|
||||
ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType()) == Boolean.class)) {
|
||||
registerPropertyHints(hints, seen, method, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ public class ClassReader {
|
||||
this.b = classFileBuffer;
|
||||
// Check the class' major_version. This field is after the magic and minor_version fields, which
|
||||
// use 4 and 2 bytes respectively.
|
||||
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V24) {
|
||||
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V25) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported class file major version " + readShort(classFileOffset + 6));
|
||||
}
|
||||
|
||||
@@ -594,7 +594,7 @@ public abstract class MethodVisitor {
|
||||
* Visits a LOOKUPSWITCH instruction.
|
||||
*
|
||||
* @param dflt beginning of the default handler block.
|
||||
* @param keys the values of the keys.
|
||||
* @param keys the values of the keys. Keys must be sorted in increasing order.
|
||||
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
|
||||
* handler block for the {@code keys[i]} key.
|
||||
*/
|
||||
|
||||
@@ -289,6 +289,7 @@ public interface Opcodes {
|
||||
int V22 = 0 << 16 | 66;
|
||||
int V23 = 0 << 16 | 67;
|
||||
int V24 = 0 << 16 | 68;
|
||||
int V25 = 0 << 16 | 69;
|
||||
|
||||
/**
|
||||
* Version flag indicating that the class is using 'preview' features.
|
||||
|
||||
+2
-2
@@ -375,8 +375,8 @@ final class TypeMappedAnnotation<A extends Annotation> extends AbstractMergedAnn
|
||||
private Object getRequiredValue(int attributeIndex, String attributeName) {
|
||||
Object value = getValue(attributeIndex, Object.class);
|
||||
if (value == null) {
|
||||
throw new NoSuchElementException("No element at attribute index "
|
||||
+ attributeIndex + " for name " + attributeName);
|
||||
throw new NoSuchElementException("No element at attribute index " +
|
||||
attributeIndex + " for name " + attributeName);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ public class ResourceRegionEncoder extends AbstractEncoder<ResourceRegion> {
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||
return super.canEncode(elementType, mimeType)
|
||||
&& ResourceRegion.class.isAssignableFrom(elementType.toClass());
|
||||
return super.canEncode(elementType, mimeType) &&
|
||||
ResourceRegion.class.isAssignableFrom(elementType.toClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-6
@@ -56,6 +56,7 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
|
||||
// Try a URL connection content-length header
|
||||
URLConnection con = url.openConnection();
|
||||
customizeConnection(con);
|
||||
|
||||
HttpURLConnection httpCon = (con instanceof HttpURLConnection huc ? huc : null);
|
||||
if (httpCon != null) {
|
||||
httpCon.setRequestMethod("HEAD");
|
||||
@@ -81,12 +82,16 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check content-length entry but not for JarURLConnection where
|
||||
// this would open the jar file but effectively never close it ->
|
||||
// for jar entries, always fall back to stream existence instead.
|
||||
if (!(con instanceof JarURLConnection) && con.getContentLengthLong() > 0) {
|
||||
|
||||
if (con instanceof JarURLConnection jarCon) {
|
||||
// For JarURLConnection, do not check content-length but rather the
|
||||
// existence of the entry (or the jar root in case of no entryName).
|
||||
return (jarCon.getEntryName() == null || jarCon.getJarEntry() != null);
|
||||
}
|
||||
else if (con.getContentLengthLong() > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (httpCon != null) {
|
||||
// No HTTP OK status, and no content-length header: give up
|
||||
httpCon.disconnect();
|
||||
@@ -346,8 +351,8 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
|
||||
*/
|
||||
protected void customizeConnection(URLConnection con) throws IOException {
|
||||
ResourceUtils.useCachesIfNecessary(con);
|
||||
if (con instanceof HttpURLConnection httpConn) {
|
||||
customizeConnection(httpConn);
|
||||
if (con instanceof HttpURLConnection httpCon) {
|
||||
customizeConnection(httpCon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -234,8 +234,8 @@ public class UrlResource extends AbstractFileResolvingResource {
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Close the HTTP connection (if applicable).
|
||||
if (con instanceof HttpURLConnection httpConn) {
|
||||
httpConn.disconnect();
|
||||
if (con instanceof HttpURLConnection httpCon) {
|
||||
httpCon.disconnect();
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
|
||||
+2
-2
@@ -472,8 +472,8 @@ public class SpringFactoriesLoader {
|
||||
|
||||
private static <T> void makeAccessible(Constructor<T> constructor,
|
||||
KFunction<T> kotlinConstructor) {
|
||||
if ((!Modifier.isPublic(constructor.getModifiers())
|
||||
|| !Modifier.isPublic(constructor.getDeclaringClass().getModifiers()))) {
|
||||
if ((!Modifier.isPublic(constructor.getModifiers()) ||
|
||||
!Modifier.isPublic(constructor.getDeclaringClass().getModifiers()))) {
|
||||
KCallablesJvm.setAccessible(kotlinConstructor, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,8 +275,8 @@ public class AntPathMatcher implements PathMatcher {
|
||||
if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) {
|
||||
return false;
|
||||
}
|
||||
if (pattIdxEnd == (pattDirs.length - 1)
|
||||
&& pattern.endsWith(this.pathSeparator) != path.endsWith(this.pathSeparator)) {
|
||||
if (pattIdxEnd == (pattDirs.length - 1) &&
|
||||
pattern.endsWith(this.pathSeparator) != path.endsWith(this.pathSeparator)) {
|
||||
return false;
|
||||
}
|
||||
pattIdxEnd--;
|
||||
|
||||
@@ -557,9 +557,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
|
||||
private boolean contains(Node<K, V> e) {
|
||||
return (e.getPrevious() != null)
|
||||
|| (e.getNext() != null)
|
||||
|| (e == this.first);
|
||||
return (e.getPrevious() != null) || (e.getNext() != null) || (e == this.first);
|
||||
}
|
||||
|
||||
private void linkLast(final Node<K, V> e) {
|
||||
|
||||
@@ -808,7 +808,7 @@ public abstract class StringUtils {
|
||||
* <li>Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"},
|
||||
* and {@code "0"} through {@code "9"} stay the same.</li>
|
||||
* <li>Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.</li>
|
||||
* <li>A sequence "{@code %<i>xy</i>}" is interpreted as a hexadecimal representation of the character.</li>
|
||||
* <li>A sequence "<i>{@code %xy}</i>" is interpreted as a hexadecimal representation of the character.</li>
|
||||
* <li>For all other characters (including those already decoded), the output is undefined.</li>
|
||||
* </ul>
|
||||
* @param source the encoded String
|
||||
|
||||
@@ -71,8 +71,8 @@ class GeneratedFilesTests {
|
||||
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld").build();
|
||||
JavaFile javaFile = JavaFile.builder("", helloWorld).build();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.generatedFiles.addSourceFile(javaFile))
|
||||
.withMessage("Could not add 'HelloWorld', processing classes in the "
|
||||
+ "default package is not supported. Did you forget to add a package statement?");
|
||||
.withMessage("Could not add 'HelloWorld', processing classes in the " +
|
||||
"default package is not supported. Did you forget to add a package statement?");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,8 +92,8 @@ class GeneratedFilesTests {
|
||||
void addSourceFileWithCharSequenceWhenClassNameIsInTheDefaultPackageThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.generatedFiles.addSourceFile("HelloWorld", "{}"))
|
||||
.withMessage("Could not add 'HelloWorld', processing classes in the "
|
||||
+ "default package is not supported. Did you forget to add a package statement?");
|
||||
.withMessage("Could not add 'HelloWorld', processing classes in the " +
|
||||
"default package is not supported. Did you forget to add a package statement?");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+13
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -64,20 +64,17 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
*/
|
||||
class ValueCodeGeneratorTests {
|
||||
|
||||
|
||||
@Nested
|
||||
class ConfigurationTests {
|
||||
|
||||
@Test
|
||||
void createWithListOfDelegatesInvokeThemInOrder() {
|
||||
Delegate first = mock(Delegate.class);
|
||||
Delegate second = mock(Delegate.class);
|
||||
Delegate third = mock(Delegate.class);
|
||||
ValueCodeGenerator codeGenerator = ValueCodeGenerator
|
||||
.with(List.of(first, second, third));
|
||||
Delegate first = mock();
|
||||
Delegate second = mock();
|
||||
Delegate third = mock();
|
||||
ValueCodeGenerator codeGenerator = ValueCodeGenerator.with(List.of(first, second, third));
|
||||
Object value = "";
|
||||
given(third.generateCode(codeGenerator, value))
|
||||
.willReturn(CodeBlock.of("test"));
|
||||
given(third.generateCode(codeGenerator, value)).willReturn(CodeBlock.of("test"));
|
||||
CodeBlock code = codeGenerator.generateCode(value);
|
||||
assertThat(code).hasToString("test");
|
||||
InOrder ordered = inOrder(first, second, third);
|
||||
@@ -88,13 +85,11 @@ class ValueCodeGeneratorTests {
|
||||
|
||||
@Test
|
||||
void generateCodeWithMatchingDelegateStops() {
|
||||
Delegate first = mock(Delegate.class);
|
||||
Delegate second = mock(Delegate.class);
|
||||
ValueCodeGenerator codeGenerator = ValueCodeGenerator
|
||||
.with(List.of(first, second));
|
||||
Delegate first = mock();
|
||||
Delegate second = mock();
|
||||
ValueCodeGenerator codeGenerator = ValueCodeGenerator.with(List.of(first, second));
|
||||
Object value = "";
|
||||
given(first.generateCode(codeGenerator, value))
|
||||
.willReturn(CodeBlock.of("test"));
|
||||
given(first.generateCode(codeGenerator, value)).willReturn(CodeBlock.of("test"));
|
||||
CodeBlock code = codeGenerator.generateCode(value);
|
||||
assertThat(code).hasToString("test");
|
||||
verify(first).generateCode(codeGenerator, value);
|
||||
@@ -198,7 +193,6 @@ class ValueCodeGeneratorTests {
|
||||
assertThat(generateCode("test")).hasToString("\"test\"");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void generateWhenStringWithCarriageReturn() {
|
||||
assertThat(generateCode("test\n")).isEqualTo(CodeBlock.of("$S", "test\n"));
|
||||
@@ -285,9 +279,9 @@ class ValueCodeGeneratorTests {
|
||||
ResolvableType resolvableType = ResolvableType.forClassWithGenerics(Map.class,
|
||||
ResolvableType.forClass(Integer.class), stringList);
|
||||
assertThat(resolve(generateCode(resolvableType)))
|
||||
.hasImport(ResolvableType.class, List.class, Map.class).hasValueCode(
|
||||
"ResolvableType.forClassWithGenerics(Map.class, ResolvableType.forClass(Integer.class), "
|
||||
+ "ResolvableType.forClassWithGenerics(List.class, String.class))");
|
||||
.hasImport(ResolvableType.class, List.class, Map.class).hasValueCode("""
|
||||
ResolvableType.forClassWithGenerics(Map.class, ResolvableType.forClass(Integer.class), \
|
||||
ResolvableType.forClassWithGenerics(List.class, String.class))""");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -216,10 +216,10 @@ class ReflectionHintsTests {
|
||||
typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
|
||||
assertThat(this.reflectionHints.typeHints()).hasSize(2)
|
||||
.noneMatch(typeHint -> typeHint.getType().getCanonicalName().equals(Serializable.class.getCanonicalName()))
|
||||
.anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(SecondInterface.class.getCanonicalName())
|
||||
&& typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS))
|
||||
.anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(FirstInterface.class.getCanonicalName())
|
||||
&& typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS));
|
||||
.anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(SecondInterface.class.getCanonicalName()) &&
|
||||
typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS))
|
||||
.anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(FirstInterface.class.getCanonicalName()) &&
|
||||
typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS));
|
||||
}
|
||||
|
||||
private void assertTestTypeMethodHints(Consumer<ExecutableHint> methodHint) {
|
||||
|
||||
+69
-89
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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,27 +54,24 @@ class AnnotationTypeMappingsTests {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SimpleAnnotation.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings.get(0).getAnnotationType()).isEqualTo(SimpleAnnotation.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(SimpleAnnotation.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
|
||||
.containsExactly(SimpleAnnotation.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenMetaAnnotationsReturnsMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MetaAnnotated.class);
|
||||
assertThat(mappings.size()).isEqualTo(6);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
MetaAnnotated.class, A.class, B.class, AA.class, AB.class,
|
||||
ABC.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
|
||||
.containsExactly(MetaAnnotated.class, A.class, B.class, AA.class, AB.class, ABC.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenHasRepeatingMetaAnnotationReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class);
|
||||
assertThat(mappings.size()).isEqualTo(3);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
|
||||
.containsExactly(WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -89,56 +86,52 @@ class AnnotationTypeMappingsTests {
|
||||
void forAnnotationTypeWhenSelfAnnotatedReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SelfAnnotated.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(SelfAnnotated.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
|
||||
.containsExactly(SelfAnnotated.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenFormsLoopReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(LoopA.class);
|
||||
assertThat(mappings.size()).isEqualTo(2);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class, LoopB.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
|
||||
.containsExactly(LoopA.class, LoopB.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenHasAliasForWithBothValueAndAttributeThrowsException() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForWithBothValueAndAttribute.class))
|
||||
.withMessage("In @AliasFor declared on attribute 'test' in annotation ["
|
||||
+ AliasForWithBothValueAndAttribute.class.getName()
|
||||
+ "], attribute 'attribute' and its alias 'value' are present with values of 'foo' and 'bar', but only one is permitted.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForWithBothValueAndAttribute.class))
|
||||
.withMessage("In @AliasFor declared on attribute 'test' in annotation [%s], attribute 'attribute' " +
|
||||
"and its alias 'value' are present with values of 'foo' and 'bar', but only one is permitted.",
|
||||
AliasForWithBothValueAndAttribute.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForToSelfNonExistingAttribute() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForToSelfNonExistingAttribute.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation ["
|
||||
+ AliasForToSelfNonExistingAttribute.class.getName()
|
||||
+ "] declares an alias for 'missing' which is not present.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelfNonExistingAttribute.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation [%s] " +
|
||||
"declares an alias for 'missing' which is not present.",
|
||||
AliasForToSelfNonExistingAttribute.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForToOtherNonExistingAttribute() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForToOtherNonExistingAttribute.class))
|
||||
.withMessage("Attribute 'test' in annotation ["
|
||||
+ AliasForToOtherNonExistingAttribute.class.getName()
|
||||
+ "] is declared as an @AliasFor nonexistent "
|
||||
+ "attribute 'missing' in annotation ["
|
||||
+ AliasForToOtherNonExistingAttributeTarget.class.getName()
|
||||
+ "].");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToOtherNonExistingAttribute.class))
|
||||
.withMessage("Attribute 'test' in annotation [%s] is declared as an @AliasFor nonexistent " +
|
||||
"attribute 'missing' in annotation [%s].", AliasForToOtherNonExistingAttribute.class.getName(),
|
||||
AliasForToOtherNonExistingAttributeTarget.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForToSelf() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForToSelf.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation ["
|
||||
+ AliasForToSelf.class.getName()
|
||||
+ "] points to itself. Specify 'annotation' to point to "
|
||||
+ "a same-named attribute on a meta-annotation.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelf.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation [%s] points to itself. " +
|
||||
"Specify 'annotation' to point to a same-named attribute on a meta-annotation.",
|
||||
AliasForToSelf.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,13 +145,12 @@ class AnnotationTypeMappingsTests {
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForWithIncompatibleReturnTypes() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForWithIncompatibleReturnTypes.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'test' in annotation ["
|
||||
+ AliasForWithIncompatibleReturnTypes.class.getName()
|
||||
+ "] and attribute 'test' in annotation ["
|
||||
+ AliasForWithIncompatibleReturnTypesTarget.class.getName()
|
||||
+ "] must declare the same return type.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForWithIncompatibleReturnTypes.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'test' in annotation [%s] and attribute 'test' " +
|
||||
"in annotation [%s] must declare the same return type.",
|
||||
AliasForWithIncompatibleReturnTypes.class.getName(),
|
||||
AliasForWithIncompatibleReturnTypesTarget.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,9 +158,8 @@ class AnnotationTypeMappingsTests {
|
||||
String annotationType = AliasForToSelfAnnotatedToOtherAttribute.class.getName();
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelfAnnotatedToOtherAttribute.class))
|
||||
.withMessage("Attribute 'b' in annotation [" + annotationType
|
||||
+ "] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationType
|
||||
+ "], not attribute 'c' in annotation [" + annotationType + "].");
|
||||
.withMessage("Attribute 'b' in annotation [%1$s] must be declared as an @AliasFor attribute 'a' in " +
|
||||
"annotation [%1$s], not attribute 'c' in annotation [%1$s].", annotationType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,53 +173,45 @@ class AnnotationTypeMappingsTests {
|
||||
String metaAnnotationName = AliasPair.class.getName();
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(annotationType))
|
||||
.withMessage("Attribute 'b' in annotation [" + annotationName
|
||||
+ "] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationName
|
||||
+ "], not attribute '" + overriddenAttribute + "' in annotation [" + metaAnnotationName + "].");
|
||||
.withMessage("Attribute 'b' in annotation [" + annotationName +
|
||||
"] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationName +
|
||||
"], not attribute '" + overriddenAttribute + "' in annotation [" + metaAnnotationName + "].");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForNonMetaAnnotated() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForNonMetaAnnotated.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation ["
|
||||
+ AliasForNonMetaAnnotated.class.getName()
|
||||
+ "] declares an alias for attribute 'test' in annotation ["
|
||||
+ AliasForNonMetaAnnotatedTarget.class.getName()
|
||||
+ "] which is not meta-present.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForNonMetaAnnotated.class))
|
||||
.withMessage("@AliasFor declaration on attribute 'test' in annotation [" + AliasForNonMetaAnnotated.class.getName() +
|
||||
"] declares an alias for attribute 'test' in annotation [" + AliasForNonMetaAnnotatedTarget.class.getName() +
|
||||
"] which is not meta-present.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForSelfWithDifferentDefaults() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForSelfWithDifferentDefaults.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation ["
|
||||
+ AliasForSelfWithDifferentDefaults.class.getName()
|
||||
+ "] and attribute 'b' in annotation ["
|
||||
+ AliasForSelfWithDifferentDefaults.class.getName()
|
||||
+ "] must declare the same default value.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForSelfWithDifferentDefaults.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasForSelfWithDifferentDefaults.class.getName() +
|
||||
"] and attribute 'b' in annotation [" + AliasForSelfWithDifferentDefaults.class.getName() +
|
||||
"] must declare the same default value.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasForSelfWithMissingDefault() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasForSelfWithMissingDefault.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation ["
|
||||
+ AliasForSelfWithMissingDefault.class.getName()
|
||||
+ "] and attribute 'b' in annotation ["
|
||||
+ AliasForSelfWithMissingDefault.class.getName()
|
||||
+ "] must declare default values.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForSelfWithMissingDefault.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasForSelfWithMissingDefault.class.getName() +
|
||||
"] and attribute 'b' in annotation [" + AliasForSelfWithMissingDefault.class.getName() +
|
||||
"] must declare default values.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenAliasWithExplicitMirrorAndDifferentDefaults() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
AnnotationTypeMappings.forAnnotationType(AliasWithExplicitMirrorAndDifferentDefaults.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation ["
|
||||
+ AliasWithExplicitMirrorAndDifferentDefaults.class.getName()
|
||||
+ "] and attribute 'c' in annotation ["
|
||||
+ AliasWithExplicitMirrorAndDifferentDefaults.class.getName()
|
||||
+ "] must declare the same default value.");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasWithExplicitMirrorAndDifferentDefaults.class))
|
||||
.withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() +
|
||||
"] and attribute 'c' in annotation [" + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() +
|
||||
"] must declare the same default value.");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -375,18 +358,16 @@ class AnnotationTypeMappingsTests {
|
||||
@Test
|
||||
void resolveMirrorsWhenHasDifferentValuesThrowsException() {
|
||||
AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(AliasPair.class).get(0);
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
resolveMirrorSets(mapping, WithDifferentValueAliasPair.class, AliasPair.class))
|
||||
.withMessage("Different @AliasFor mirror values for annotation ["
|
||||
+ AliasPair.class.getName() + "] declared on "
|
||||
+ WithDifferentValueAliasPair.class.getName()
|
||||
+ "; attribute 'a' and its alias 'b' are declared with values of [test1] and [test2].");
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> resolveMirrorSets(mapping, WithDifferentValueAliasPair.class, AliasPair.class))
|
||||
.withMessage("Different @AliasFor mirror values for annotation [" + AliasPair.class.getName() + "] declared on " +
|
||||
WithDifferentValueAliasPair.class.getName() +
|
||||
"; attribute 'a' and its alias 'b' are declared with values of [test1] and [test2].");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveMirrorsWhenHasWithMultipleRoutesToAliasReturnsMirrors() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
MultipleRoutesToAliasA.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MultipleRoutesToAliasA.class);
|
||||
AnnotationTypeMapping mappingsA = getMapping(mappings, MultipleRoutesToAliasA.class);
|
||||
assertThat(mappingsA.getMirrorSets().size()).isZero();
|
||||
AnnotationTypeMapping mappingsB = getMapping(mappings, MultipleRoutesToAliasB.class);
|
||||
@@ -397,8 +378,7 @@ class AnnotationTypeMappingsTests {
|
||||
|
||||
@Test
|
||||
void getAliasMappingWhenHasWithMultipleRoutesToAliasReturnsMappedAttributes() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
MultipleRoutesToAliasA.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MultipleRoutesToAliasA.class);
|
||||
AnnotationTypeMapping mappingsA = getMapping(mappings, MultipleRoutesToAliasA.class);
|
||||
assertThat(getAliasMapping(mappingsA, 0)).isNull();
|
||||
AnnotationTypeMapping mappingsB = getMapping(mappings, MultipleRoutesToAliasB.class);
|
||||
|
||||
+2
-2
@@ -925,8 +925,8 @@ class AnnotationUtilsTests {
|
||||
Map<String, Object> map = Collections.singletonMap(VALUE, 42L);
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
synthesizeAnnotation(map, Component.class, null).value())
|
||||
.withMessageContaining("Attribute 'value' in annotation org.springframework.core.testfixture.stereotype.Component "
|
||||
+ "should be compatible with java.lang.String but a java.lang.Long value was returned");
|
||||
.withMessageContaining("Attribute 'value' in annotation org.springframework.core.testfixture.stereotype.Component " +
|
||||
"should be compatible with java.lang.String but a java.lang.Long value was returned");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-3
@@ -120,9 +120,7 @@ class MergedAnnotationClassLoaderTests {
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleForOverriding(String className) {
|
||||
return WITH_TEST_ANNOTATION.equals(className)
|
||||
|| TEST_ANNOTATION.equals(className)
|
||||
|| TEST_REFERENCE.equals(className);
|
||||
return WITH_TEST_ANNOTATION.equals(className) || TEST_ANNOTATION.equals(className) || TEST_REFERENCE.equals(className);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -171,8 +171,7 @@ class MergedAnnotationsCollectionTests {
|
||||
void getWithSelectorReturnsSelected() {
|
||||
MergedAnnotations annotations = getMultiRoute1();
|
||||
MergedAnnotationSelector<MultiRouteTarget> deepest = (existing,
|
||||
candidate) -> candidate.getDistance() > existing.getDistance() ? candidate
|
||||
: existing;
|
||||
candidate) -> candidate.getDistance() > existing.getDistance() ? candidate : existing;
|
||||
assertThat(annotations.get(MultiRouteTarget.class, null, deepest).getString(
|
||||
MergedAnnotation.VALUE)).isEqualTo("111");
|
||||
}
|
||||
|
||||
+16
-11
@@ -51,8 +51,10 @@ import org.junit.jupiter.api.io.TempDir;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -133,6 +135,7 @@ class PathMatchingResourcePatternResolverTests {
|
||||
assertExactFilenames("classpath*:scanned/*.txt", "resource#test1.txt", "resource#test2.txt");
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class WithHashtagsInTheirFilenames {
|
||||
|
||||
@@ -299,6 +302,7 @@ class PathMatchingResourcePatternResolverTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class ClassPathManifestEntries {
|
||||
|
||||
@@ -313,8 +317,8 @@ class PathMatchingResourcePatternResolverTests {
|
||||
writeApplicationJar(this.temp.resolve("app.jar"));
|
||||
String java = ProcessHandle.current().info().command().get();
|
||||
Process process = new ProcessBuilder(java, "-jar", "app.jar")
|
||||
.directory(this.temp.toFile())
|
||||
.start();
|
||||
.directory(this.temp.toFile())
|
||||
.start();
|
||||
assertThat(process.waitFor()).isZero();
|
||||
String result = StreamUtils.copyToString(process.getInputStream(), StandardCharsets.UTF_8);
|
||||
assertThat(result.replace("\\", "/")).contains("!!!!").contains("/lib/asset.jar!/assets/file.txt");
|
||||
@@ -328,6 +332,8 @@ class PathMatchingResourcePatternResolverTests {
|
||||
StreamUtils.copy("test", StandardCharsets.UTF_8, jar);
|
||||
jar.closeEntry();
|
||||
}
|
||||
assertThat(new FileSystemResource(path).exists()).isTrue();
|
||||
assertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue();
|
||||
}
|
||||
|
||||
private void writeApplicationJar(Path path) throws Exception {
|
||||
@@ -338,8 +344,7 @@ class PathMatchingResourcePatternResolverTests {
|
||||
mainAttributes.put(Name.MANIFEST_VERSION, "1.0");
|
||||
try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(path.toFile()), manifest)) {
|
||||
String appClassResource = ClassUtils.convertClassNameToResourcePath(
|
||||
ClassPathManifestEntriesTestApplication.class.getName())
|
||||
+ ClassUtils.CLASS_FILE_SUFFIX;
|
||||
ClassPathManifestEntriesTestApplication.class.getName()) + ClassUtils.CLASS_FILE_SUFFIX;
|
||||
String folder = "";
|
||||
for (String name : appClassResource.split("/")) {
|
||||
if (!name.endsWith(ClassUtils.CLASS_FILE_SUFFIX)) {
|
||||
@@ -356,18 +361,19 @@ class PathMatchingResourcePatternResolverTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
assertThat(new FileSystemResource(path).exists()).isTrue();
|
||||
assertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue();
|
||||
}
|
||||
|
||||
private String buildSpringClassPath() throws Exception {
|
||||
return copyClasses(PathMatchingResourcePatternResolver.class, "spring-core")
|
||||
+ copyClasses(LogFactory.class, "commons-logging");
|
||||
return copyClasses(PathMatchingResourcePatternResolver.class, "spring-core") +
|
||||
copyClasses(LogFactory.class, "commons-logging");
|
||||
}
|
||||
|
||||
private String copyClasses(Class<?> sourceClass, String destinationName)
|
||||
throws URISyntaxException, IOException {
|
||||
private String copyClasses(Class<?> sourceClass, String destinationName) throws URISyntaxException, IOException {
|
||||
Path destination = this.temp.resolve(destinationName);
|
||||
String resourcePath = ClassUtils.convertClassNameToResourcePath(sourceClass.getName())
|
||||
+ ClassUtils.CLASS_FILE_SUFFIX;
|
||||
String resourcePath = ClassUtils.convertClassNameToResourcePath(
|
||||
sourceClass.getName()) + ClassUtils.CLASS_FILE_SUFFIX;
|
||||
URL resource = getClass().getClassLoader().getResource(resourcePath);
|
||||
URL url = new URL(resource.toString().replace(resourcePath, ""));
|
||||
URLConnection connection = url.openConnection();
|
||||
@@ -393,7 +399,6 @@ class PathMatchingResourcePatternResolverTests {
|
||||
}
|
||||
return destinationName + "/ ";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -99,8 +99,8 @@ class SpringFactoriesLoaderTests {
|
||||
void loadWhenIncompatibleTypeThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> SpringFactoriesLoader.forDefaultResourceLocation().load(String.class))
|
||||
.withMessageContaining("Unable to instantiate factory class "
|
||||
+ "[org.springframework.core.io.support.MyDummyFactory1] for factory type [java.lang.String]");
|
||||
.withMessageContaining("Unable to instantiate factory class " +
|
||||
"[org.springframework.core.io.support.MyDummyFactory1] for factory type [java.lang.String]");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -127,8 +127,8 @@ class SpringFactoriesLoaderTests {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> SpringFactoriesLoader.forDefaultResourceLocation(LimitedClassLoader.multipleArgumentFactories)
|
||||
.load(DummyFactory.class, resolver))
|
||||
.withMessageContaining("Unable to instantiate factory class "
|
||||
+ "[org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] for factory type [org.springframework.core.io.support.DummyFactory]")
|
||||
.withMessageContaining("Unable to instantiate factory class " +
|
||||
"[org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] for factory type [org.springframework.core.io.support.DummyFactory]")
|
||||
.havingRootCause().withMessageContaining("Class [org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] has no suitable constructor");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,11 +21,10 @@ import java.util.Arrays;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link CompositeLog}.
|
||||
|
||||
+6
-6
@@ -218,8 +218,8 @@ abstract class AbstractStaxXMLReaderTests {
|
||||
|
||||
@Override
|
||||
public Object[] adaptArguments(Object[] arguments) {
|
||||
if (arguments.length == 3 && arguments[0] instanceof char[]
|
||||
&& arguments[1] instanceof Integer && arguments[2] instanceof Integer) {
|
||||
if (arguments.length == 3 && arguments[0] instanceof char[] &&
|
||||
arguments[1] instanceof Integer && arguments[2] instanceof Integer) {
|
||||
return new Object[] {new String((char[]) arguments[0], (Integer) arguments[1], (Integer) arguments[2])};
|
||||
}
|
||||
return arguments;
|
||||
@@ -271,10 +271,10 @@ abstract class AbstractStaxXMLReaderTests {
|
||||
for (int i = 0; i < other.getLength(); i++) {
|
||||
boolean found = false;
|
||||
for (int j = 0; j < attributes.getLength(); j++) {
|
||||
if (other.getURI(i).equals(attributes.getURI(j))
|
||||
&& other.getQName(i).equals(attributes.getQName(j))
|
||||
&& other.getType(i).equals(attributes.getType(j))
|
||||
&& other.getValue(i).equals(attributes.getValue(j))) {
|
||||
if (other.getURI(i).equals(attributes.getURI(j)) &&
|
||||
other.getQName(i).equals(attributes.getQName(j)) &&
|
||||
other.getType(i).equals(attributes.getType(j)) &&
|
||||
other.getValue(i).equals(attributes.getValue(j))) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -57,8 +57,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.doThrow;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
+2
-2
@@ -737,8 +737,8 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
parser.parseExpression("Name").setValue(societyContext, "IEEE");
|
||||
societyContext.setVariable("queryName", "Nikola Tesla");
|
||||
|
||||
String expression = "isMember(#queryName) ? #queryName + ' is a member of the ' "
|
||||
+ "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
|
||||
String expression = "isMember(#queryName) ? #queryName + ' is a member of the ' " +
|
||||
"+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
|
||||
|
||||
String queryResultString = parser.parseExpression(expression).getValue(societyContext, String.class);
|
||||
assertThat(queryResultString).isEqualTo("Nikola Tesla is a member of the IEEE Society");
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 +38,8 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.mockito.BDDMockito.doThrow;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 +25,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link DataSourceUtils}.
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,10 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link ShardingKeyDataSourceAdapter}.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,7 @@ import org.springframework.core.io.Resource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceDatabasePopulator}.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 @@ import java.sql.SQLException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link SqlArrayValue}.
|
||||
|
||||
+4
-4
@@ -293,10 +293,10 @@ class JmsNamespaceHandlerTests {
|
||||
assertThat(context.containsComponentDefinition("listener1")).as("Parser should have registered a component named 'listener1'").isTrue();
|
||||
assertThat(context.containsComponentDefinition("listener2")).as("Parser should have registered a component named 'listener2'").isTrue();
|
||||
assertThat(context.containsComponentDefinition("listener3")).as("Parser should have registered a component named 'listener3'").isTrue();
|
||||
assertThat(context.containsComponentDefinition(DefaultMessageListenerContainer.class.getName() + "#0")).as("Parser should have registered a component named '"
|
||||
+ DefaultMessageListenerContainer.class.getName() + "#0'").isTrue();
|
||||
assertThat(context.containsComponentDefinition(JmsMessageEndpointManager.class.getName() + "#0")).as("Parser should have registered a component named '"
|
||||
+ JmsMessageEndpointManager.class.getName() + "#0'").isTrue();
|
||||
assertThat(context.containsComponentDefinition(DefaultMessageListenerContainer.class.getName() + "#0")).as("Parser should have registered a component named '" +
|
||||
DefaultMessageListenerContainer.class.getName() + "#0'").isTrue();
|
||||
assertThat(context.containsComponentDefinition(JmsMessageEndpointManager.class.getName() + "#0")).as("Parser should have registered a component named '" +
|
||||
JmsMessageEndpointManager.class.getName() + "#0'").isTrue();
|
||||
assertThat(context.containsComponentDefinition("testJmsFactory")).as("Parser should have registered a component named 'testJmsFactory").isTrue();
|
||||
assertThat(context.containsComponentDefinition("testJcaFactory")).as("Parser should have registered a component named 'testJcaFactory").isTrue();
|
||||
assertThat(context.containsComponentDefinition("onlyJmsFactory")).as("Parser should have registered a component named 'testJcaFactory").isTrue();
|
||||
|
||||
@@ -530,8 +530,7 @@ class JmsTemplateTests {
|
||||
|
||||
if (!useTransactedTemplate() && !useTransactedSession()) {
|
||||
given(this.session.getAcknowledgeMode()).willReturn(
|
||||
clientAcknowledge ? Session.CLIENT_ACKNOWLEDGE
|
||||
: Session.AUTO_ACKNOWLEDGE);
|
||||
clientAcknowledge ? Session.CLIENT_ACKNOWLEDGE : Session.AUTO_ACKNOWLEDGE);
|
||||
}
|
||||
|
||||
TextMessage textMessage = mock();
|
||||
|
||||
+2
-2
@@ -71,8 +71,8 @@ public class MessagingException extends NestedRuntimeException {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + (this.failedMessage == null ? ""
|
||||
: (", failedMessage=" + this.failedMessage));
|
||||
return super.toString() + (this.failedMessage == null ? "" :
|
||||
(", failedMessage=" + this.failedMessage));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -202,8 +202,8 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
|
||||
}
|
||||
|
||||
// Do not log warning for serializer not found (note: different message wording on Jackson 2.9)
|
||||
boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage() != null
|
||||
&& cause.getMessage().startsWith("Cannot find"));
|
||||
boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage() != null &&
|
||||
cause.getMessage().startsWith("Cannot find"));
|
||||
|
||||
if (debugLevel ? logger.isDebugEnabled() : logger.isWarnEnabled()) {
|
||||
String msg = "Failed to evaluate Jackson " + (type instanceof JavaType ? "de" : "") +
|
||||
|
||||
+2
-2
@@ -176,8 +176,8 @@ public class GenericMessagingTemplate extends AbstractDestinationResolvingMessag
|
||||
accessor.removeHeader(this.receiveTimeoutHeader);
|
||||
accessor.setImmutable();
|
||||
}
|
||||
else if (message.getHeaders().containsKey(this.sendTimeoutHeader)
|
||||
|| message.getHeaders().containsKey(this.receiveTimeoutHeader)) {
|
||||
else if (message.getHeaders().containsKey(this.sendTimeoutHeader) ||
|
||||
message.getHeaders().containsKey(this.receiveTimeoutHeader)) {
|
||||
messageToSend = MessageBuilder.fromMessage(message)
|
||||
.setHeader(this.sendTimeoutHeader, null)
|
||||
.setHeader(this.receiveTimeoutHeader, null)
|
||||
|
||||
+2
-2
@@ -196,8 +196,8 @@ public class HandlerMethod extends AnnotatedMethod {
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (this == other || (super.equals(other) && other instanceof HandlerMethod otherMethod
|
||||
&& this.bean.equals(otherMethod.bean)));
|
||||
return (this == other || (super.equals(other) && other instanceof HandlerMethod otherMethod &&
|
||||
this.bean.equals(otherMethod.bean)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -126,8 +126,8 @@ public class StompEncoder {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean shouldEscape = (command != StompCommand.CONNECT && command != StompCommand.STOMP
|
||||
&& command != StompCommand.CONNECTED);
|
||||
boolean shouldEscape = (command != StompCommand.CONNECT && command != StompCommand.STOMP &&
|
||||
command != StompCommand.CONNECTED);
|
||||
|
||||
for (Entry<String, List<String>> entry : nativeHeaders.entrySet()) {
|
||||
if (command.requiresContentLength() && "content-length".equals(entry.getKey())) {
|
||||
|
||||
+2
-2
@@ -538,8 +538,8 @@ public abstract class AbstractStompBrokerRelayIntegrationTests {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", subscriptionId=\"" + this.subscriptionId
|
||||
+ "\", destination=\"" + this.destination + "\", payload=\"" + getPayloadAsText() + "\"";
|
||||
return super.toString() + ", subscriptionId=\"" + this.subscriptionId +
|
||||
"\", destination=\"" + this.destination + "\", payload=\"" + getPayloadAsText() + "\"";
|
||||
}
|
||||
|
||||
protected String getPayloadAsText() {
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 +22,8 @@ import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link DelegatingConnectionFactory}.
|
||||
|
||||
+35
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,7 @@ import io.r2dbc.spi.Connection;
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
import io.r2dbc.spi.IsolationLevel;
|
||||
import io.r2dbc.spi.R2dbcBadGrammarException;
|
||||
import io.r2dbc.spi.R2dbcTransientResourceException;
|
||||
import io.r2dbc.spi.Statement;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -32,6 +33,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.r2dbc.BadSqlGrammarException;
|
||||
import org.springframework.transaction.CannotCreateTransactionException;
|
||||
import org.springframework.transaction.IllegalTransactionStateException;
|
||||
@@ -46,13 +48,13 @@ import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.inOrder;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.never;
|
||||
import static org.mockito.BDDMockito.reset;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.BDDMockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link R2dbcTransactionManager}.
|
||||
@@ -315,6 +317,31 @@ class R2dbcTransactionManagerTests {
|
||||
verify(connectionMock).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCommitAndRollbackFails() {
|
||||
when(connectionMock.isAutoCommit()).thenReturn(false);
|
||||
when(connectionMock.commitTransaction()).thenReturn(Mono.defer(() ->
|
||||
Mono.error(new R2dbcBadGrammarException("Commit should fail"))));
|
||||
when(connectionMock.rollbackTransaction()).thenReturn(Mono.defer(() ->
|
||||
Mono.error(new R2dbcTransientResourceException("Rollback should also fail"))));
|
||||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.doOnNext(connection -> connection.createStatement("foo")).then()
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.verifyError(TransientDataAccessResourceException.class);
|
||||
|
||||
verify(connectionMock).isAutoCommit();
|
||||
verify(connectionMock).beginTransaction(any(io.r2dbc.spi.TransactionDefinition.class));
|
||||
verify(connectionMock).createStatement("foo");
|
||||
verify(connectionMock).commitTransaction();
|
||||
verify(connectionMock).rollbackTransaction();
|
||||
verify(connectionMock).close();
|
||||
verifyNoMoreInteractions(connectionMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTransactionSetRollbackOnly() {
|
||||
when(connectionMock.isAutoCommit()).thenReturn(false);
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,10 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.never;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link SingleConnectionFactory}.
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,11 +31,11 @@ import org.springframework.transaction.reactive.TransactionalOperator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.times;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.BDDMockito.verifyNoInteractions;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link TransactionAwareConnectionFactoryProxy}.
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,10 +25,10 @@ import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.times;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link CompositeDatabasePopulator}.
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 @@ import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConnectionFactoryInitializer}.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,7 @@ import org.springframework.core.io.Resource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceDatabasePopulator}.
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,8 +28,8 @@ import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link BeanFactoryConnectionFactoryLookup}.
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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,14 +50,14 @@ import org.springframework.r2dbc.core.binding.BindTarget;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.doReturn;
|
||||
import static org.mockito.BDDMockito.inOrder;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.times;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.BDDMockito.verifyNoInteractions;
|
||||
import static org.mockito.BDDMockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultDatabaseClient}.
|
||||
|
||||
+2
-2
@@ -96,8 +96,8 @@ class R2dbcBeanPropertyRowMapperTests {
|
||||
|
||||
assertThatExceptionOfType(TypeMismatchException.class)
|
||||
.isThrownBy(() -> mapper.apply(EXTENDED_PERSON_ROW))
|
||||
.withMessage("Failed to convert property value of type 'java.lang.String' to required type "
|
||||
+ "'java.lang.String' for property 'address'; simulating type mismatch for address");
|
||||
.withMessage("Failed to convert property value of type 'java.lang.String' to required type " +
|
||||
"'java.lang.String' for property 'address'; simulating type mismatch for address");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
+25
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2025 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.mock.web.server;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
@@ -39,9 +40,15 @@ import org.springframework.web.server.session.WebSessionManager;
|
||||
*/
|
||||
public final class MockServerWebExchange extends DefaultServerWebExchange {
|
||||
|
||||
private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) {
|
||||
super(request, new MockServerHttpResponse(), sessionManager,
|
||||
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver());
|
||||
|
||||
private MockServerWebExchange(
|
||||
MockServerHttpRequest request, @Nullable WebSessionManager sessionManager,
|
||||
@Nullable ApplicationContext applicationContext) {
|
||||
|
||||
super(request, new MockServerHttpResponse(),
|
||||
sessionManager != null ? sessionManager : new DefaultWebSessionManager(),
|
||||
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver(),
|
||||
applicationContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +108,9 @@ public final class MockServerWebExchange extends DefaultServerWebExchange {
|
||||
@Nullable
|
||||
private WebSessionManager sessionManager;
|
||||
|
||||
@Nullable
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public Builder(MockServerHttpRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
@@ -127,12 +137,21 @@ public final class MockServerWebExchange extends DefaultServerWebExchange {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the {@code ApplicationContext} to expose through the exchange.
|
||||
* @param applicationContext the context to use
|
||||
* @since 6.2.5
|
||||
*/
|
||||
public Builder applicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the {@code MockServerWebExchange} instance.
|
||||
*/
|
||||
public MockServerWebExchange build() {
|
||||
return new MockServerWebExchange(this.request,
|
||||
this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager());
|
||||
return new MockServerWebExchange(this.request, this.sessionManager, this.applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user