mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bea4682b7 | |||
| be17c8d85f | |||
| b73f5fcac2 | |||
| bc1511d667 | |||
| db9b139cf0 | |||
| bd029b9218 | |||
| 5f2264816a | |||
| a8f31f5b9e | |||
| 90627b4345 | |||
| 4acc71b282 | |||
| cd0379a67f | |||
| e262e98bab | |||
| 59c65fa940 | |||
| 695601aa06 | |||
| 8f5a1fe7e2 | |||
| 073226d792 | |||
| 1abe155663 | |||
| 33ef9107e0 | |||
| 8463eade33 | |||
| e77faf7484 | |||
| b23cc01cb7 | |||
| 01f97887ea | |||
| cef597bedd | |||
| 01fabfe66d | |||
| c811428512 | |||
| b5b115e52c | |||
| 310344cf61 | |||
| 2bac371c5b | |||
| cef9166833 | |||
| d6460e0d57 | |||
| 842490beeb | |||
| e746230de6 | |||
| 8161316b1d | |||
| 1734deca1e | |||
| dd97ee4e99 | |||
| 90b0f451f0 | |||
| 9fb61c57ae | |||
| f9cb0eba87 | |||
| d1d2d5943e | |||
| 281736f14e | |||
| 6bfc70b61e | |||
| 95883b9eb7 | |||
| f0eb43a6af | |||
| 6c8ebc7f7e | |||
| 69c8f8e9c7 | |||
| 02f2d94f57 | |||
| 7fcbc869a6 | |||
| 4eed2ced74 | |||
| 98f1287f3a | |||
| 8234fa2a13 | |||
| 8b9d2e3f95 | |||
| 534d1cd35b | |||
| ca545ac3d4 | |||
| ca7c2779bf | |||
| 4a90257a84 | |||
| 49a4ed2ffa | |||
| 717d03a29d | |||
| 2b427efe7f | |||
| 3632bea51e | |||
| 1efa162cf0 | |||
| a8b7a5e037 | |||
| 807325916f | |||
| d451d6adcc | |||
| 8fca258207 | |||
| d126b99c91 | |||
| c5f0f7bb11 | |||
| 3a36d51473 | |||
| fe6589d5af | |||
| b374824319 | |||
| 7e905e3e00 | |||
| 491ae1e3be | |||
| 66cdf43b56 | |||
| 2ba206f8ba | |||
| 5ba6944145 | |||
| 5609e67100 | |||
| b2be07c73c | |||
| ce2689eead | |||
| 2184d4e80e | |||
| 50d01ce405 | |||
| 0c0cda9815 | |||
| 47aca90c58 | |||
| ddd6b123bb | |||
| ec270c7135 | |||
| 7cc72ddf7a | |||
| 5f0ee2e4dd | |||
| 43031509c8 | |||
| e66c80667f | |||
| 84714fbae9 | |||
| 0ca02ce677 | |||
| db29b65399 | |||
| 18adf905a8 | |||
| ce9a72f95c | |||
| dfb4a951ae | |||
| d9776941bf | |||
| 24b359d519 | |||
| ae70bf7c38 | |||
| c68e986b75 | |||
| 2bc1aa7827 | |||
| 570d21ebbd | |||
| 800b13492b | |||
| 4e896c8125 | |||
| 9421fe1d75 | |||
| 37a4e84450 | |||
| c27a5687dc | |||
| 4e8162c6dd | |||
| 202fa5cdb3 | |||
| 8010de8b63 | |||
| 5529294ec9 | |||
| 935c29e3dd | |||
| 4a3518b4d6 | |||
| dd4a34778b | |||
| 46bd6add15 | |||
| 19384ac8ad | |||
| a0358a4650 | |||
| 88bc504625 | |||
| 3af8efbdc7 | |||
| 2e08a07d7c | |||
| df4e7d1929 | |||
| 2a5eab4b89 | |||
| 1de36abc07 | |||
| 97b5af8a55 | |||
| 4751769a7c | |||
| 1f8e9f5c55 | |||
| c3ce847871 | |||
| cd8955fa72 | |||
| d18bcb3f3d | |||
| e17f5c50a8 | |||
| 00be19c647 | |||
| a6dab10309 | |||
| b617e16d8d | |||
| 9cf7b0e230 | |||
| 3431b2330a | |||
| 99e54fec3a | |||
| 7e32f504b0 | |||
| 268e3fec99 | |||
| 9b50c0d590 | |||
| 2e5d0470dc | |||
| d2868f5dd0 | |||
| 1acbc97b16 | |||
| e88ec06a36 | |||
| 2302358606 | |||
| d213522dfc | |||
| 95710646d1 | |||
| 6cd67412cc | |||
| e427ea8086 | |||
| d8fbd35467 | |||
| a31cfba992 | |||
| 14973fd6f3 | |||
| ffe7ec4a99 | |||
| 9b811a01f6 | |||
| 2b23d1693d | |||
| 9011ce9c68 | |||
| 29fe0a3c6a | |||
| c20efba45c | |||
| fa95bf4dc1 | |||
| eea000d034 | |||
| a6338fcc43 | |||
| dafc7a2aab | |||
| b7288a4073 | |||
| 004a144bdc | |||
| 09b60220d8 | |||
| 7f1b81ff53 | |||
| 8175a3bf09 | |||
| 7eadedae36 | |||
| cb4f93561e | |||
| f3cb331e4e | |||
| 74f6725a37 | |||
| edf0ae77e5 | |||
| 95481018d0 | |||
| 56523d5014 | |||
| 8ebd746d69 | |||
| 162c09d036 | |||
| 7766b518d3 | |||
| 24de8c6f4c | |||
| d9500e60a1 | |||
| e5d20a4f9d | |||
| 37458d28d9 | |||
| c9aba1eaad | |||
| 3854861a8a | |||
| 3dd0fbfb57 |
@@ -1,5 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## JAR signing
|
||||
|
||||
Spring Framework JARs released on Maven Central are signed.
|
||||
You'll find more information about the key here: https://spring.io/GPG-KEY-spring.txt
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Please see the
|
||||
|
||||
+11
-13
@@ -1,16 +1,16 @@
|
||||
plugins {
|
||||
id 'io.spring.nohttp' version '0.0.11'
|
||||
id 'io.freefair.aspectj' version '6.5.0.3' apply false
|
||||
id 'io.freefair.aspectj' version '8.0.1' apply false
|
||||
// kotlinVersion is managed in gradle.properties
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version "${kotlinVersion}" apply false
|
||||
id 'org.jetbrains.dokka' version '1.7.20'
|
||||
id 'org.jetbrains.dokka' version '1.8.10'
|
||||
id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false
|
||||
id 'org.unbroken-dome.xjc' version '2.0.0' apply false
|
||||
id 'com.github.ben-manes.versions' version '0.42.0'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
|
||||
id 'de.undercouch.download' version '5.1.0'
|
||||
id 'me.champeau.jmh' version '0.6.8' apply false
|
||||
id 'com.github.ben-manes.versions' version '0.46.0'
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
|
||||
id 'de.undercouch.download' version '5.4.0'
|
||||
id 'me.champeau.jmh' version '0.7.0' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -78,7 +78,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.7.0"
|
||||
toolVersion = "10.9.3"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
@@ -105,11 +105,11 @@ configure([rootProject] + javaProjects) { project ->
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl")
|
||||
// JSR-305 only used for non-required meta-annotations
|
||||
compileOnly("com.google.code.findbugs:jsr305")
|
||||
testCompileOnly("com.google.code.findbugs:jsr305")
|
||||
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
|
||||
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.38")
|
||||
}
|
||||
|
||||
ext.javadocLinks = [
|
||||
@@ -127,10 +127,8 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://hc.apache.org/httpcomponents-client-5.2.x/current/httpclient5/apidocs/",
|
||||
"https://projectreactor.io/docs/test/release/api/",
|
||||
"https://junit.org/junit4/javadoc/4.13.2/",
|
||||
// TODO Uncomment link to JUnit 5 docs once we have sorted out
|
||||
// the following warning in the build.
|
||||
//
|
||||
// warning: The code being documented uses packages in the unnamed module, but the packages defined in https://junit.org/junit5/docs/5.9.2/api/ are in named modules.
|
||||
// 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.9.2/api/",
|
||||
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.gradle.testretry.TestRetryTaskExtension;
|
||||
* Conventions that are applied in the presence of the {@link JavaBasePlugin}. When the
|
||||
* plugin is applied:
|
||||
* <ul>
|
||||
* <li>The {@link TestRetryPlugin Test Retry} plugins is applied so that flaky tests
|
||||
* are retried 3 times when running on the CI.
|
||||
* <li>The {@link TestRetryPlugin Test Retry} plugin is applied so that flaky tests
|
||||
* are retried 3 times when running on the CI server.
|
||||
* </ul>
|
||||
*
|
||||
* @author Brian Clozel
|
||||
@@ -41,7 +41,7 @@ class TestConventions {
|
||||
|
||||
private void configureTestConventions(Project project) {
|
||||
project.getTasks().withType(Test.class,
|
||||
(test) -> project.getPlugins().withType(TestRetryPlugin.class, (testRetryPlugin) -> {
|
||||
test -> project.getPlugins().withType(TestRetryPlugin.class, testRetryPlugin -> {
|
||||
TestRetryTaskExtension testRetry = test.getExtensions().getByType(TestRetryTaskExtension.class);
|
||||
testRetry.getFailOnPassedAfterRetry().set(true);
|
||||
testRetry.getMaxRetries().set(isCi() ? 3 : 0);
|
||||
|
||||
@@ -6,6 +6,6 @@ RUN ./setup.sh
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk/java17
|
||||
ENV JDK17 /opt/openjdk/java17
|
||||
ENV JDK19 /opt/openjdk/java19
|
||||
ENV JDK20 /opt/openjdk/java20
|
||||
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
|
||||
@@ -5,8 +5,8 @@ case "$1" in
|
||||
java17)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.6+10/bellsoft-jdk17.0.6+10-linux-amd64.tar.gz"
|
||||
;;
|
||||
java19)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/19.0.2+9/bellsoft-jdk19.0.2+9-linux-amd64.tar.gz"
|
||||
java20)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/20%2B37/bellsoft-jdk20+37-linux-amd64.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/c
|
||||
|
||||
mkdir -p /opt/openjdk
|
||||
pushd /opt/openjdk > /dev/null
|
||||
for jdk in java17 java19
|
||||
for jdk in java17 java20
|
||||
do
|
||||
JDK_URL=$( /get-jdk-url.sh $jdk )
|
||||
mkdir $jdk
|
||||
|
||||
+8
-8
@@ -127,14 +127,14 @@ resources:
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: build
|
||||
- name: repo-status-jdk19-build
|
||||
- name: repo-status-jdk20-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk19-build
|
||||
context: jdk20-build
|
||||
- name: slack-alert
|
||||
type: slack-notification
|
||||
icon: slack
|
||||
@@ -231,7 +231,7 @@ jobs:
|
||||
"zip.type": "schema"
|
||||
get_params:
|
||||
threads: 8
|
||||
- name: jdk19-build
|
||||
- name: jdk20-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
@@ -239,7 +239,7 @@ jobs:
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk19-build
|
||||
- put: repo-status-jdk20-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
@@ -248,16 +248,16 @@ jobs:
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
TEST_TOOLCHAIN: 19
|
||||
TEST_TOOLCHAIN: 20
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk19-build
|
||||
- put: repo-status-jdk20-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk19-build
|
||||
- put: repo-status-jdk20-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: build-pull-requests
|
||||
serial: true
|
||||
@@ -441,7 +441,7 @@ jobs:
|
||||
|
||||
groups:
|
||||
- name: "builds"
|
||||
jobs: ["build", "jdk19-build"]
|
||||
jobs: ["build", "jdk20-build"]
|
||||
- name: "releases"
|
||||
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
|
||||
- name: "ci-images"
|
||||
|
||||
@@ -4,6 +4,6 @@ set -e
|
||||
source $(dirname $0)/common.sh
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17,JDK19 \
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17,JDK20 \
|
||||
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
|
||||
popd > /dev/null
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
aot=core.aot
|
||||
aot-basics=core.aot.basics
|
||||
aot-refresh=core.aot.refresh
|
||||
aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions
|
||||
aot-bean-registration-contributions=core.aot.bean-registration-contributions
|
||||
aot-hints=core.aot.hints
|
||||
aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints
|
||||
aot-hints-reflective=core.aot.hints.reflective
|
||||
aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding
|
||||
@@ -1300,7 +1300,7 @@ listing shows our custom `BeanDefinitionParser` implementation:
|
||||
}
|
||||
|
||||
private static void parseChildComponents(List<Element> childElements, BeanDefinitionBuilder factory) {
|
||||
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(childElements.size());
|
||||
ManagedList<BeanDefinition> children = new ManagedList<>(childElements.size());
|
||||
for (Element element : childElements) {
|
||||
children.add(parseComponentElement(element));
|
||||
}
|
||||
|
||||
@@ -7189,7 +7189,7 @@ You can add the following dependency to your file pom.xml:
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
<version>1</version>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
----
|
||||
=====
|
||||
|
||||
@@ -293,7 +293,7 @@ being placed in it. The following example shows how to do so:
|
||||
.Java
|
||||
----
|
||||
class Simple {
|
||||
public List<Boolean> booleanList = new ArrayList<Boolean>();
|
||||
public List<Boolean> booleanList = new ArrayList<>();
|
||||
}
|
||||
|
||||
Simple simple = new Simple();
|
||||
@@ -1478,7 +1478,7 @@ show how to use the `#this` and `#root` variables:
|
||||
.Java
|
||||
----
|
||||
// create an array of integers
|
||||
List<Integer> primes = new ArrayList<Integer>();
|
||||
List<Integer> primes = new ArrayList<>();
|
||||
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
|
||||
|
||||
// create parser and set variable 'primes' as the array of integers
|
||||
@@ -2122,7 +2122,7 @@ This section lists the classes used in the examples throughout this chapter.
|
||||
public static String Advisors = "advisors";
|
||||
public static String President = "president";
|
||||
|
||||
private List<Inventor> members = new ArrayList<Inventor>();
|
||||
private List<Inventor> members = new ArrayList<>();
|
||||
private Map officers = new HashMap();
|
||||
|
||||
public List getMembers() {
|
||||
|
||||
@@ -1028,12 +1028,30 @@ the call stack and makes a determination whether to mark the transaction for rol
|
||||
In its default configuration, the Spring Framework's transaction infrastructure code
|
||||
marks a transaction for rollback only in the case of runtime, unchecked exceptions.
|
||||
That is, when the thrown exception is an instance or subclass of `RuntimeException`.
|
||||
(`Error` instances also, by default, result in a rollback). Checked exceptions that are
|
||||
thrown from a transactional method do not result in rollback in the default
|
||||
configuration.
|
||||
(`Error` instances also, by default, result in a rollback).
|
||||
|
||||
You can configure exactly which `Exception` types mark a transaction for rollback,
|
||||
including checked exceptions by specifying _rollback rules_.
|
||||
As of Spring Framework 5.2, the default configuration also provides support for
|
||||
Vavr's `Try` method to trigger transaction rollbacks when it returns a 'Failure'.
|
||||
This allows you to handle functional-style errors using Try and have the transaction
|
||||
automatically rolled back in case of a failure. For more information on Vavr's Try,
|
||||
refer to the [official Vavr documentation](https://www.vavr.io/vavr-docs/#_try).
|
||||
|
||||
Here's an example of how to use Vavr's Try with a transactional method:
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Transactional
|
||||
public Try<String> myTransactionalMethod() {
|
||||
// If myDataAccessOperation throws an exception, it will be caught by the
|
||||
// Try instance created with Try.of() and wrapped inside the Failure class
|
||||
// which can be checked using the isFailure() method on the Try instance.
|
||||
return Try.of(delegate::myDataAccessOperation);
|
||||
}
|
||||
----
|
||||
|
||||
Checked exceptions that are thrown from a transactional method do not result in a rollback
|
||||
in the default configuration. You can configure exactly which `Exception` types mark a
|
||||
transaction for rollback, including checked exceptions by specifying _rollback rules_.
|
||||
|
||||
.Rollback rules
|
||||
[[transaction-declarative-rollback-rules]]
|
||||
@@ -4528,7 +4546,7 @@ JDBC `?` placeholders:
|
||||
}
|
||||
|
||||
public int[] batchUpdate(final List<Actor> actors) {
|
||||
List<Object[]> batch = new ArrayList<Object[]>();
|
||||
List<Object[]> batch = new ArrayList<>();
|
||||
for (Actor actor : actors) {
|
||||
Object[] values = new Object[] {
|
||||
actor.getFirstName(), actor.getLastName(), actor.getId()};
|
||||
@@ -4692,7 +4710,7 @@ example uses only one configuration method (we show examples of multiple methods
|
||||
}
|
||||
|
||||
public void add(Actor actor) {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>(3);
|
||||
Map<String, Object> parameters = new HashMap<>(3);
|
||||
parameters.put("id", actor.getId());
|
||||
parameters.put("first_name", actor.getFirstName());
|
||||
parameters.put("last_name", actor.getLastName());
|
||||
@@ -4750,7 +4768,7 @@ listing shows how it works:
|
||||
}
|
||||
|
||||
public void add(Actor actor) {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
||||
Map<String, Object> parameters = new HashMap<>(2);
|
||||
parameters.put("first_name", actor.getFirstName());
|
||||
parameters.put("last_name", actor.getLastName());
|
||||
Number newId = insertActor.executeAndReturnKey(parameters);
|
||||
@@ -4810,7 +4828,7 @@ You can limit the columns for an insert by specifying a list of column names wit
|
||||
}
|
||||
|
||||
public void add(Actor actor) {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
||||
Map<String, Object> parameters = new HashMap<>(2);
|
||||
parameters.put("first_name", actor.getFirstName());
|
||||
parameters.put("last_name", actor.getLastName());
|
||||
Number newId = insertActor.executeAndReturnKey(parameters);
|
||||
|
||||
@@ -13,7 +13,7 @@ Spring MVC Test, WebTestClient.
|
||||
JDBC, R2DBC, O/R Mapping, XML Marshalling.
|
||||
<<web.adoc#spring-web, Web Servlet>> :: Spring MVC, WebSocket, SockJS,
|
||||
STOMP Messaging.
|
||||
<<web-reactive.adoc#spring-webflux, Web Reactive>> :: Spring WebFlux, WebClient,
|
||||
<<web-reactive.adoc#spring-web-reactive, Web Reactive>> :: Spring WebFlux, WebClient,
|
||||
WebSocket, RSocket.
|
||||
<<integration.adoc#spring-integration, Integration>> :: REST Clients, JMS, JCA, JMX,
|
||||
Email, Tasks, Scheduling, Caching, Observability.
|
||||
|
||||
@@ -9,6 +9,30 @@ Traces provide a holistic view of an entire system, crossing application boundar
|
||||
Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.
|
||||
You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].
|
||||
|
||||
|
||||
[[integration.observability.list]]
|
||||
== List of produced Observations
|
||||
|
||||
Spring Framework instruments various features for observability.
|
||||
As outlined <<integration.observability,at the beginning of this section>>, observations can generate timer Metrics and/or Traces depending on the configuration.
|
||||
|
||||
.Observations produced by Spring Framework
|
||||
[%autowidth]
|
||||
|===
|
||||
|Observation name |Description
|
||||
|
||||
|<<integration.observability.http-client,`"http.client.requests"`>>
|
||||
|Time spent for HTTP client exchanges
|
||||
|
||||
|<<integration.observability.http-server,`"http.server.requests"`>>
|
||||
|Processing time for HTTP server exchanges at the Framework level
|
||||
|===
|
||||
|
||||
NOTE: Observations are using Micrometer's official naming convention, but Metrics names will be automatically converted
|
||||
https://micrometer.io/docs/concepts#_naming_meters[to the format preferred by the monitoring system backend]
|
||||
(Prometheus, Atlas, Graphite, InfluxDB...).
|
||||
|
||||
|
||||
[[integration.observability.concepts]]
|
||||
== Micrometer Observation concepts
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ By default global configuration enables the following:
|
||||
* `GET`, `HEAD`, and `POST` methods.
|
||||
|
||||
`allowedCredentials` is not enabled by default, since that establishes a trust level
|
||||
that exposes sensitive user-specific information( such as cookies and CSRF tokens) and
|
||||
that exposes sensitive user-specific information (such as cookies and CSRF tokens) and
|
||||
should be used only where appropriate. When it is enabled either `allowOrigins` must be
|
||||
set to one or more specific domain (but not the special value `"*"`) or alternatively
|
||||
the `allowOriginPatterns` property may be used to match to a dynamic set of origins.
|
||||
|
||||
@@ -1655,7 +1655,7 @@ content types that a controller method produces, as the following example shows:
|
||||
----
|
||||
@GetMapping("/pets/{petId}", produces = ["application/json"])
|
||||
@ResponseBody
|
||||
fun getPet(@PathVariable String petId): Pet {
|
||||
fun getPet(@PathVariable petId: String): Pet {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@@ -1704,7 +1704,7 @@ You can also use the same with request header conditions, as the following examp
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@GetMapping(path = "/pets", headers = "myHeader=myValue") // <1>
|
||||
@GetMapping(path = "/pets/{petId}", headers = "myHeader=myValue") // <1>
|
||||
public void findPet(@PathVariable String petId) {
|
||||
// ...
|
||||
}
|
||||
@@ -1714,7 +1714,7 @@ You can also use the same with request header conditions, as the following examp
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@GetMapping("/pets", headers = ["myHeader=myValue"]) // <1>
|
||||
@GetMapping("/pets/{petId}", headers = ["myHeader=myValue"]) // <1>
|
||||
fun findPet(@PathVariable petId: String) {
|
||||
// ...
|
||||
}
|
||||
@@ -2504,7 +2504,7 @@ reactive type, as the following example shows:
|
||||
----
|
||||
|
||||
Note that use of `@ModelAttribute` is optional -- for example, to set its attributes.
|
||||
By default, any argument that is not a simple value type( as determined by
|
||||
By default, any argument that is not a simple value type (as determined by
|
||||
{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])
|
||||
and is not resolved by any other argument resolver is treated as if it were annotated
|
||||
with `@ModelAttribute`.
|
||||
|
||||
@@ -743,7 +743,7 @@ or to render a JSON response, as the following example shows:
|
||||
|
||||
@RequestMapping(path = "/error")
|
||||
public Map<String, Object> handle(HttpServletRequest request) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("status", request.getAttribute("jakarta.servlet.error.status_code"));
|
||||
map.put("reason", request.getAttribute("jakarta.servlet.error.message"));
|
||||
return map;
|
||||
@@ -1903,7 +1903,7 @@ You can also use the same with request header conditions, as the following examp
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@GetMapping(path = "/pets", headers = "myHeader=myValue") // <1>
|
||||
@GetMapping(path = "/pets/{petId}", headers = "myHeader=myValue") // <1>
|
||||
public void findPet(@PathVariable String petId) {
|
||||
// ...
|
||||
}
|
||||
@@ -1913,7 +1913,7 @@ You can also use the same with request header conditions, as the following examp
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@GetMapping("/pets", headers = ["myHeader=myValue"]) // <1>
|
||||
@GetMapping("/pets/{petId}", headers = ["myHeader=myValue"]) // <1>
|
||||
fun findPet(@PathVariable petId: String) {
|
||||
// ...
|
||||
}
|
||||
@@ -4393,7 +4393,7 @@ return value with `DeferredResult`, as the following example shows:
|
||||
@GetMapping("/quotes")
|
||||
@ResponseBody
|
||||
public DeferredResult<String> quotes() {
|
||||
DeferredResult<String> deferredResult = new DeferredResult<String>();
|
||||
DeferredResult<String> deferredResult = new DeferredResult<>();
|
||||
// Save the deferredResult somewhere..
|
||||
return deferredResult;
|
||||
}
|
||||
|
||||
@@ -8,32 +8,32 @@ javaPlatform {
|
||||
|
||||
dependencies {
|
||||
api(platform("com.fasterxml.jackson:jackson-bom:2.14.2"))
|
||||
api(platform("io.micrometer:micrometer-bom:1.10.4"))
|
||||
api(platform("io.netty:netty-bom:4.1.89.Final"))
|
||||
api(platform("io.micrometer:micrometer-bom:1.10.6"))
|
||||
api(platform("io.netty:netty-bom:4.1.91.Final"))
|
||||
api(platform("io.netty:netty5-bom:5.0.0.Alpha5"))
|
||||
api(platform("io.projectreactor:reactor-bom:2022.0.4"))
|
||||
api(platform("io.projectreactor:reactor-bom:2022.0.6"))
|
||||
api(platform("io.rsocket:rsocket-bom:1.1.3"))
|
||||
api(platform("org.apache.groovy:groovy-bom:4.0.8"))
|
||||
api(platform("org.apache.logging.log4j:log4j-bom:2.19.0"))
|
||||
api(platform("org.eclipse.jetty:jetty-bom:11.0.13"))
|
||||
api(platform("org.apache.groovy:groovy-bom:4.0.11"))
|
||||
api(platform("org.apache.logging.log4j:log4j-bom:2.20.0"))
|
||||
api(platform("org.eclipse.jetty:jetty-bom:11.0.14"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4"))
|
||||
api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.4.0"))
|
||||
api(platform("org.junit:junit-bom:5.9.2"))
|
||||
api(platform("org.mockito:mockito-bom:5.1.1"))
|
||||
api(platform("org.mockito:mockito-bom:5.3.0"))
|
||||
|
||||
constraints {
|
||||
api("com.fasterxml:aalto-xml:1.3.1")
|
||||
api("com.fasterxml:aalto-xml:1.3.2")
|
||||
api("com.fasterxml.woodstox:woodstox-core:6.5.0")
|
||||
api("com.github.ben-manes.caffeine:caffeine:3.1.2")
|
||||
api("com.github.ben-manes.caffeine:caffeine:3.1.5")
|
||||
api("com.github.librepdf:openpdf:1.3.30")
|
||||
api("com.google.code.findbugs:findbugs:3.0.1")
|
||||
api("com.google.code.findbugs:jsr305:3.0.2")
|
||||
api("com.google.code.gson:gson:2.10")
|
||||
api("com.google.code.gson:gson:2.10.1")
|
||||
api("com.google.protobuf:protobuf-java-util:3.21.12")
|
||||
api("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
|
||||
api("com.h2database:h2:2.1.214")
|
||||
api("com.jayway.jsonpath:json-path:2.7.0")
|
||||
api("com.rometools:rome:1.18.0")
|
||||
api("com.jayway.jsonpath:json-path:2.8.0")
|
||||
api("com.rometools:rome:1.19.0")
|
||||
api("com.squareup.okhttp3:mockwebserver:3.14.9")
|
||||
api("com.squareup.okhttp3:okhttp:3.14.9")
|
||||
api("com.sun.activation:jakarta.activation:2.0.1")
|
||||
@@ -41,31 +41,31 @@ dependencies {
|
||||
api("com.sun.xml.bind:jaxb-core:3.0.2")
|
||||
api("com.sun.xml.bind:jaxb-impl:3.0.2")
|
||||
api("com.sun.xml.bind:jaxb-xjc:3.0.2")
|
||||
api("com.thoughtworks.qdox:qdox:2.0.2")
|
||||
api("com.thoughtworks.xstream:xstream:1.4.19")
|
||||
api("com.thoughtworks.qdox:qdox:2.0.3")
|
||||
api("com.thoughtworks.xstream:xstream:1.4.20")
|
||||
api("commons-io:commons-io:2.11.0")
|
||||
api("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1")
|
||||
api("info.picocli:picocli:4.7.0")
|
||||
api("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.2")
|
||||
api("info.picocli:picocli:4.7.1")
|
||||
api("io.micrometer:context-propagation:1.0.0")
|
||||
api("io.mockk:mockk:1.12.1")
|
||||
api("io.mockk:mockk:1.13.4")
|
||||
api("io.projectreactor.netty:reactor-netty5-http:2.0.0-M3")
|
||||
api("io.projectreactor.tools:blockhound:1.0.6.RELEASE")
|
||||
api("io.projectreactor.tools:blockhound:1.0.7.RELEASE")
|
||||
api("io.r2dbc:r2dbc-h2:1.0.0.RELEASE")
|
||||
api("io.r2dbc:r2dbc-spi-test:1.0.0.RELEASE")
|
||||
api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE")
|
||||
api("io.reactivex.rxjava3:rxjava:3.1.5")
|
||||
api("io.smallrye.reactive:mutiny:1.8.0")
|
||||
api("io.undertow:undertow-core:2.3.3.Final")
|
||||
api("io.undertow:undertow-servlet:2.3.3.Final")
|
||||
api("io.undertow:undertow-websockets-jsr:2.3.3.Final")
|
||||
api("io.reactivex.rxjava3:rxjava:3.1.6")
|
||||
api("io.smallrye.reactive:mutiny:1.9.0")
|
||||
api("io.undertow:undertow-core:2.3.5.Final")
|
||||
api("io.undertow:undertow-servlet:2.3.5.Final")
|
||||
api("io.undertow:undertow-websockets-jsr:2.3.5.Final")
|
||||
api("io.vavr:vavr:0.10.4")
|
||||
api("jakarta.activation:jakarta.activation-api:2.0.1")
|
||||
api("jakarta.annotation:jakarta.annotation-api:2.0.0")
|
||||
api("jakarta.ejb:jakarta.ejb-api:4.0.0")
|
||||
api("jakarta.ejb:jakarta.ejb-api:4.0.1")
|
||||
api("jakarta.el:jakarta.el-api:4.0.0")
|
||||
api("jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api:2.0.0")
|
||||
api("jakarta.faces:jakarta.faces-api:3.0.0")
|
||||
api("jakarta.inject:jakarta.inject-api:2.0.0")
|
||||
api("jakarta.inject:jakarta.inject-api:2.0.1")
|
||||
api("jakarta.inject:jakarta.inject-tck:2.0.1")
|
||||
api("jakarta.interceptor:jakarta.interceptor-api:2.0.0")
|
||||
api("jakarta.jms:jakarta.jms-api:3.0.0")
|
||||
@@ -75,7 +75,7 @@ dependencies {
|
||||
api("jakarta.persistence:jakarta.persistence-api:3.0.0")
|
||||
api("jakarta.resource:jakarta.resource-api:2.0.0")
|
||||
api("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0")
|
||||
api("jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.0")
|
||||
api("jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.1")
|
||||
api("jakarta.servlet:jakarta.servlet-api:6.0.0")
|
||||
api("jakarta.transaction:jakarta.transaction-api:2.0.1")
|
||||
api("jakarta.validation:jakarta.validation-api:3.0.2")
|
||||
@@ -89,9 +89,9 @@ dependencies {
|
||||
api("net.sf.jopt-simple:jopt-simple:5.0.4")
|
||||
api("net.sourceforge.htmlunit:htmlunit:2.70.0")
|
||||
api("org.apache-extras.beanshell:bsh:2.0b6")
|
||||
api("org.apache.activemq:activemq-broker:5.16.2")
|
||||
api("org.apache.activemq:activemq-kahadb-store:5.16.2")
|
||||
api("org.apache.activemq:activemq-stomp:5.16.2")
|
||||
api("org.apache.activemq:activemq-broker:5.17.2")
|
||||
api("org.apache.activemq:activemq-kahadb-store:5.17.2")
|
||||
api("org.apache.activemq:activemq-stomp:5.17.2")
|
||||
api("org.apache.commons:commons-pool2:2.9.0")
|
||||
api("org.apache.derby:derby:10.16.1.1")
|
||||
api("org.apache.derby:derbyclient:10.16.1.1")
|
||||
@@ -99,45 +99,45 @@ dependencies {
|
||||
api("org.apache.httpcomponents.client5:httpclient5:5.2.1")
|
||||
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.2.1")
|
||||
api("org.apache.poi:poi-ooxml:5.2.3")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.5")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.5")
|
||||
api("org.apache.tomcat:tomcat-util:10.1.5")
|
||||
api("org.apache.tomcat:tomcat-websocket:10.1.5")
|
||||
api("org.aspectj:aspectjrt:1.9.9.1")
|
||||
api("org.aspectj:aspectjtools:1.9.9.1")
|
||||
api("org.aspectj:aspectjweaver:1.9.9.1")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.7")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.7")
|
||||
api("org.apache.tomcat:tomcat-util:10.1.7")
|
||||
api("org.apache.tomcat:tomcat-websocket:10.1.7")
|
||||
api("org.aspectj:aspectjrt:1.9.19")
|
||||
api("org.aspectj:aspectjtools:1.9.19")
|
||||
api("org.aspectj:aspectjweaver:1.9.19")
|
||||
api("org.assertj:assertj-core:3.24.2")
|
||||
api("org.awaitility:awaitility:3.1.6")
|
||||
api("org.bouncycastle:bcpkix-jdk18on:1.71")
|
||||
api("org.codehaus.jettison:jettison:1.3.8")
|
||||
api("org.dom4j:dom4j:2.1.3")
|
||||
api("org.eclipse.jetty:jetty-reactive-httpclient:3.0.7")
|
||||
api("org.awaitility:awaitility:4.2.0")
|
||||
api("org.bouncycastle:bcpkix-jdk18on:1.72")
|
||||
api("org.codehaus.jettison:jettison:1.5.4")
|
||||
api("org.dom4j:dom4j:2.1.4")
|
||||
api("org.eclipse.jetty:jetty-reactive-httpclient:3.0.8")
|
||||
api("org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.3")
|
||||
api("org.eclipse:yasson:2.0.4")
|
||||
api("org.ehcache:ehcache:3.4.0")
|
||||
api("org.ehcache:ehcache:3.10.8")
|
||||
api("org.ehcache:jcache:1.0.1")
|
||||
api("org.freemarker:freemarker:2.3.32")
|
||||
// Substitute for "javax.management:jmxremote_optional:1.0.1_04" which
|
||||
// is not available on Maven Central
|
||||
api("org.glassfish.external:opendmk_jmxremote_optional_jar:1.0-b01-ea")
|
||||
api("org.glassfish.tyrus:tyrus-container-servlet:2.0.1")
|
||||
api("org.glassfish.tyrus:tyrus-container-servlet:2.1.3")
|
||||
api("org.glassfish:jakarta.el:4.0.2")
|
||||
api("org.graalvm.sdk:graal-sdk:22.3.0")
|
||||
api("org.graalvm.sdk:graal-sdk:22.3.1")
|
||||
api("org.hamcrest:hamcrest:2.2")
|
||||
api("org.hibernate:hibernate-core-jakarta:5.6.15.Final")
|
||||
api("org.hibernate:hibernate-validator:7.0.5.Final")
|
||||
api("org.hsqldb:hsqldb:2.7.1")
|
||||
api("org.javamoney:moneta:1.4.2")
|
||||
api("org.jruby:jruby:9.4.0.0")
|
||||
api("org.jruby:jruby:9.4.2.0")
|
||||
api("org.junit.support:testng-engine:1.0.4")
|
||||
api("org.mozilla:rhino:1.7.11")
|
||||
api("org.mozilla:rhino:1.7.14")
|
||||
api("org.ogce:xpp3:1.1.6")
|
||||
api("org.python:jython-standalone:2.7.1")
|
||||
api("org.python:jython-standalone:2.7.3")
|
||||
api("org.quartz-scheduler:quartz:2.3.2")
|
||||
api("org.seleniumhq.selenium:htmlunit-driver:2.70.0")
|
||||
api("org.seleniumhq.selenium:selenium-java:3.141.59")
|
||||
api("org.skyscreamer:jsonassert:1.5.0")
|
||||
api("org.slf4j:slf4j-api:2.0.6")
|
||||
api("org.skyscreamer:jsonassert:1.5.1")
|
||||
api("org.slf4j:slf4j-api:2.0.7")
|
||||
api("org.testng:testng:7.7.1")
|
||||
api("org.webjars:underscorejs:1.8.3")
|
||||
api("org.webjars:webjars-locator-core:0.52")
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=6.0.6-SNAPSHOT
|
||||
version=6.0.8
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
* One can choose the toolchain to use for compiling the MAIN sources and/or compiling
|
||||
* and running the TEST sources. These options apply to Java, Kotlin and Groovy sources
|
||||
* when available.
|
||||
* {@code "./gradlew check -PmainToolchain=17 -PtestToolchain=19"} will use:
|
||||
* {@code "./gradlew check -PmainToolchain=17 -PtestToolchain=20"} will use:
|
||||
* <ul>
|
||||
* <li>a JDK17 toolchain for compiling the main SourceSet
|
||||
* <li>a JDK19 toolchain for compiling and running the test SourceSet
|
||||
* <li>a JDK20 toolchain for compiling and running the test SourceSet
|
||||
* </ul>
|
||||
*
|
||||
* By default, the build will fall back to using the current JDK and 17 language level for all sourceSets.
|
||||
@@ -23,9 +23,9 @@
|
||||
* {@code
|
||||
* $ echo JDK17
|
||||
* /opt/openjdk/java17
|
||||
* $ echo JDK19
|
||||
* /opt/openjdk/java18
|
||||
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK17,JDK19 check
|
||||
* $ echo JDK20
|
||||
* /opt/openjdk/java20
|
||||
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK17,JDK20 check
|
||||
* }
|
||||
*
|
||||
* @author Brian Clozel
|
||||
@@ -81,6 +81,7 @@ plugins.withType(JavaPlugin) {
|
||||
javaLauncher = javaToolchains.launcherFor {
|
||||
languageVersion = testLanguageVersion
|
||||
}
|
||||
jvmArgs += ['-Djava.locale.providers=COMPAT']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -99,7 +99,7 @@ class AopNamespaceHandlerScopeIntegrationTests {
|
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(oldRequest));
|
||||
assertThat(requestScoped.getName()).isEqualTo(bram);
|
||||
|
||||
assertThat(((Advised) requestScoped).getAdvisors().length > 0).as("Should have advisors").isTrue();
|
||||
assertThat(((Advised) requestScoped).getAdvisors()).as("Should have advisors").isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,7 +131,7 @@ class AopNamespaceHandlerScopeIntegrationTests {
|
||||
request.setSession(oldSession);
|
||||
assertThat(sessionScoped.getName()).isEqualTo(bram);
|
||||
|
||||
assertThat(((Advised) sessionScoped).getAdvisors().length > 0).as("Should have advisors").isTrue();
|
||||
assertThat(((Advised) sessionScoped).getAdvisors()).as("Should have advisors").isNotEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,25 +52,25 @@ class ComponentBeanDefinitionParserTests {
|
||||
@Test
|
||||
void testBionicBasic() {
|
||||
Component cp = getBionicFamily();
|
||||
assertThat("Bionic-1").isEqualTo(cp.getName());
|
||||
assertThat(cp.getName()).isEqualTo("Bionic-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBionicFirstLevelChildren() {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents();
|
||||
assertThat(2).isEqualTo(components.size());
|
||||
assertThat("Mother-1").isEqualTo(components.get(0).getName());
|
||||
assertThat("Rock-1").isEqualTo(components.get(1).getName());
|
||||
assertThat(components).hasSize(2);
|
||||
assertThat(components.get(0).getName()).isEqualTo("Mother-1");
|
||||
assertThat(components.get(1).getName()).isEqualTo("Rock-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBionicSecondLevelChildren() {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents().get(0).getComponents();
|
||||
assertThat(2).isEqualTo(components.size());
|
||||
assertThat("Karate-1").isEqualTo(components.get(0).getName());
|
||||
assertThat("Sport-1").isEqualTo(components.get(1).getName());
|
||||
assertThat(components).hasSize(2);
|
||||
assertThat(components.get(0).getName()).isEqualTo("Karate-1");
|
||||
assertThat(components.get(1).getName()).isEqualTo("Sport-1");
|
||||
}
|
||||
|
||||
private Component getBionicFamily() {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.12.3"
|
||||
id "com.gradle.enterprise" version "3.12.6"
|
||||
id "io.spring.ge.conventions" version "0.0.13"
|
||||
}
|
||||
|
||||
|
||||
+15
-9
@@ -248,20 +248,26 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
/**
|
||||
* Set by creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML,
|
||||
* Set by the creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML
|
||||
* or in an advice annotation.
|
||||
* @param argNames comma delimited list of arg names
|
||||
* @param argumentNames comma delimited list of argument names
|
||||
*/
|
||||
public void setArgumentNames(String argNames) {
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(argNames);
|
||||
public void setArgumentNames(String argumentNames) {
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(argumentNames);
|
||||
setArgumentNamesFromStringArray(tokens);
|
||||
}
|
||||
|
||||
public void setArgumentNamesFromStringArray(String... args) {
|
||||
this.argumentNames = new String[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
this.argumentNames[i] = args[i].strip();
|
||||
/**
|
||||
* Set by the creator of this advice object if the argument names are known.
|
||||
* <p>This could be for example because they have been explicitly specified in XML
|
||||
* or in an advice annotation.
|
||||
* @param argumentNames list of argument names
|
||||
*/
|
||||
public void setArgumentNamesFromStringArray(String... argumentNames) {
|
||||
this.argumentNames = new String[argumentNames.length];
|
||||
for (int i = 0; i < argumentNames.length; i++) {
|
||||
this.argumentNames[i] = argumentNames[i].strip();
|
||||
if (!isVariableName(this.argumentNames[i])) {
|
||||
throw new IllegalArgumentException(
|
||||
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -117,7 +117,7 @@ public class TypePatternClassFilter implements ClassFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
return (this == obj || (obj instanceof TypePatternClassFilter that &&
|
||||
ObjectUtils.nullSafeEquals(this.typePattern, that.typePattern)));
|
||||
}
|
||||
|
||||
+7
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2023 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,20 +21,13 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
|
||||
/**
|
||||
* Internal framework class, combining a MethodInterceptor instance
|
||||
* with a MethodMatcher for use as an element in the advisor chain.
|
||||
* Internal framework record, combining a {@link MethodInterceptor} instance
|
||||
* with a {@link MethodMatcher} for use as an element in the advisor chain.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @param interceptor the {@code MethodInterceptor}
|
||||
* @param matcher the {@code MethodMatcher}
|
||||
*/
|
||||
class InterceptorAndDynamicMethodMatcher {
|
||||
|
||||
final MethodInterceptor interceptor;
|
||||
|
||||
final MethodMatcher methodMatcher;
|
||||
|
||||
public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
|
||||
this.interceptor = interceptor;
|
||||
this.methodMatcher = methodMatcher;
|
||||
}
|
||||
|
||||
record InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher matcher) {
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -120,6 +120,11 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
|
||||
}
|
||||
if (classLoader == null || classLoader.getParent() == null) {
|
||||
// JDK bootstrap loader or platform loader suggested ->
|
||||
// use higher-level loader which can see Spring infrastructure classes
|
||||
classLoader = getClass().getClassLoader();
|
||||
}
|
||||
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -169,8 +169,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
// Evaluate dynamic method matcher here: static part will already have
|
||||
// been evaluated and found to match.
|
||||
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
|
||||
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
|
||||
return dm.interceptor.invoke(this);
|
||||
if (dm.matcher().matches(this.method, targetClass, this.arguments)) {
|
||||
return dm.interceptor().invoke(this);
|
||||
}
|
||||
else {
|
||||
// Dynamic matching failed.
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -58,11 +58,11 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private ConfigurableBeanFactory beanFactory;
|
||||
|
||||
/** Internally used DefaultListableBeanFactory instances, keyed by bean name. */
|
||||
private final Map<String, DefaultListableBeanFactory> internalBeanFactories =
|
||||
new HashMap<>();
|
||||
private final Map<String, DefaultListableBeanFactory> internalBeanFactories = new HashMap<>();
|
||||
|
||||
|
||||
@Override
|
||||
@@ -77,6 +77,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
/**
|
||||
* Return the BeanFactory that this TargetSourceCreators runs in.
|
||||
*/
|
||||
@Nullable
|
||||
protected final BeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -55,8 +55,8 @@ class ScopedProxyBeanRegistrationAotProcessor implements BeanRegistrationAotProc
|
||||
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanType = registeredBean.getBeanType().toClass();
|
||||
if (beanType.equals(ScopedProxyFactoryBean.class)) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
if (beanClass.equals(ScopedProxyFactoryBean.class)) {
|
||||
String targetBeanName = getTargetBeanName(registeredBean.getMergedBeanDefinition());
|
||||
BeanDefinition targetBeanDefinition =
|
||||
getTargetBeanDefinition(registeredBean.getBeanFactory(), targetBeanName);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.support;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -45,7 +46,7 @@ public class RootClassFilter implements ClassFilter, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
return (this == obj || (obj instanceof RootClassFilter that &&
|
||||
this.clazz.equals(that.clazz)));
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -183,7 +183,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -169,7 +170,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -181,7 +181,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the call should bock when the pool is exhausted.
|
||||
* Set whether the call should block when the pool is exhausted.
|
||||
*/
|
||||
public void setBlockWhenExhausted(boolean blockWhenExhausted) {
|
||||
this.blockWhenExhausted = blockWhenExhausted;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -131,7 +131,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.target;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -100,7 +101,7 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
|
||||
* objects are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
return (this == obj || (obj instanceof HotSwappableTargetSource that &&
|
||||
this.target.equals(that.target)));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -65,7 +65,6 @@ public class LazyInitTargetSource extends AbstractBeanFactoryBasedTargetSource {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public synchronized Object getTarget() throws BeansException {
|
||||
if (this.target == null) {
|
||||
this.target = getBeanFactory().getBean(getTargetBeanName());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.target;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -82,7 +83,7 @@ public class SingletonTargetSource implements TargetSource, Serializable {
|
||||
* targets or the targets are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Support for dynamic, refreshable {@link org.springframework.aop.TargetSource}
|
||||
* implementations for use with Spring AOP.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.aop.target.dynamic;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Various {@link org.springframework.aop.TargetSource} implementations for use
|
||||
* with Spring AOP.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.aop.target;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -70,7 +70,7 @@ public class MethodInvocationProceedingJoinPointTests {
|
||||
AtomicInteger depth = new AtomicInteger();
|
||||
pf.addAdvice((MethodBeforeAdvice) (method, args, target) -> {
|
||||
JoinPoint jp = AbstractAspectJAdvice.currentJoinPoint();
|
||||
assertThat(jp.toString().contains(method.getName())).as("Method named in toString").isTrue();
|
||||
assertThat(jp.toString()).as("Method named in toString").contains(method.getName());
|
||||
// Ensure that these don't cause problems
|
||||
jp.toShortString();
|
||||
jp.toLongString();
|
||||
|
||||
+8
-8
@@ -319,10 +319,10 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
@Test
|
||||
void introductionOnTargetNotImplementingInterface() {
|
||||
NotLockable notLockableTarget = new NotLockable();
|
||||
assertThat(notLockableTarget instanceof Lockable).isFalse();
|
||||
assertThat(notLockableTarget).isNotInstanceOf(Lockable.class);
|
||||
NotLockable notLockable1 = createProxy(notLockableTarget, NotLockable.class,
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
assertThat(notLockable1 instanceof Lockable).isTrue();
|
||||
assertThat(notLockable1).isInstanceOf(Lockable.class);
|
||||
Lockable lockable = (Lockable) notLockable1;
|
||||
assertThat(lockable.locked()).isFalse();
|
||||
lockable.lock();
|
||||
@@ -331,7 +331,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
NotLockable notLockable2Target = new NotLockable();
|
||||
NotLockable notLockable2 = createProxy(notLockable2Target, NotLockable.class,
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
|
||||
assertThat(notLockable2 instanceof Lockable).isTrue();
|
||||
assertThat(notLockable2).isInstanceOf(Lockable.class);
|
||||
Lockable lockable2 = (Lockable) notLockable2;
|
||||
assertThat(lockable2.locked()).isFalse();
|
||||
notLockable2.setIntValue(1);
|
||||
@@ -345,7 +345,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
assertThat(AopUtils.findAdvisorsThatCanApply(
|
||||
getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
CannotBeUnlocked.class).isEmpty()).isTrue();
|
||||
CannotBeUnlocked.class)).isEmpty();
|
||||
assertThat(AopUtils.findAdvisorsThatCanApply(getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
|
||||
}
|
||||
@@ -373,7 +373,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
AopUtils.findAdvisorsThatCanApply(
|
||||
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
List.class));
|
||||
assertThat(proxy instanceof Lockable).as("Type pattern must have excluded mixin").isFalse();
|
||||
assertThat(proxy).as("Type pattern must have excluded mixin").isNotInstanceOf(Lockable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -430,7 +430,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
UnsupportedOperationException expectedException = new UnsupportedOperationException();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
assertThat(advisors.size()).as("One advice method was found").isEqualTo(1);
|
||||
assertThat(advisors).as("One advice method was found").hasSize(1);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(itb::getAge);
|
||||
}
|
||||
@@ -443,7 +443,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
RemoteException expectedException = new RemoteException();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
|
||||
assertThat(advisors.size()).as("One advice method was found").isEqualTo(1);
|
||||
assertThat(advisors).as("One advice method was found").hasSize(1);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
assertThatExceptionOfType(UndeclaredThrowableException.class)
|
||||
.isThrownBy(itb::getAge)
|
||||
@@ -456,7 +456,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect();
|
||||
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
|
||||
aspectInstanceFactory(twoAdviceAspect, "someBean"));
|
||||
assertThat(advisors.size()).as("Two advice methods found").isEqualTo(2);
|
||||
assertThat(advisors).as("Two advice methods found").hasSize(2);
|
||||
ITestBean itb = createProxy(target, ITestBean.class, advisors);
|
||||
itb.setName("");
|
||||
assertThat(itb.getAge()).isEqualTo(0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.springframework.aop.framework;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
@@ -194,11 +197,11 @@ public class ProxyFactoryTests {
|
||||
TestBeanSubclass raw = new TestBeanSubclass();
|
||||
ProxyFactory factory = new ProxyFactory(raw);
|
||||
//System.out.println("Proxied interfaces are " + StringUtils.arrayToDelimitedString(factory.getProxiedInterfaces(), ","));
|
||||
assertThat(factory.getProxiedInterfaces().length).as("Found correct number of interfaces").isEqualTo(5);
|
||||
assertThat(factory.getProxiedInterfaces()).as("Found correct number of interfaces").hasSize(5);
|
||||
ITestBean tb = (ITestBean) factory.getProxy();
|
||||
assertThat(tb).as("Picked up secondary interface").isInstanceOf(IOther.class);
|
||||
raw.setAge(25);
|
||||
assertThat(tb.getAge() == raw.getAge()).isTrue();
|
||||
assertThat(tb.getAge()).isEqualTo(raw.getAge());
|
||||
|
||||
long t = 555555L;
|
||||
TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor(t);
|
||||
@@ -208,10 +211,10 @@ public class ProxyFactoryTests {
|
||||
factory.addAdvisor(0, new DefaultIntroductionAdvisor(ti, TimeStamped.class));
|
||||
|
||||
Class<?>[] newProxiedInterfaces = factory.getProxiedInterfaces();
|
||||
assertThat(newProxiedInterfaces.length).as("Advisor proxies one more interface after introduction").isEqualTo(oldProxiedInterfaces.length + 1);
|
||||
assertThat(newProxiedInterfaces).as("Advisor proxies one more interface after introduction").hasSize(oldProxiedInterfaces.length + 1);
|
||||
|
||||
TimeStamped ts = (TimeStamped) factory.getProxy();
|
||||
assertThat(ts.getTimeStamp() == t).isTrue();
|
||||
assertThat(ts.getTimeStamp()).isEqualTo(t);
|
||||
// Shouldn't fail;
|
||||
((IOther) ts).absquatulate();
|
||||
}
|
||||
@@ -231,13 +234,13 @@ public class ProxyFactoryTests {
|
||||
factory.addAdvice(0, di);
|
||||
assertThat(factory.getProxy()).isInstanceOf(ITestBean.class);
|
||||
assertThat(factory.adviceIncluded(di)).isTrue();
|
||||
assertThat(!factory.adviceIncluded(diUnused)).isTrue();
|
||||
assertThat(factory.countAdvicesOfType(NopInterceptor.class) == 1).isTrue();
|
||||
assertThat(factory.countAdvicesOfType(MyInterceptor.class) == 0).isTrue();
|
||||
assertThat(factory.adviceIncluded(diUnused)).isFalse();
|
||||
assertThat(factory.countAdvicesOfType(NopInterceptor.class)).isEqualTo(1);
|
||||
assertThat(factory.countAdvicesOfType(MyInterceptor.class)).isEqualTo(0);
|
||||
|
||||
factory.addAdvice(0, diUnused);
|
||||
assertThat(factory.adviceIncluded(diUnused)).isTrue();
|
||||
assertThat(factory.countAdvicesOfType(NopInterceptor.class) == 2).isTrue();
|
||||
assertThat(factory.countAdvicesOfType(NopInterceptor.class)).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -257,7 +260,8 @@ public class ProxyFactoryTests {
|
||||
public void testCanAddAndRemoveAspectInterfacesOnSingleton() {
|
||||
ProxyFactory config = new ProxyFactory(new TestBean());
|
||||
|
||||
assertThat(config.getProxy() instanceof TimeStamped).as("Shouldn't implement TimeStamped before manipulation").isFalse();
|
||||
assertThat(config.getProxy()).as("Shouldn't implement TimeStamped before manipulation")
|
||||
.isNotInstanceOf(TimeStamped.class);
|
||||
|
||||
long time = 666L;
|
||||
TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor();
|
||||
@@ -267,26 +271,26 @@ public class ProxyFactoryTests {
|
||||
int oldCount = config.getAdvisors().length;
|
||||
config.addAdvisor(0, new DefaultIntroductionAdvisor(ti, TimeStamped.class));
|
||||
|
||||
assertThat(config.getAdvisors().length == oldCount + 1).isTrue();
|
||||
assertThat(config.getAdvisors()).hasSize(oldCount + 1);
|
||||
|
||||
TimeStamped ts = (TimeStamped) config.getProxy();
|
||||
assertThat(ts.getTimeStamp() == time).isTrue();
|
||||
assertThat(ts.getTimeStamp()).isEqualTo(time);
|
||||
|
||||
// Can remove
|
||||
config.removeAdvice(ti);
|
||||
|
||||
assertThat(config.getAdvisors().length == oldCount).isTrue();
|
||||
assertThat(config.getAdvisors()).hasSize(oldCount);
|
||||
|
||||
assertThatRuntimeException()
|
||||
.as("Existing object won't implement this interface any more")
|
||||
.isThrownBy(ts::getTimeStamp); // Existing reference will fail
|
||||
|
||||
assertThat(config.getProxy() instanceof TimeStamped).as("Should no longer implement TimeStamped").isFalse();
|
||||
assertThat(config.getProxy()).as("Should no longer implement TimeStamped").isNotInstanceOf(TimeStamped.class);
|
||||
|
||||
// Now check non-effect of removing interceptor that isn't there
|
||||
config.removeAdvice(new DebugInterceptor());
|
||||
|
||||
assertThat(config.getAdvisors().length == oldCount).isTrue();
|
||||
assertThat(config.getAdvisors()).hasSize(oldCount);
|
||||
|
||||
ITestBean it = (ITestBean) ts;
|
||||
DebugInterceptor debugInterceptor = new DebugInterceptor();
|
||||
@@ -296,7 +300,7 @@ public class ProxyFactoryTests {
|
||||
config.removeAdvice(debugInterceptor);
|
||||
it.getSpouse();
|
||||
// not invoked again
|
||||
assertThat(debugInterceptor.getCount() == 1).isTrue();
|
||||
assertThat(debugInterceptor.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -305,13 +309,13 @@ public class ProxyFactoryTests {
|
||||
pf.setTargetClass(ITestBean.class);
|
||||
Object proxy = pf.getProxy();
|
||||
assertThat(AopUtils.isJdkDynamicProxy(proxy)).as("Proxy is a JDK proxy").isTrue();
|
||||
assertThat(proxy instanceof ITestBean).isTrue();
|
||||
assertThat(proxy).isInstanceOf(ITestBean.class);
|
||||
assertThat(AopProxyUtils.ultimateTargetClass(proxy)).isEqualTo(ITestBean.class);
|
||||
|
||||
ProxyFactory pf2 = new ProxyFactory(proxy);
|
||||
Object proxy2 = pf2.getProxy();
|
||||
assertThat(AopUtils.isJdkDynamicProxy(proxy2)).as("Proxy is a JDK proxy").isTrue();
|
||||
assertThat(proxy2 instanceof ITestBean).isTrue();
|
||||
assertThat(proxy2).isInstanceOf(ITestBean.class);
|
||||
assertThat(AopProxyUtils.ultimateTargetClass(proxy2)).isEqualTo(ITestBean.class);
|
||||
}
|
||||
|
||||
@@ -321,14 +325,14 @@ public class ProxyFactoryTests {
|
||||
pf.setTargetClass(TestBean.class);
|
||||
Object proxy = pf.getProxy();
|
||||
assertThat(AopUtils.isCglibProxy(proxy)).as("Proxy is a CGLIB proxy").isTrue();
|
||||
assertThat(proxy instanceof TestBean).isTrue();
|
||||
assertThat(proxy).isInstanceOf(TestBean.class);
|
||||
assertThat(AopProxyUtils.ultimateTargetClass(proxy)).isEqualTo(TestBean.class);
|
||||
|
||||
ProxyFactory pf2 = new ProxyFactory(proxy);
|
||||
pf2.setProxyTargetClass(true);
|
||||
Object proxy2 = pf2.getProxy();
|
||||
assertThat(AopUtils.isCglibProxy(proxy2)).as("Proxy is a CGLIB proxy").isTrue();
|
||||
assertThat(proxy2 instanceof TestBean).isTrue();
|
||||
assertThat(proxy2).isInstanceOf(TestBean.class);
|
||||
assertThat(AopProxyUtils.ultimateTargetClass(proxy2)).isEqualTo(TestBean.class);
|
||||
}
|
||||
|
||||
@@ -338,8 +342,8 @@ public class ProxyFactoryTests {
|
||||
JFrame frame = new JFrame();
|
||||
ProxyFactory proxyFactory = new ProxyFactory(frame);
|
||||
Object proxy = proxyFactory.getProxy();
|
||||
assertThat(proxy instanceof RootPaneContainer).isTrue();
|
||||
assertThat(proxy instanceof Accessible).isTrue();
|
||||
assertThat(proxy).isInstanceOf(RootPaneContainer.class);
|
||||
assertThat(proxy).isInstanceOf(Accessible.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -380,6 +384,40 @@ public class ProxyFactoryTests {
|
||||
assertThat(proxy.getName()).isEqualTo("tb");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharSequenceProxy() {
|
||||
CharSequence target = "test";
|
||||
ProxyFactory pf = new ProxyFactory(target);
|
||||
ClassLoader cl = target.getClass().getClassLoader();
|
||||
assertThat(((CharSequence) pf.getProxy(cl)).toString()).isEqualTo(target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateProxy() {
|
||||
Date target = new Date();
|
||||
ProxyFactory pf = new ProxyFactory(target);
|
||||
pf.setProxyTargetClass(true);
|
||||
ClassLoader cl = target.getClass().getClassLoader();
|
||||
assertThat(((Date) pf.getProxy(cl)).getTime()).isEqualTo(target.getTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdbcSavepointProxy() throws SQLException {
|
||||
Savepoint target = new Savepoint() {
|
||||
@Override
|
||||
public int getSavepointId() throws SQLException {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public String getSavepointName() throws SQLException {
|
||||
return "sp";
|
||||
}
|
||||
};
|
||||
ProxyFactory pf = new ProxyFactory(target);
|
||||
ClassLoader cl = Savepoint.class.getClassLoader();
|
||||
assertThat(((Savepoint) pf.getProxy(cl)).getSavepointName()).isEqualTo("sp");
|
||||
}
|
||||
|
||||
|
||||
@Order(2)
|
||||
public static class A implements Runnable {
|
||||
@@ -391,7 +429,7 @@ public class ProxyFactoryTests {
|
||||
|
||||
|
||||
@Order(1)
|
||||
public static class B implements Runnable{
|
||||
public static class B implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,7 @@ class InvocationCheckExposedInvocationTestBean extends ExposedInvocationTestBean
|
||||
|
||||
@Override
|
||||
protected void assertions(MethodInvocation invocation) {
|
||||
assertThat(invocation.getThis() == this).isTrue();
|
||||
assertThat(invocation.getThis()).isSameAs(this);
|
||||
assertThat(ITestBean.class.isAssignableFrom(invocation.getMethod().getDeclaringClass())).as("Invocation should be on ITestBean: " + invocation.getMethod()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -128,7 +128,7 @@ class ScopedProxyBeanRegistrationAotProcessorTests {
|
||||
this.beanFactory.registerBeanDefinition("test", scopedBean);
|
||||
compile((freshBeanFactory, compiled) -> {
|
||||
Object bean = freshBeanFactory.getBean("test");
|
||||
assertThat(bean).isNotNull().isInstanceOf(NumberHolder.class).isInstanceOf(AopInfrastructureBean.class);
|
||||
assertThat(bean).isInstanceOf(NumberHolder.class).isInstanceOf(AopInfrastructureBean.class);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -142,7 +142,7 @@ public class ComposablePointcutTests {
|
||||
pc1.intersection(GETTER_METHOD_MATCHER);
|
||||
|
||||
assertThat(pc1.equals(pc2)).isFalse();
|
||||
assertThat(pc1.hashCode() == pc2.hashCode()).isFalse();
|
||||
assertThat(pc1.hashCode()).isNotEqualTo(pc2.hashCode());
|
||||
|
||||
pc2.intersection(GETTER_METHOD_MATCHER);
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -97,7 +97,7 @@ public class ControlFlowPointcutTests {
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").equals(new ControlFlowPointcut(One.class))).isFalse();
|
||||
assertThat(new ControlFlowPointcut(One.class).hashCode()).isEqualTo(new ControlFlowPointcut(One.class).hashCode());
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isEqualTo(new ControlFlowPointcut(One.class, "getAge").hashCode());
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode() == new ControlFlowPointcut(One.class).hashCode()).isFalse();
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isNotEqualTo(new ControlFlowPointcut(One.class).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+14
-14
@@ -56,7 +56,7 @@ class DelegatingIntroductionInterceptorTests {
|
||||
@Test
|
||||
void testIntroductionInterceptorWithDelegation() throws Exception {
|
||||
TestBean raw = new TestBean();
|
||||
assertThat(! (raw instanceof TimeStamped)).isTrue();
|
||||
assertThat(raw).isNotInstanceOf(TimeStamped.class);
|
||||
ProxyFactory factory = new ProxyFactory(raw);
|
||||
|
||||
TimeStamped ts = mock();
|
||||
@@ -66,13 +66,13 @@ class DelegatingIntroductionInterceptorTests {
|
||||
factory.addAdvisor(0, new DefaultIntroductionAdvisor(new DelegatingIntroductionInterceptor(ts)));
|
||||
|
||||
TimeStamped tsp = (TimeStamped) factory.getProxy();
|
||||
assertThat(tsp.getTimeStamp() == timestamp).isTrue();
|
||||
assertThat(tsp.getTimeStamp()).isEqualTo(timestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntroductionInterceptorWithInterfaceHierarchy() throws Exception {
|
||||
TestBean raw = new TestBean();
|
||||
assertThat(! (raw instanceof SubTimeStamped)).isTrue();
|
||||
assertThat(raw).isNotInstanceOf(SubTimeStamped.class);
|
||||
ProxyFactory factory = new ProxyFactory(raw);
|
||||
|
||||
SubTimeStamped ts = mock();
|
||||
@@ -82,13 +82,13 @@ class DelegatingIntroductionInterceptorTests {
|
||||
factory.addAdvisor(0, new DefaultIntroductionAdvisor(new DelegatingIntroductionInterceptor(ts), SubTimeStamped.class));
|
||||
|
||||
SubTimeStamped tsp = (SubTimeStamped) factory.getProxy();
|
||||
assertThat(tsp.getTimeStamp() == timestamp).isTrue();
|
||||
assertThat(tsp.getTimeStamp()).isEqualTo(timestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntroductionInterceptorWithSuperInterface() throws Exception {
|
||||
TestBean raw = new TestBean();
|
||||
assertThat(! (raw instanceof TimeStamped)).isTrue();
|
||||
assertThat(raw).isNotInstanceOf(TimeStamped.class);
|
||||
ProxyFactory factory = new ProxyFactory(raw);
|
||||
|
||||
SubTimeStamped ts = mock();
|
||||
@@ -98,8 +98,8 @@ class DelegatingIntroductionInterceptorTests {
|
||||
factory.addAdvisor(0, new DefaultIntroductionAdvisor(new DelegatingIntroductionInterceptor(ts), TimeStamped.class));
|
||||
|
||||
TimeStamped tsp = (TimeStamped) factory.getProxy();
|
||||
assertThat(!(tsp instanceof SubTimeStamped)).isTrue();
|
||||
assertThat(tsp.getTimeStamp() == timestamp).isTrue();
|
||||
assertThat(tsp).isNotInstanceOf(SubTimeStamped.class);
|
||||
assertThat(tsp.getTimeStamp()).isEqualTo(timestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,7 +125,7 @@ class DelegatingIntroductionInterceptorTests {
|
||||
//assertTrue(Arrays.binarySearch(pf.getProxiedInterfaces(), TimeStamped.class) != -1);
|
||||
TimeStamped ts = (TimeStamped) pf.getProxy();
|
||||
|
||||
assertThat(ts.getTimeStamp() == t).isTrue();
|
||||
assertThat(ts.getTimeStamp()).isEqualTo(t);
|
||||
((ITester) ts).foo();
|
||||
|
||||
((ITestBean) ts).getAge();
|
||||
@@ -160,10 +160,10 @@ class DelegatingIntroductionInterceptorTests {
|
||||
|
||||
assertThat(ts).isInstanceOf(TimeStamped.class);
|
||||
// Shouldn't proxy framework interfaces
|
||||
assertThat(!(ts instanceof MethodInterceptor)).isTrue();
|
||||
assertThat(!(ts instanceof IntroductionInterceptor)).isTrue();
|
||||
assertThat(ts).isNotInstanceOf(MethodInterceptor.class);
|
||||
assertThat(ts).isNotInstanceOf(IntroductionInterceptor.class);
|
||||
|
||||
assertThat(ts.getTimeStamp() == t).isTrue();
|
||||
assertThat(ts.getTimeStamp()).isEqualTo(t);
|
||||
((ITester) ts).foo();
|
||||
((ITestBean) ts).getAge();
|
||||
|
||||
@@ -174,14 +174,14 @@ class DelegatingIntroductionInterceptorTests {
|
||||
pf = new ProxyFactory(target);
|
||||
pf.addAdvisor(0, new DefaultIntroductionAdvisor(ii));
|
||||
Object o = pf.getProxy();
|
||||
assertThat(!(o instanceof TimeStamped)).isTrue();
|
||||
assertThat(o).isNotInstanceOf(TimeStamped.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test
|
||||
void testIntroductionInterceptorDoesntReplaceToString() throws Exception {
|
||||
TestBean raw = new TestBean();
|
||||
assertThat(! (raw instanceof TimeStamped)).isTrue();
|
||||
assertThat(raw).isNotInstanceOf(TimeStamped.class);
|
||||
ProxyFactory factory = new ProxyFactory(raw);
|
||||
|
||||
TimeStamped ts = new SerializableTimeStamped(0);
|
||||
@@ -266,7 +266,7 @@ class DelegatingIntroductionInterceptorTests {
|
||||
|
||||
TimeStamped ts = (TimeStamped) pf.getProxy();
|
||||
// From introduction interceptor, not target
|
||||
assertThat(ts.getTimeStamp() == t).isTrue();
|
||||
assertThat(ts.getTimeStamp()).isEqualTo(t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -129,7 +129,7 @@ public class NameMatchMethodPointcutTests {
|
||||
|
||||
pc1.setMappedName(foo);
|
||||
assertThat(pc1.equals(pc2)).isFalse();
|
||||
assertThat(pc1.hashCode() != pc2.hashCode()).isTrue();
|
||||
assertThat(pc1.hashCode()).isNotEqualTo(pc2.hashCode());
|
||||
|
||||
pc2.setMappedName(foo);
|
||||
assertThat(pc2).isEqualTo(pc1);
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,8 @@ import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Abstract superclass for counting advices etc.
|
||||
*
|
||||
@@ -59,7 +61,7 @@ public class MethodCounter implements Serializable {
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (other != null && other.getClass() == this.getClass());
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,8 @@ package org.springframework.aop.testfixture.interceptor;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Trivial interceptor that can be introduced in a chain to display it.
|
||||
*
|
||||
@@ -45,14 +47,14 @@ public class NopInterceptor implements MethodInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof NopInterceptor)) {
|
||||
return false;
|
||||
}
|
||||
if (this == other) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
return this.count == ((NopInterceptor) other).count;
|
||||
if (!(obj instanceof NopInterceptor that)) {
|
||||
return false;
|
||||
}
|
||||
return this.count == that.count;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* Support for an HTTP service proxy created from an interface declaration.
|
||||
* AspectJ-based dependency injection support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.web.reactive.service;
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
/**
|
||||
* Utility to trick the compiler to throw a valid checked
|
||||
* exceptions within the interceptor.
|
||||
* Utility to trick the compiler to throw valid checked exceptions masked as
|
||||
* runtime exceptions within the interceptor.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@@ -36,4 +36,5 @@ final class AnyThrow {
|
||||
private static <E extends Throwable> void throwAny(Throwable e) throws E {
|
||||
throw (E) e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* AspectJ-based caching support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* AspectJ-based dependency injection support driven by the
|
||||
* {@link org.springframework.beans.factory.annotation.Configurable @Configurable}
|
||||
* annotation.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.context.annotation.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* AspectJ-based scheduling support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* AspectJ-based transaction management support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -543,7 +543,7 @@ public abstract class AbstractCacheAnnotationTests {
|
||||
Object r1 = service.multiConditionalCacheAndEvict(key);
|
||||
Object r3 = service.multiConditionalCacheAndEvict(key);
|
||||
|
||||
assertThat(!r1.equals(r3)).isTrue();
|
||||
assertThat(r1.equals(r3)).isFalse();
|
||||
assertThat(primary.get(key)).isNull();
|
||||
|
||||
Object key2 = 3;
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -92,7 +92,7 @@ public class AspectJEnableCachingIsolatedTests {
|
||||
load(MultiCacheManagerConfig.class);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getMessage().contains("bean of type CacheManager")).isTrue();
|
||||
assertThat(ex.getMessage()).contains("bean of type CacheManager");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class AspectJEnableCachingIsolatedTests {
|
||||
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
|
||||
assertThat(ex.getMessage()).contains("implementations of CachingConfigurer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class AspectJEnableCachingIsolatedTests {
|
||||
load(EmptyConfig.class);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getMessage().contains("no bean of type CacheManager")).isTrue();
|
||||
assertThat(ex.getMessage()).contains("no bean of type CacheManager");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -45,16 +46,11 @@ public class TestEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof TestEntity) {
|
||||
return ObjectUtils.nullSafeEquals(this.id, ((TestEntity) obj).id);
|
||||
}
|
||||
return false;
|
||||
return (obj instanceof TestEntity that && ObjectUtils.nullSafeEquals(this.id, that.id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.time.temporal.Temporal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -791,11 +792,11 @@ public abstract class BeanUtils {
|
||||
actualEditable = editable;
|
||||
}
|
||||
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
|
||||
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
|
||||
Set<String> ignoredProps = (ignoreProperties != null ? new HashSet<>(Arrays.asList(ignoreProperties)) : null);
|
||||
|
||||
for (PropertyDescriptor targetPd : targetPds) {
|
||||
Method writeMethod = targetPd.getWriteMethod();
|
||||
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
|
||||
if (writeMethod != null && (ignoredProps == null || !ignoredProps.contains(targetPd.getName()))) {
|
||||
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
||||
if (sourcePd != null) {
|
||||
Method readMethod = sourcePd.getReadMethod();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -88,8 +88,9 @@ abstract class PropertyDescriptorUtils {
|
||||
BasicPropertyDescriptor pd = pdMap.get(propertyName);
|
||||
if (pd != null) {
|
||||
if (setter) {
|
||||
if (pd.getWriteMethod() == null ||
|
||||
pd.getWriteMethod().getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
Method writeMethod = pd.getWriteMethod();
|
||||
if (writeMethod == null ||
|
||||
writeMethod.getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
pd.setWriteMethod(method);
|
||||
}
|
||||
else {
|
||||
@@ -97,8 +98,9 @@ abstract class PropertyDescriptorUtils {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pd.getReadMethod() == null ||
|
||||
(pd.getReadMethod().getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod == null ||
|
||||
(readMethod.getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
|
||||
pd.setReadMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -280,6 +280,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
String beanName = registeredBean.getBeanName();
|
||||
@@ -323,10 +324,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
checkLookupMethods(beanClass, beanName);
|
||||
|
||||
// Pick up subclass with fresh lookup method override from above
|
||||
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacbf) {
|
||||
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacBeanFactory) {
|
||||
RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
|
||||
if (mbd.getFactoryMethodName() == null && mbd.hasBeanClass()) {
|
||||
return aacbf.getInstantiationStrategy().getActualBeanClass(mbd, beanName, this.beanFactory);
|
||||
return aacBeanFactory.getInstantiationStrategy().getActualBeanClass(mbd, beanName, aacBeanFactory);
|
||||
}
|
||||
}
|
||||
return beanClass;
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -157,6 +157,7 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
|
||||
beanDefinition.resolveDestroyMethodIfNecessary();
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,7 @@ import org.springframework.util.ClassUtils;
|
||||
class JakartaAnnotationsRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
if (ClassUtils.isPresent("jakarta.inject.Inject", classLoader)) {
|
||||
Stream.of("jakarta.inject.Inject", "jakarta.inject.Qualifier").forEach(annotationType ->
|
||||
hints.reflection().registerType(ClassUtils.resolveClassName(annotationType, classLoader)));
|
||||
|
||||
+4
-2
@@ -25,6 +25,7 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
@@ -240,10 +241,11 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
}
|
||||
}
|
||||
if (targetAnnotation == null) {
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
// Look for matching annotation on the target class
|
||||
if (getBeanFactory() != null) {
|
||||
if (beanFactory != null) {
|
||||
try {
|
||||
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
|
||||
Class<?> beanType = beanFactory.getType(bdHolder.getBeanName());
|
||||
if (beanType != null) {
|
||||
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
|
||||
}
|
||||
|
||||
+3
-3
@@ -138,7 +138,7 @@ class BeanDefinitionMethodGenerator {
|
||||
ClassName topLevelClassName = target.topLevelClassName();
|
||||
GeneratedClass generatedClass = generationContext.getGeneratedClasses()
|
||||
.getOrAddForFeatureComponent("BeanDefinitions", topLevelClassName, type -> {
|
||||
type.addJavadoc("Bean definitions for {@link $T}", topLevelClassName);
|
||||
type.addJavadoc("Bean definitions for {@link $T}.", topLevelClassName);
|
||||
type.addModifiers(Modifier.PUBLIC);
|
||||
});
|
||||
|
||||
@@ -159,7 +159,7 @@ class BeanDefinitionMethodGenerator {
|
||||
|
||||
private static GeneratedClass createInnerClass(GeneratedClass generatedClass, String name, ClassName target) {
|
||||
return generatedClass.getOrAdd(name, type -> {
|
||||
type.addJavadoc("Bean definitions for {@link $T}", target);
|
||||
type.addJavadoc("Bean definitions for {@link $T}.", target);
|
||||
type.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
});
|
||||
}
|
||||
@@ -186,7 +186,7 @@ class BeanDefinitionMethodGenerator {
|
||||
this.aotContributions.forEach(aotContribution -> aotContribution.applyTo(generationContext, codeGenerator));
|
||||
|
||||
return generatedMethods.add("getBeanDefinition", method -> {
|
||||
method.addJavadoc("Get the $L definition for '$L'",
|
||||
method.addJavadoc("Get the $L definition for '$L'.",
|
||||
(!this.registeredBean.isInnerBean()) ? "bean" : "inner-bean",
|
||||
getName());
|
||||
method.addModifiers(modifier, Modifier.STATIC);
|
||||
|
||||
+38
-57
@@ -27,9 +27,9 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.InjectionPoint;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
@@ -97,11 +97,13 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
private BeanInstanceSupplier(ExecutableLookup lookup,
|
||||
@Nullable ThrowingBiFunction<RegisteredBean, AutowiredArguments, T> generator,
|
||||
@Nullable String[] shortcuts) {
|
||||
|
||||
this.lookup = lookup;
|
||||
this.generator = generator;
|
||||
this.shortcuts = shortcuts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link BeanInstanceSupplier} that resolves
|
||||
* arguments for the specified bean constructor.
|
||||
@@ -109,9 +111,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* @param parameterTypes the constructor parameter types
|
||||
* @return a new {@link BeanInstanceSupplier} instance
|
||||
*/
|
||||
public static <T> BeanInstanceSupplier<T> forConstructor(
|
||||
Class<?>... parameterTypes) {
|
||||
|
||||
public static <T> BeanInstanceSupplier<T> forConstructor(Class<?>... parameterTypes) {
|
||||
Assert.notNull(parameterTypes, "'parameterTypes' must not be null");
|
||||
Assert.noNullElements(parameterTypes, "'parameterTypes' must not contain null elements");
|
||||
return new BeanInstanceSupplier<>(new ConstructorLookup(parameterTypes), null, null);
|
||||
@@ -149,11 +149,11 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* @param generator a {@link ThrowingBiFunction} that uses the
|
||||
* {@link RegisteredBean} and resolved {@link AutowiredArguments} to
|
||||
* instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(
|
||||
ThrowingBiFunction<RegisteredBean, AutowiredArguments, T> generator) {
|
||||
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
return new BeanInstanceSupplier<>(this.lookup, generator, this.shortcuts);
|
||||
}
|
||||
@@ -163,11 +163,9 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
* {@code generator} function to instantiate the underlying bean.
|
||||
* @param generator a {@link ThrowingFunction} that uses the
|
||||
* {@link RegisteredBean} to instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(
|
||||
ThrowingFunction<RegisteredBean, T> generator) {
|
||||
public BeanInstanceSupplier<T> withGenerator(ThrowingFunction<RegisteredBean, T> generator) {
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
return new BeanInstanceSupplier<>(this.lookup,
|
||||
(registeredBean, args) -> generator.apply(registeredBean), this.shortcuts);
|
||||
@@ -176,10 +174,8 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
/**
|
||||
* Return a new {@link BeanInstanceSupplier} instance that uses the specified
|
||||
* {@code generator} supplier to instantiate the underlying bean.
|
||||
* @param generator a {@link ThrowingSupplier} to instantiate the underlying
|
||||
* bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified
|
||||
* generator
|
||||
* @param generator a {@link ThrowingSupplier} to instantiate the underlying bean
|
||||
* @return a new {@link BeanInstanceSupplier} instance with the specified generator
|
||||
*/
|
||||
public BeanInstanceSupplier<T> withGenerator(ThrowingSupplier<T> generator) {
|
||||
Assert.notNull(generator, "'generator' must not be null");
|
||||
@@ -282,8 +278,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
if (executable instanceof Method method) {
|
||||
return new MethodParameter(method, index);
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unsupported executable " + executable.getClass().getName());
|
||||
throw new IllegalStateException("Unsupported executable: " + executable.getClass().getName());
|
||||
}
|
||||
|
||||
private ConstructorArgumentValues resolveArgumentValues(
|
||||
@@ -303,9 +298,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private ValueHolder resolveArgumentValue(BeanDefinitionValueResolver resolver,
|
||||
ValueHolder valueHolder) {
|
||||
|
||||
private ValueHolder resolveArgumentValue(BeanDefinitionValueResolver resolver, ValueHolder valueHolder) {
|
||||
if (valueHolder.isConverted()) {
|
||||
return valueHolder;
|
||||
}
|
||||
@@ -331,8 +324,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
}
|
||||
try {
|
||||
try {
|
||||
return beanFactory.resolveDependency(dependencyDescriptor, beanName,
|
||||
autowiredBeans, typeConverter);
|
||||
return beanFactory.resolveDependency(dependencyDescriptor, beanName, autowiredBeans, typeConverter);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
if (parameterType.isArray()) {
|
||||
@@ -348,47 +340,45 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
}
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new UnsatisfiedDependencyException(null, beanName,
|
||||
new InjectionPoint(parameter), ex);
|
||||
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(parameter), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T instantiate(ConfigurableBeanFactory beanFactory, Executable executable,
|
||||
Object[] arguments) {
|
||||
|
||||
try {
|
||||
if (executable instanceof Constructor<?> constructor) {
|
||||
return (T) instantiate(constructor, arguments);
|
||||
private T instantiate(ConfigurableBeanFactory beanFactory, Executable executable, Object[] args) {
|
||||
if (executable instanceof Constructor<?> constructor) {
|
||||
try {
|
||||
return (T) instantiate(constructor, args);
|
||||
}
|
||||
if (executable instanceof Method method) {
|
||||
return (T) instantiate(beanFactory, method, arguments);
|
||||
catch (Exception ex) {
|
||||
throw new BeanInstantiationException(constructor, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanCreationException(
|
||||
"Unable to instantiate bean using " + executable, ex);
|
||||
if (executable instanceof Method method) {
|
||||
try {
|
||||
return (T) instantiate(beanFactory, method, args);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanInstantiationException(method, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unsupported executable " + executable.getClass().getName());
|
||||
throw new IllegalStateException("Unsupported executable " + executable.getClass().getName());
|
||||
}
|
||||
|
||||
private Object instantiate(Constructor<?> constructor, Object[] arguments) throws Exception {
|
||||
private Object instantiate(Constructor<?> constructor, Object[] args) throws Exception {
|
||||
Class<?> declaringClass = constructor.getDeclaringClass();
|
||||
if (ClassUtils.isInnerClass(declaringClass)) {
|
||||
Object enclosingInstance = createInstance(declaringClass.getEnclosingClass());
|
||||
arguments = ObjectUtils.addObjectToArray(arguments, enclosingInstance, 0);
|
||||
args = ObjectUtils.addObjectToArray(args, enclosingInstance, 0);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(constructor);
|
||||
return constructor.newInstance(arguments);
|
||||
return constructor.newInstance(args);
|
||||
}
|
||||
|
||||
private Object instantiate(ConfigurableBeanFactory beanFactory, Method method,
|
||||
Object[] arguments) {
|
||||
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
private Object instantiate(ConfigurableBeanFactory beanFactory, Method method, Object[] args) throws Exception {
|
||||
Object target = getFactoryMethodTarget(beanFactory, method);
|
||||
return ReflectionUtils.invokeMethod(method, target, arguments);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -416,13 +406,13 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
return Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs lookup of the {@link Executable}.
|
||||
*/
|
||||
static abstract class ExecutableLookup {
|
||||
|
||||
abstract Executable get(RegisteredBean registeredBean);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -433,12 +423,10 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
|
||||
ConstructorLookup(Class<?>[] parameterTypes) {
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Executable get(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
@@ -456,10 +444,8 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Constructor with parameter types [%s]".formatted(
|
||||
toCommaSeparatedNames(this.parameterTypes));
|
||||
return "Constructor with parameter types [%s]".formatted(toCommaSeparatedNames(this.parameterTypes));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -474,23 +460,19 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
|
||||
FactoryMethodLookup(Class<?> declaringClass, String methodName,
|
||||
Class<?>[] parameterTypes) {
|
||||
FactoryMethodLookup(Class<?> declaringClass, String methodName, Class<?>[] parameterTypes) {
|
||||
this.declaringClass = declaringClass;
|
||||
this.methodName = methodName;
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Executable get(RegisteredBean registeredBean) {
|
||||
return get();
|
||||
}
|
||||
|
||||
Method get() {
|
||||
Method method = ReflectionUtils.findMethod(this.declaringClass,
|
||||
this.methodName, this.parameterTypes);
|
||||
Method method = ReflectionUtils.findMethod(this.declaringClass, this.methodName, this.parameterTypes);
|
||||
Assert.notNull(method, () -> "%s cannot be found".formatted(this));
|
||||
return method;
|
||||
}
|
||||
@@ -501,7 +483,6 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||
this.methodName, toCommaSeparatedNames(this.parameterTypes),
|
||||
this.declaringClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.aot;
|
||||
|
||||
/**
|
||||
* Record class holding key information for beans registered in a bean factory.
|
||||
*
|
||||
* @param beanName the name of the registered bean
|
||||
* @param beanClass the type of the registered bean
|
||||
* @author Brian Clozel
|
||||
* @since 6.0.8
|
||||
*/
|
||||
record BeanRegistrationKey(String beanName, Class<?> beanClass) {
|
||||
}
|
||||
+22
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,8 @@ import org.springframework.aot.generate.GeneratedMethods;
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.aot.generate.MethodReference;
|
||||
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.javapoet.ClassName;
|
||||
import org.springframework.javapoet.CodeBlock;
|
||||
@@ -38,6 +40,7 @@ import org.springframework.javapoet.MethodSpec;
|
||||
* @author Phillip Webb
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
* @see BeanRegistrationsAotProcessor
|
||||
*/
|
||||
@@ -46,9 +49,10 @@ class BeanRegistrationsAotContribution
|
||||
|
||||
private static final String BEAN_FACTORY_PARAMETER_NAME = "beanFactory";
|
||||
|
||||
private final Map<String, Registration> registrations;
|
||||
private final Map<BeanRegistrationKey, Registration> registrations;
|
||||
|
||||
BeanRegistrationsAotContribution(Map<String, Registration> registrations) {
|
||||
|
||||
BeanRegistrationsAotContribution(Map<BeanRegistrationKey, Registration> registrations) {
|
||||
this.registrations = registrations;
|
||||
}
|
||||
|
||||
@@ -69,26 +73,23 @@ class BeanRegistrationsAotContribution
|
||||
GeneratedMethod generatedAliasesMethod = codeGenerator.getMethods().add("registerAliases",
|
||||
this::generateRegisterAliasesMethod);
|
||||
beanFactoryInitializationCode.addInitializer(generatedAliasesMethod.toMethodReference());
|
||||
generateRegisterHints(generationContext.getRuntimeHints(), this.registrations);
|
||||
}
|
||||
|
||||
private void generateRegisterBeanDefinitionsMethod(MethodSpec.Builder method,
|
||||
GenerationContext generationContext,
|
||||
BeanRegistrationsCode beanRegistrationsCode) {
|
||||
GenerationContext generationContext, BeanRegistrationsCode beanRegistrationsCode) {
|
||||
|
||||
method.addJavadoc("Register the bean definitions.");
|
||||
method.addModifiers(Modifier.PUBLIC);
|
||||
method.addParameter(DefaultListableBeanFactory.class,
|
||||
BEAN_FACTORY_PARAMETER_NAME);
|
||||
method.addParameter(DefaultListableBeanFactory.class, BEAN_FACTORY_PARAMETER_NAME);
|
||||
CodeBlock.Builder code = CodeBlock.builder();
|
||||
this.registrations.forEach((beanName, registration) -> {
|
||||
this.registrations.forEach((registeredBean, registration) -> {
|
||||
MethodReference beanDefinitionMethod = registration.methodGenerator
|
||||
.generateBeanDefinitionMethod(generationContext,
|
||||
beanRegistrationsCode);
|
||||
.generateBeanDefinitionMethod(generationContext, beanRegistrationsCode);
|
||||
CodeBlock methodInvocation = beanDefinitionMethod.toInvokeCodeBlock(
|
||||
ArgumentCodeGenerator.none(), beanRegistrationsCode.getClassName());
|
||||
code.addStatement("$L.registerBeanDefinition($S, $L)",
|
||||
BEAN_FACTORY_PARAMETER_NAME, beanName,
|
||||
methodInvocation);
|
||||
BEAN_FACTORY_PARAMETER_NAME, registeredBean.beanName(), methodInvocation);
|
||||
});
|
||||
method.addCode(code.build());
|
||||
}
|
||||
@@ -96,18 +97,22 @@ class BeanRegistrationsAotContribution
|
||||
private void generateRegisterAliasesMethod(MethodSpec.Builder method) {
|
||||
method.addJavadoc("Register the aliases.");
|
||||
method.addModifiers(Modifier.PUBLIC);
|
||||
method.addParameter(DefaultListableBeanFactory.class,
|
||||
BEAN_FACTORY_PARAMETER_NAME);
|
||||
method.addParameter(DefaultListableBeanFactory.class, BEAN_FACTORY_PARAMETER_NAME);
|
||||
CodeBlock.Builder code = CodeBlock.builder();
|
||||
this.registrations.forEach((beanName, registration) -> {
|
||||
this.registrations.forEach((registeredBean, registration) -> {
|
||||
for (String alias : registration.aliases) {
|
||||
code.addStatement("$L.registerAlias($S, $S)",
|
||||
BEAN_FACTORY_PARAMETER_NAME, beanName, alias);
|
||||
code.addStatement("$L.registerAlias($S, $S)", BEAN_FACTORY_PARAMETER_NAME,
|
||||
registeredBean.beanName(), alias);
|
||||
}
|
||||
});
|
||||
method.addCode(code.build());
|
||||
}
|
||||
|
||||
private void generateRegisterHints(RuntimeHints runtimeHints, Map<BeanRegistrationKey, Registration> registrations) {
|
||||
registrations.keySet().forEach(beanRegistrationKey -> runtimeHints.reflection()
|
||||
.registerType(beanRegistrationKey.beanClass(), MemberCategory.INTROSPECT_DECLARED_METHODS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the necessary information to register a particular bean.
|
||||
* @param methodGenerator the {@link BeanDefinitionMethodGenerator} to use
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Phillip Webb
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
class BeanRegistrationsAotProcessor implements BeanFactoryInitializationAotProcessor {
|
||||
@@ -40,15 +41,15 @@ class BeanRegistrationsAotProcessor implements BeanFactoryInitializationAotProce
|
||||
public BeanRegistrationsAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
BeanDefinitionMethodGeneratorFactory beanDefinitionMethodGeneratorFactory =
|
||||
new BeanDefinitionMethodGeneratorFactory(beanFactory);
|
||||
Map<String, Registration> registrations = new LinkedHashMap<>();
|
||||
Map<BeanRegistrationKey, Registration> registrations = new LinkedHashMap<>();
|
||||
|
||||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||
RegisteredBean registeredBean = RegisteredBean.of(beanFactory, beanName);
|
||||
BeanDefinitionMethodGenerator beanDefinitionMethodGenerator =
|
||||
beanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean);
|
||||
if (beanDefinitionMethodGenerator != null) {
|
||||
registrations.put(beanName, new Registration(beanDefinitionMethodGenerator,
|
||||
beanFactory.getAliases(beanName)));
|
||||
registrations.put(new BeanRegistrationKey(beanName, registeredBean.getBeanClass()),
|
||||
new Registration(beanDefinitionMethodGenerator, beanFactory.getAliases(beanName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -188,7 +188,7 @@ public class ConstructorArgumentValues {
|
||||
* rather than matched multiple times.
|
||||
* @param value the argument value
|
||||
*/
|
||||
public void addGenericArgumentValue(Object value) {
|
||||
public void addGenericArgumentValue(@Nullable Object value) {
|
||||
this.genericArgumentValues.add(new ValueHolder(value));
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -53,6 +53,7 @@ import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.core.io.DescriptiveResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -149,8 +150,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
|
||||
private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass());
|
||||
|
||||
@Nullable
|
||||
private Binding binding;
|
||||
|
||||
@Nullable
|
||||
private GroovyBeanDefinitionWrapper currentBeanDefinition;
|
||||
|
||||
|
||||
@@ -203,6 +206,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
/**
|
||||
* Return a specified binding for Groovy variables, if any.
|
||||
*/
|
||||
@Nullable
|
||||
public Binding getBinding() {
|
||||
return this.binding;
|
||||
}
|
||||
|
||||
+28
-30
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.beans.factory.groovy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import groovy.lang.GroovyObjectSupport;
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -51,58 +53,54 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
private static final String DESTROY_METHOD = "destroyMethod";
|
||||
private static final String SINGLETON = "singleton";
|
||||
|
||||
private static final List<String> dynamicProperties = new ArrayList<>(8);
|
||||
|
||||
static {
|
||||
dynamicProperties.add(PARENT);
|
||||
dynamicProperties.add(AUTOWIRE);
|
||||
dynamicProperties.add(CONSTRUCTOR_ARGS);
|
||||
dynamicProperties.add(FACTORY_BEAN);
|
||||
dynamicProperties.add(FACTORY_METHOD);
|
||||
dynamicProperties.add(INIT_METHOD);
|
||||
dynamicProperties.add(DESTROY_METHOD);
|
||||
dynamicProperties.add(SINGLETON);
|
||||
}
|
||||
private static final Set<String> dynamicProperties = Set.of(PARENT, AUTOWIRE, CONSTRUCTOR_ARGS,
|
||||
FACTORY_BEAN, FACTORY_METHOD, INIT_METHOD, DESTROY_METHOD, SINGLETON);
|
||||
|
||||
|
||||
@Nullable
|
||||
private String beanName;
|
||||
|
||||
private Class<?> clazz;
|
||||
@Nullable
|
||||
private final Class<?> clazz;
|
||||
|
||||
private Collection<?> constructorArgs;
|
||||
@Nullable
|
||||
private final Collection<?> constructorArgs;
|
||||
|
||||
@Nullable
|
||||
private AbstractBeanDefinition definition;
|
||||
|
||||
@Nullable
|
||||
private BeanWrapper definitionWrapper;
|
||||
|
||||
@Nullable
|
||||
private String parentName;
|
||||
|
||||
|
||||
public GroovyBeanDefinitionWrapper(String beanName) {
|
||||
this.beanName = beanName;
|
||||
GroovyBeanDefinitionWrapper(String beanName) {
|
||||
this(beanName, null);
|
||||
}
|
||||
|
||||
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz) {
|
||||
this.beanName = beanName;
|
||||
this.clazz = clazz;
|
||||
GroovyBeanDefinitionWrapper(@Nullable String beanName, @Nullable Class<?> clazz) {
|
||||
this(beanName, clazz, null);
|
||||
}
|
||||
|
||||
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz, Collection<?> constructorArgs) {
|
||||
GroovyBeanDefinitionWrapper(@Nullable String beanName, Class<?> clazz, @Nullable Collection<?> constructorArgs) {
|
||||
this.beanName = beanName;
|
||||
this.clazz = clazz;
|
||||
this.constructorArgs = constructorArgs;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
public void setBeanDefinition(AbstractBeanDefinition definition) {
|
||||
void setBeanDefinition(AbstractBeanDefinition definition) {
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
public AbstractBeanDefinition getBeanDefinition() {
|
||||
AbstractBeanDefinition getBeanDefinition() {
|
||||
if (this.definition == null) {
|
||||
this.definition = createBeanDefinition();
|
||||
}
|
||||
@@ -126,19 +124,17 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
return bd;
|
||||
}
|
||||
|
||||
public void setBeanDefinitionHolder(BeanDefinitionHolder holder) {
|
||||
void setBeanDefinitionHolder(BeanDefinitionHolder holder) {
|
||||
this.definition = (AbstractBeanDefinition) holder.getBeanDefinition();
|
||||
this.beanName = holder.getBeanName();
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder getBeanDefinitionHolder() {
|
||||
BeanDefinitionHolder getBeanDefinitionHolder() {
|
||||
return new BeanDefinitionHolder(getBeanDefinition(), getBeanName());
|
||||
}
|
||||
|
||||
public void setParent(Object obj) {
|
||||
if (obj == null) {
|
||||
throw new IllegalArgumentException("Parent bean cannot be set to a null runtime bean reference!");
|
||||
}
|
||||
void setParent(Object obj) {
|
||||
Assert.notNull(obj, "Parent bean cannot be set to a null runtime bean reference.");
|
||||
if (obj instanceof String name) {
|
||||
this.parentName = name;
|
||||
}
|
||||
@@ -152,7 +148,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
getBeanDefinition().setAbstract(false);
|
||||
}
|
||||
|
||||
public GroovyBeanDefinitionWrapper addProperty(String propertyName, Object propertyValue) {
|
||||
GroovyBeanDefinitionWrapper addProperty(String propertyName, Object propertyValue) {
|
||||
if (propertyValue instanceof GroovyBeanDefinitionWrapper wrapper) {
|
||||
propertyValue = wrapper.getBeanDefinition();
|
||||
}
|
||||
@@ -163,6 +159,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
|
||||
@Override
|
||||
public Object getProperty(String property) {
|
||||
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
|
||||
if (this.definitionWrapper.isReadableProperty(property)) {
|
||||
return this.definitionWrapper.getPropertyValue(property);
|
||||
}
|
||||
@@ -179,6 +176,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
}
|
||||
else {
|
||||
AbstractBeanDefinition bd = getBeanDefinition();
|
||||
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
|
||||
if (AUTOWIRE.equals(property)) {
|
||||
if ("byName".equals(newValue)) {
|
||||
bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Used by GroovyBeanDefinitionReader to read a Spring XML namespace expression
|
||||
@@ -68,6 +69,7 @@ class GroovyDynamicElementReader extends GroovyObjectSupport {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invokeMethod(String name, Object obj) {
|
||||
Object[] args = (Object[]) obj;
|
||||
if (name.equals("doCall")) {
|
||||
@@ -88,6 +90,7 @@ class GroovyDynamicElementReader extends GroovyObjectSupport {
|
||||
String myNamespace = this.rootNamespace;
|
||||
Map<String, String> myNamespaces = this.xmlNamespaces;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
Closure<Object> callable = new Closure<>(this) {
|
||||
@Override
|
||||
public Object call(Object... arguments) {
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/**
|
||||
* Support package for Groovy-based bean definitions.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.beans.factory.groovy;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
+38
-29
@@ -61,7 +61,6 @@ import org.springframework.beans.factory.config.AutowiredPropertyMarker;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
|
||||
@@ -755,13 +754,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (candidate.getTypeParameters().length > 0) {
|
||||
try {
|
||||
// Fully resolve parameter names and argument values.
|
||||
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
String[] paramNames = null;
|
||||
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
|
||||
if (pnd != null) {
|
||||
paramNames = pnd.getParameterNames(candidate);
|
||||
if (cav.containsNamedArgument()) {
|
||||
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
|
||||
if (pnd != null) {
|
||||
paramNames = pnd.getParameterNames(candidate);
|
||||
}
|
||||
}
|
||||
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
|
||||
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
@@ -1154,7 +1155,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
|
||||
if (instanceSupplier != null) {
|
||||
return obtainFromSupplier(instanceSupplier, beanName);
|
||||
return obtainFromSupplier(instanceSupplier, beanName, mbd);
|
||||
}
|
||||
|
||||
if (mbd.getFactoryMethodName() != null) {
|
||||
@@ -1203,38 +1204,20 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param supplier the configured supplier
|
||||
* @param beanName the corresponding bean name
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @since 5.0
|
||||
* @see #getObjectForBeanInstance
|
||||
*/
|
||||
protected BeanWrapper obtainFromSupplier(Supplier<?> supplier, String beanName) {
|
||||
Object instance = obtainInstanceFromSupplier(supplier, beanName);
|
||||
if (instance == null) {
|
||||
instance = new NullBean();
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(instance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName) {
|
||||
private BeanWrapper obtainFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd) {
|
||||
String outerBean = this.currentlyCreatedBean.get();
|
||||
this.currentlyCreatedBean.set(beanName);
|
||||
Object instance;
|
||||
|
||||
try {
|
||||
if (supplier instanceof InstanceSupplier<?> instanceSupplier) {
|
||||
return instanceSupplier.get(RegisteredBean.of((ConfigurableListableBeanFactory) this, beanName));
|
||||
}
|
||||
if (supplier instanceof ThrowingSupplier<?> throwableSupplier) {
|
||||
return throwableSupplier.getWithException();
|
||||
}
|
||||
return supplier.get();
|
||||
instance = obtainInstanceFromSupplier(supplier, beanName, mbd);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (ex instanceof BeansException beansException) {
|
||||
throw beansException;
|
||||
}
|
||||
throw new BeanCreationException(beanName,
|
||||
"Instantiation of supplied bean failed", ex);
|
||||
throw new BeanCreationException(beanName, "Instantiation of supplied bean failed", ex);
|
||||
}
|
||||
finally {
|
||||
if (outerBean != null) {
|
||||
@@ -1244,6 +1227,31 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
this.currentlyCreatedBean.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance == null) {
|
||||
instance = new NullBean();
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(instance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a bean instance from the given supplier.
|
||||
* @param supplier the configured supplier
|
||||
* @param beanName the corresponding bean name
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the bean instance (possibly {@code null})
|
||||
* @since 6.0.7
|
||||
*/
|
||||
@Nullable
|
||||
protected Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd)
|
||||
throws Exception {
|
||||
|
||||
if (supplier instanceof ThrowingSupplier<?> throwingSupplier) {
|
||||
return throwingSupplier.getWithException();
|
||||
}
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1950,6 +1958,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDependencyName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
+11
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -853,10 +853,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
*/
|
||||
@Override
|
||||
public ConstructorArgumentValues getConstructorArgumentValues() {
|
||||
if (this.constructorArgumentValues == null) {
|
||||
this.constructorArgumentValues = new ConstructorArgumentValues();
|
||||
ConstructorArgumentValues cav = this.constructorArgumentValues;
|
||||
if (cav == null) {
|
||||
cav = new ConstructorArgumentValues();
|
||||
this.constructorArgumentValues = cav;
|
||||
}
|
||||
return this.constructorArgumentValues;
|
||||
return cav;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -879,10 +881,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
*/
|
||||
@Override
|
||||
public MutablePropertyValues getPropertyValues() {
|
||||
if (this.propertyValues == null) {
|
||||
this.propertyValues = new MutablePropertyValues();
|
||||
MutablePropertyValues pvs = this.propertyValues;
|
||||
if (pvs == null) {
|
||||
pvs = new MutablePropertyValues();
|
||||
this.propertyValues = pvs;
|
||||
}
|
||||
return this.propertyValues;
|
||||
return pvs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-1
@@ -294,7 +294,9 @@ class ConstructorResolver {
|
||||
}
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
|
||||
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
|
||||
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities. " +
|
||||
"You should also check the consistency of arguments when mixing indexed and named arguments, " +
|
||||
"especially in case of bean definition inheritance)");
|
||||
}
|
||||
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
|
||||
+14
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,6 +40,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.inject.Provider;
|
||||
@@ -937,6 +938,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd)
|
||||
throws Exception {
|
||||
|
||||
if (supplier instanceof InstanceSupplier<?> instanceSupplier) {
|
||||
return instanceSupplier.get(RegisteredBean.of(this, beanName, mbd));
|
||||
}
|
||||
return super.obtainInstanceFromSupplier(supplier, beanName, mbd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preInstantiateSingletons() throws BeansException {
|
||||
if (logger.isTraceEnabled()) {
|
||||
@@ -1720,7 +1732,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (beanInstance != null) {
|
||||
Integer candidatePriority = getPriority(beanInstance);
|
||||
if (candidatePriority != null) {
|
||||
if (highestPriorityBeanName != null) {
|
||||
if (highestPriority != null) {
|
||||
if (candidatePriority.equals(highestPriority)) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
|
||||
"Multiple beans found with the same priority ('" + highestPriority +
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -340,7 +340,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* (within the entire factory).
|
||||
* @param beanName the name of the bean
|
||||
*/
|
||||
public boolean isSingletonCurrentlyInCreation(String beanName) {
|
||||
public boolean isSingletonCurrentlyInCreation(@Nullable String beanName) {
|
||||
return this.singletonsCurrentlyInCreation.contains(beanName);
|
||||
}
|
||||
|
||||
|
||||
+19
-7
@@ -49,6 +49,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @author Sebastien Deleuze
|
||||
* @since 2.0
|
||||
* @see AbstractBeanFactory
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
@@ -114,7 +115,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
(bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodNames[0]));
|
||||
if (!this.invokeAutoCloseable) {
|
||||
this.destroyMethodNames = destroyMethodNames;
|
||||
Method[] destroyMethods = new Method[destroyMethodNames.length];
|
||||
List<Method> destroyMethods = new ArrayList<>(destroyMethodNames.length);
|
||||
for (int i = 0; i < destroyMethodNames.length; i++) {
|
||||
String destroyMethodName = destroyMethodNames[i];
|
||||
Method destroyMethod = determineDestroyMethod(destroyMethodName);
|
||||
@@ -137,10 +138,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass());
|
||||
destroyMethods.add(destroyMethod);
|
||||
}
|
||||
destroyMethods[i] = destroyMethod;
|
||||
}
|
||||
this.destroyMethods = destroyMethods;
|
||||
this.destroyMethods = destroyMethods.toArray(Method[]::new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +254,18 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
@Nullable
|
||||
private Method determineDestroyMethod(String name) {
|
||||
try {
|
||||
return findDestroyMethod(name);
|
||||
Class<?> beanClass = this.bean.getClass();
|
||||
Method destroyMethod = findDestroyMethod(beanClass, name);
|
||||
if (destroyMethod != null) {
|
||||
return destroyMethod;
|
||||
}
|
||||
for (Class<?> beanInterface : beanClass.getInterfaces()) {
|
||||
destroyMethod = findDestroyMethod(beanInterface, name);
|
||||
if (destroyMethod != null) {
|
||||
return destroyMethod;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanDefinitionValidationException("Could not find unique destroy method on bean with name '" +
|
||||
@@ -262,10 +274,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Method findDestroyMethod(String name) {
|
||||
private Method findDestroyMethod(Class<?> clazz, String name) {
|
||||
return (this.nonPublicAccessAllowed ?
|
||||
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), name) :
|
||||
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), name));
|
||||
BeanUtils.findMethodWithMinimalParameters(clazz, name) :
|
||||
BeanUtils.findMethodWithMinimalParameters(clazz.getMethods(), name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,6 +35,7 @@ import org.springframework.util.function.ThrowingSupplier;
|
||||
* @since 6.0
|
||||
* @param <T> the type of instance supplied by this supplier
|
||||
* @see RegisteredBean
|
||||
* @see org.springframework.beans.factory.aot.BeanInstanceSupplier
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
@@ -74,19 +75,17 @@ public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
*/
|
||||
default <V> InstanceSupplier<V> andThen(
|
||||
ThrowingBiFunction<RegisteredBean, ? super T, ? extends V> after) {
|
||||
|
||||
Assert.notNull(after, "'after' function must not be null");
|
||||
return new InstanceSupplier<>() {
|
||||
|
||||
@Override
|
||||
public V get(RegisteredBean registeredBean) throws Exception {
|
||||
return after.applyWithException(registeredBean, InstanceSupplier.this.get(registeredBean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getFactoryMethod() {
|
||||
return InstanceSupplier.this.getFactoryMethod();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,22 +114,21 @@ public interface InstanceSupplier<T> extends ThrowingSupplier<T> {
|
||||
*/
|
||||
static <T> InstanceSupplier<T> using(@Nullable Method factoryMethod, ThrowingSupplier<T> supplier) {
|
||||
Assert.notNull(supplier, "Supplier must not be null");
|
||||
if (supplier instanceof InstanceSupplier<T> instanceSupplier
|
||||
&& instanceSupplier.getFactoryMethod() == factoryMethod) {
|
||||
|
||||
if (supplier instanceof InstanceSupplier<T> instanceSupplier &&
|
||||
instanceSupplier.getFactoryMethod() == factoryMethod) {
|
||||
return instanceSupplier;
|
||||
}
|
||||
return new InstanceSupplier<>() {
|
||||
|
||||
return new InstanceSupplier<>() {
|
||||
@Override
|
||||
public T get(RegisteredBean registeredBean) throws Exception {
|
||||
return supplier.getWithException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getFactoryMethod() {
|
||||
return factoryMethod;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+19
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -80,6 +80,18 @@ public final class RegisteredBean {
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link RegisteredBean} instance for a regular bean.
|
||||
* @param beanFactory the source bean factory
|
||||
* @param beanName the bean name
|
||||
* @param mbd the pre-determined merged bean definition
|
||||
* @return a new {@link RegisteredBean} instance
|
||||
* @since 6.0.7
|
||||
*/
|
||||
static RegisteredBean of(ConfigurableListableBeanFactory beanFactory, String beanName, RootBeanDefinition mbd) {
|
||||
return new RegisteredBean(beanFactory, () -> beanName, false, () -> mbd, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link RegisteredBean} instance for an inner-bean.
|
||||
* @param parent the parent of the inner-bean
|
||||
@@ -220,45 +232,34 @@ public final class RegisteredBean {
|
||||
@Nullable
|
||||
private volatile String resolvedBeanName;
|
||||
|
||||
|
||||
InnerBeanResolver(RegisteredBean parent, @Nullable String innerBeanName,
|
||||
BeanDefinition innerBeanDefinition) {
|
||||
|
||||
Assert.isInstanceOf(AbstractAutowireCapableBeanFactory.class,
|
||||
parent.getBeanFactory());
|
||||
InnerBeanResolver(RegisteredBean parent, @Nullable String innerBeanName, BeanDefinition innerBeanDefinition) {
|
||||
Assert.isInstanceOf(AbstractAutowireCapableBeanFactory.class, parent.getBeanFactory());
|
||||
this.parent = parent;
|
||||
this.innerBeanName = innerBeanName;
|
||||
this.innerBeanDefinition = innerBeanDefinition;
|
||||
}
|
||||
|
||||
|
||||
String resolveBeanName() {
|
||||
String resolvedBeanName = this.resolvedBeanName;
|
||||
if (resolvedBeanName != null) {
|
||||
return resolvedBeanName;
|
||||
}
|
||||
resolvedBeanName = resolveInnerBean(
|
||||
(beanName, mergedBeanDefinition) -> beanName);
|
||||
resolvedBeanName = resolveInnerBean((beanName, mergedBeanDefinition) -> beanName);
|
||||
this.resolvedBeanName = resolvedBeanName;
|
||||
return resolvedBeanName;
|
||||
}
|
||||
|
||||
RootBeanDefinition resolveMergedBeanDefinition() {
|
||||
return resolveInnerBean(
|
||||
(beanName, mergedBeanDefinition) -> mergedBeanDefinition);
|
||||
return resolveInnerBean((beanName, mergedBeanDefinition) -> mergedBeanDefinition);
|
||||
}
|
||||
|
||||
private <T> T resolveInnerBean(
|
||||
BiFunction<String, RootBeanDefinition, T> resolver) {
|
||||
|
||||
private <T> T resolveInnerBean(BiFunction<String, RootBeanDefinition, T> resolver) {
|
||||
// Always use a fresh BeanDefinitionValueResolver in case the parent merged bean definition has changed.
|
||||
BeanDefinitionValueResolver beanDefinitionValueResolver = new BeanDefinitionValueResolver(
|
||||
(AbstractAutowireCapableBeanFactory) this.parent.getBeanFactory(),
|
||||
this.parent.getBeanName(), this.parent.getMergedBeanDefinition());
|
||||
return beanDefinitionValueResolver.resolveInnerBean(this.innerBeanName,
|
||||
this.innerBeanDefinition, resolver);
|
||||
return beanDefinitionValueResolver.resolveInnerBean(this.innerBeanName, this.innerBeanDefinition, resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -163,8 +163,8 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
catch (InvocationTargetException ex) {
|
||||
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception with message: " +
|
||||
ex.getTargetException().getMessage();
|
||||
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
|
||||
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
|
||||
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory cbf &&
|
||||
cbf.isCurrentlyInCreation(bd.getFactoryBeanName())) {
|
||||
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
|
||||
"declaring the factory method as static for independence from its containing instance. " + msg;
|
||||
}
|
||||
|
||||
+11
-11
@@ -127,9 +127,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
throw new BeanIsNotAFactoryException(beanName, bean.getClass());
|
||||
}
|
||||
|
||||
if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
try {
|
||||
Object exposedObject = ((FactoryBean<?>) bean).getObject();
|
||||
Object exposedObject = factoryBean.getObject();
|
||||
if (exposedObject == null) {
|
||||
throw new BeanCreationException(beanName, "FactoryBean exposed null object");
|
||||
}
|
||||
@@ -205,8 +205,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||
Object bean = getBean(name);
|
||||
// In case of FactoryBean, return singleton status of created object.
|
||||
if (bean instanceof FactoryBean) {
|
||||
return ((FactoryBean<?>) bean).isSingleton();
|
||||
if (bean instanceof FactoryBean<?> factoryBean) {
|
||||
return factoryBean.isSingleton();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -215,8 +215,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
|
||||
Object bean = getBean(name);
|
||||
// In case of FactoryBean, return prototype status of created object.
|
||||
return ((bean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) bean).isPrototype()) ||
|
||||
(bean instanceof FactoryBean && !((FactoryBean<?>) bean).isSingleton()));
|
||||
return ((bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isPrototype()) ||
|
||||
(bean instanceof FactoryBean<?> factoryBean && !factoryBean.isSingleton()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -246,9 +246,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
|
||||
}
|
||||
|
||||
if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
|
||||
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
|
||||
return ((FactoryBean<?>) bean).getObjectType();
|
||||
return factoryBean.getObjectType();
|
||||
}
|
||||
return bean.getClass();
|
||||
}
|
||||
@@ -408,10 +408,10 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
String beanName = entry.getKey();
|
||||
Object beanInstance = entry.getValue();
|
||||
// Is bean a FactoryBean?
|
||||
if (beanInstance instanceof FactoryBean<?> factory && !isFactoryType) {
|
||||
if (beanInstance instanceof FactoryBean<?> factoryBean && !isFactoryType) {
|
||||
// Match object created by FactoryBean.
|
||||
Class<?> objectType = factory.getObjectType();
|
||||
if ((includeNonSingletons || factory.isSingleton()) &&
|
||||
Class<?> objectType = factoryBean.getObjectType();
|
||||
if ((includeNonSingletons || factoryBean.isSingleton()) &&
|
||||
objectType != null && (type == null || type.isAssignableFrom(objectType))) {
|
||||
matches.put(beanName, getBean(beanName, type));
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -547,7 +547,8 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
* @see DefaultNamespaceHandlerResolver#DefaultNamespaceHandlerResolver(ClassLoader)
|
||||
*/
|
||||
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
|
||||
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
|
||||
ResourceLoader resourceLoader = getResourceLoader();
|
||||
ClassLoader cl = (resourceLoader != null ? resourceLoader.getClassLoader() : getBeanClassLoader());
|
||||
return new DefaultNamespaceHandlerResolver(cl);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -111,6 +111,7 @@ public class ArgumentConvertingMethodInvoker extends MethodInvoker {
|
||||
* @see #doFindMatchingMethod
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
protected Method findMatchingMethod() {
|
||||
Method matchingMethod = super.findMatchingMethod();
|
||||
// Second pass: look for method where arguments can be converted to parameter types.
|
||||
|
||||
+28
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -205,11 +205,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
kerry.setSpouse(target);
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
Integer KA = (Integer) accessor.getPropertyValue("spouse.age");
|
||||
assertThat(KA == 35).as("kerry is 35").isTrue();
|
||||
assertThat(KA).as("kerry is 35").isEqualTo(35);
|
||||
Integer RA = (Integer) accessor.getPropertyValue("spouse.spouse.age");
|
||||
assertThat(RA == 31).as("rod is 31, not" + RA).isTrue();
|
||||
assertThat(RA).as("rod is 31, not" + RA).isEqualTo(31);
|
||||
ITestBean spousesSpouse = (ITestBean) accessor.getPropertyValue("spouse.spouse");
|
||||
assertThat(target == spousesSpouse).as("spousesSpouse = initial point").isTrue();
|
||||
assertThat(target).as("spousesSpouse = initial point").isSameAs(spousesSpouse);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -236,13 +236,14 @@ abstract class AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void getPropertyIntermediateMapEntryIsNullWithAutoGrow() {
|
||||
Foo target = new Foo();
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
accessor.setConversionService(new DefaultConversionService());
|
||||
accessor.setAutoGrowNestedPaths(true);
|
||||
accessor.setPropertyValue("listOfMaps[0]['luckyNumber']", "9");
|
||||
assertThat(target.listOfMaps.get(0).get("luckyNumber")).isEqualTo("9");
|
||||
assertThat(target.listOfMaps.get(0)).containsEntry("luckyNumber", "9");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -298,13 +299,14 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("spouse.company", "Lewisham");
|
||||
assertThat(kerry.getName()).as("kerry name is Kerry").isEqualTo("Kerry");
|
||||
|
||||
assertThat(target.getSpouse() == kerry).as("nested set worked").isTrue();
|
||||
assertThat(target.getSpouse()).as("nested set worked").isSameAs(kerry);
|
||||
assertThat(kerry.getSpouse()).as("no back relation").isNull();
|
||||
accessor.setPropertyValue(new PropertyValue("spouse.spouse", target));
|
||||
assertThat(kerry.getSpouse() == target).as("nested set worked").isTrue();
|
||||
assertThat(kerry.getSpouse()).as("nested set worked").isSameAs(target);
|
||||
|
||||
AbstractPropertyAccessor kerryAccessor = createAccessor(kerry);
|
||||
assertThat("Lewisham".equals(kerryAccessor.getPropertyValue("spouse.spouse.spouse.spouse.company"))).as("spouse.spouse.spouse.spouse.company=Lewisham").isTrue();
|
||||
assertThat(kerryAccessor.getPropertyValue("spouse.spouse.spouse.spouse.company")).as("spouse.spouse.spouse.spouse.company=Lewisham")
|
||||
.isEqualTo("Lewisham");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -315,13 +317,13 @@ abstract class AbstractPropertyAccessorTests {
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("spouse", kerry);
|
||||
|
||||
assertThat(target.getSpouse() == kerry).as("nested set worked").isTrue();
|
||||
assertThat(target.getSpouse()).as("nested set worked").isSameAs(kerry);
|
||||
assertThat(kerry.getSpouse()).as("no back relation").isNull();
|
||||
accessor.setPropertyValue(new PropertyValue("spouse.spouse", target));
|
||||
assertThat(kerry.getSpouse() == target).as("nested set worked").isTrue();
|
||||
assertThat(kerry.getAge() == 0).as("kerry age not set").isTrue();
|
||||
assertThat(kerry.getSpouse()).as("nested set worked").isSameAs(target);
|
||||
assertThat(kerry.getAge()).as("kerry age not set").isEqualTo(0);
|
||||
accessor.setPropertyValue(new PropertyValue("spouse.age", 35));
|
||||
assertThat(kerry.getAge() == 35).as("Set primitive on spouse").isTrue();
|
||||
assertThat(kerry.getAge()).as("Set primitive on spouse").isEqualTo(35);
|
||||
|
||||
assertThat(accessor.getPropertyValue("spouse")).isEqualTo(kerry);
|
||||
assertThat(accessor.getPropertyValue("spouse.spouse")).isEqualTo(target);
|
||||
@@ -359,7 +361,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.getPropertyValue("spouse.bla");
|
||||
}
|
||||
catch (NotReadablePropertyException ex) {
|
||||
assertThat(ex.getMessage().contains(TestBean.class.getName())).isTrue();
|
||||
assertThat(ex.getMessage()).contains(TestBean.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,12 +444,12 @@ abstract class AbstractPropertyAccessorTests {
|
||||
target.setAge(age);
|
||||
target.setName(name);
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
assertThat(target.getAge() == age).as("age is OK").isTrue();
|
||||
assertThat(name.equals(target.getName())).as("name is OK").isTrue();
|
||||
assertThat(target.getAge()).as("age is OK").isEqualTo(age);
|
||||
assertThat(name).as("name is OK").isEqualTo(target.getName());
|
||||
accessor.setPropertyValues(new MutablePropertyValues());
|
||||
// Check its unchanged
|
||||
assertThat(target.getAge() == age).as("age is OK").isTrue();
|
||||
assertThat(name.equals(target.getName())).as("name is OK").isTrue();
|
||||
assertThat(target.getAge()).as("age is OK").isEqualTo(age);
|
||||
assertThat(name).as("name is OK").isEqualTo(target.getName());
|
||||
}
|
||||
|
||||
|
||||
@@ -463,9 +465,9 @@ abstract class AbstractPropertyAccessorTests {
|
||||
pvs.addPropertyValue(new PropertyValue("name", newName));
|
||||
pvs.addPropertyValue(new PropertyValue("touchy", newTouchy));
|
||||
accessor.setPropertyValues(pvs);
|
||||
assertThat(target.getName().equals(newName)).as("Name property should have changed").isTrue();
|
||||
assertThat(target.getTouchy().equals(newTouchy)).as("Touchy property should have changed").isTrue();
|
||||
assertThat(target.getAge() == newAge).as("Age property should have changed").isTrue();
|
||||
assertThat(target.getName()).as("Name property should have changed").isEqualTo(newName);
|
||||
assertThat(target.getTouchy()).as("Touchy property should have changed").isEqualTo(newTouchy);
|
||||
assertThat(target.getAge()).as("Age property should have changed").isEqualTo(newAge);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -480,7 +482,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue(new PropertyValue("touchy", newTouchy));
|
||||
assertThat(target.getName()).as("Name property should have changed").isEqualTo(newName);
|
||||
assertThat(target.getTouchy()).as("Touchy property should have changed").isEqualTo(newTouchy);
|
||||
assertThat(target.getAge() == newAge).as("Age property should have changed").isTrue();
|
||||
assertThat(target.getAge()).as("Age property should have changed").isEqualTo(newAge);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -559,11 +561,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
}
|
||||
});
|
||||
accessor.setPropertyValue("name", new String[] {});
|
||||
assertThat(target.getName()).isEqualTo("");
|
||||
assertThat(target.getName()).isEmpty();
|
||||
accessor.setPropertyValue("name", new String[] {"a1", "b2"});
|
||||
assertThat(target.getName()).isEqualTo("a1-b2");
|
||||
accessor.setPropertyValue("name", null);
|
||||
assertThat(target.getName()).isEqualTo("");
|
||||
assertThat(target.getName()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -577,7 +579,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
|
||||
accessor.setPropertyValue("bool2", "false");
|
||||
assertThat(Boolean.FALSE.equals(accessor.getPropertyValue("bool2"))).as("Correct bool2 value").isTrue();
|
||||
assertThat(!target.getBool2()).as("Correct bool2 value").isTrue();
|
||||
assertThat(target.getBool2()).as("Correct bool2 value").isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -729,7 +731,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
String freedomVal = target.properties.getProperty("freedom");
|
||||
String peaceVal = target.properties.getProperty("peace");
|
||||
assertThat(peaceVal).as("peace==war").isEqualTo("war");
|
||||
assertThat(freedomVal.equals("slavery")).as("Freedom==slavery").isTrue();
|
||||
assertThat(freedomVal).as("Freedom==slavery").isEqualTo("slavery");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1344,7 +1346,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
pvs.addPropertyValue(new PropertyValue("more.garbage", new Object()));
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
accessor.setPropertyValues(pvs, true);
|
||||
assertThat(target.getName().equals("rod")).as("Set valid and ignored invalid").isTrue();
|
||||
assertThat(target.getName()).as("Set valid and ignored invalid").isEqualTo("rod");
|
||||
assertThatExceptionOfType(NotWritablePropertyException.class).isThrownBy(() ->
|
||||
accessor.setPropertyValues(pvs, false)); // Don't ignore: should fail
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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,7 +31,7 @@ public abstract class AbstractPropertyValuesTests {
|
||||
* Must contain: forname=Tony surname=Blair age=50
|
||||
*/
|
||||
protected void doTestTony(PropertyValues pvs) {
|
||||
assertThat(pvs.getPropertyValues().length == 3).as("Contains 3").isTrue();
|
||||
assertThat(pvs.getPropertyValues()).as("Contains 3").hasSize(3);
|
||||
assertThat(pvs.contains("forname")).as("Contains forname").isTrue();
|
||||
assertThat(pvs.contains("surname")).as("Contains surname").isTrue();
|
||||
assertThat(pvs.contains("age")).as("Contains age").isTrue();
|
||||
@@ -45,13 +45,13 @@ public abstract class AbstractPropertyValuesTests {
|
||||
m.put("age", "50");
|
||||
for (PropertyValue element : ps) {
|
||||
Object val = m.get(element.getName());
|
||||
assertThat(val != null).as("Can't have unexpected value").isTrue();
|
||||
assertThat(val).as("Can't have unexpected value").isNotNull();
|
||||
boolean condition = val instanceof String;
|
||||
assertThat(condition).as("Val i string").isTrue();
|
||||
assertThat(val.equals(element.getValue())).as("val matches expected").isTrue();
|
||||
m.remove(element.getName());
|
||||
}
|
||||
assertThat(m.size() == 0).as("Map size is 0").isTrue();
|
||||
assertThat(m).as("Map size is 0").isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -135,7 +135,7 @@ class BeanUtilsTests {
|
||||
PropertyDescriptor[] actual = Introspector.getBeanInfo(TestBean.class).getPropertyDescriptors();
|
||||
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(TestBean.class);
|
||||
assertThat(descriptors).as("Descriptors should not be null").isNotNull();
|
||||
assertThat(descriptors.length).as("Invalid number of descriptors returned").isEqualTo(actual.length);
|
||||
assertThat(descriptors).as("Invalid number of descriptors returned").hasSameSizeAs(actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,13 +161,13 @@ class BeanUtilsTests {
|
||||
tb.setAge(32);
|
||||
tb.setTouchy("touchy");
|
||||
TestBean tb2 = new TestBean();
|
||||
assertThat(tb2.getName() == null).as("Name empty").isTrue();
|
||||
assertThat(tb2.getAge() == 0).as("Age empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy empty").isTrue();
|
||||
assertThat(tb2.getName()).as("Name empty").isNull();
|
||||
assertThat(tb2.getAge()).as("Age empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy empty").isNull();
|
||||
BeanUtils.copyProperties(tb, tb2);
|
||||
assertThat(tb2.getName().equals(tb.getName())).as("Name copied").isTrue();
|
||||
assertThat(tb2.getAge() == tb.getAge()).as("Age copied").isTrue();
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
assertThat(tb2.getName()).as("Name copied").isEqualTo(tb.getName());
|
||||
assertThat(tb2.getAge()).as("Age copied").isEqualTo(tb.getAge());
|
||||
assertThat(tb2.getTouchy()).as("Touchy copied").isEqualTo(tb.getTouchy());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -177,13 +177,13 @@ class BeanUtilsTests {
|
||||
tb.setAge(32);
|
||||
tb.setTouchy("touchy");
|
||||
TestBean tb2 = new TestBean();
|
||||
assertThat(tb2.getName() == null).as("Name empty").isTrue();
|
||||
assertThat(tb2.getAge() == 0).as("Age empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy empty").isTrue();
|
||||
assertThat(tb2.getName()).as("Name empty").isNull();
|
||||
assertThat(tb2.getAge()).as("Age empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy empty").isNull();
|
||||
BeanUtils.copyProperties(tb, tb2);
|
||||
assertThat(tb2.getName().equals(tb.getName())).as("Name copied").isTrue();
|
||||
assertThat(tb2.getAge() == tb.getAge()).as("Age copied").isTrue();
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
assertThat(tb2.getName()).as("Name copied").isEqualTo(tb.getName());
|
||||
assertThat(tb2.getAge()).as("Age copied").isEqualTo(tb.getAge());
|
||||
assertThat(tb2.getTouchy()).as("Touchy copied").isEqualTo(tb.getTouchy());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -193,13 +193,13 @@ class BeanUtilsTests {
|
||||
tb.setAge(32);
|
||||
tb.setTouchy("touchy");
|
||||
DerivedTestBean tb2 = new DerivedTestBean();
|
||||
assertThat(tb2.getName() == null).as("Name empty").isTrue();
|
||||
assertThat(tb2.getAge() == 0).as("Age empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy empty").isTrue();
|
||||
assertThat(tb2.getName()).as("Name empty").isNull();
|
||||
assertThat(tb2.getAge()).as("Age empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy empty").isNull();
|
||||
BeanUtils.copyProperties(tb, tb2);
|
||||
assertThat(tb2.getName().equals(tb.getName())).as("Name copied").isTrue();
|
||||
assertThat(tb2.getAge() == tb.getAge()).as("Age copied").isTrue();
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
assertThat(tb2.getName()).as("Name copied").isEqualTo(tb.getName());
|
||||
assertThat(tb2.getAge()).as("Age copied").isEqualTo(tb.getAge());
|
||||
assertThat(tb2.getTouchy()).as("Touchy copied").isEqualTo(tb.getTouchy());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,37 +342,37 @@ class BeanUtilsTests {
|
||||
@Test
|
||||
void copyPropertiesWithEditable() throws Exception {
|
||||
TestBean tb = new TestBean();
|
||||
assertThat(tb.getName() == null).as("Name empty").isTrue();
|
||||
assertThat(tb.getName()).as("Name empty").isNull();
|
||||
tb.setAge(32);
|
||||
tb.setTouchy("bla");
|
||||
TestBean tb2 = new TestBean();
|
||||
tb2.setName("rod");
|
||||
assertThat(tb2.getAge() == 0).as("Age empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy empty").isTrue();
|
||||
assertThat(tb2.getAge()).as("Age empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy empty").isNull();
|
||||
|
||||
// "touchy" should not be copied: it's not defined in ITestBean
|
||||
BeanUtils.copyProperties(tb, tb2, ITestBean.class);
|
||||
assertThat(tb2.getName() == null).as("Name copied").isTrue();
|
||||
assertThat(tb2.getAge() == 32).as("Age copied").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy still empty").isTrue();
|
||||
assertThat(tb2.getName()).as("Name copied").isNull();
|
||||
assertThat(tb2.getAge()).as("Age copied").isEqualTo(32);
|
||||
assertThat(tb2.getTouchy()).as("Touchy still empty").isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyPropertiesWithIgnore() throws Exception {
|
||||
TestBean tb = new TestBean();
|
||||
assertThat(tb.getName() == null).as("Name empty").isTrue();
|
||||
assertThat(tb.getName()).as("Name empty").isNull();
|
||||
tb.setAge(32);
|
||||
tb.setTouchy("bla");
|
||||
TestBean tb2 = new TestBean();
|
||||
tb2.setName("rod");
|
||||
assertThat(tb2.getAge() == 0).as("Age empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy empty").isTrue();
|
||||
assertThat(tb2.getAge()).as("Age empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy empty").isNull();
|
||||
|
||||
// "spouse", "touchy", "age" should not be copied
|
||||
BeanUtils.copyProperties(tb, tb2, "spouse", "touchy", "age");
|
||||
assertThat(tb2.getName() == null).as("Name copied").isTrue();
|
||||
assertThat(tb2.getAge() == 0).as("Age still empty").isTrue();
|
||||
assertThat(tb2.getTouchy() == null).as("Touchy still empty").isTrue();
|
||||
assertThat(tb2.getName()).as("Name copied").isNull();
|
||||
assertThat(tb2.getAge()).as("Age still empty").isEqualTo(0);
|
||||
assertThat(tb2.getTouchy()).as("Touchy still empty").isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -381,7 +381,7 @@ class BeanUtilsTests {
|
||||
source.setName("name");
|
||||
TestBean target = new TestBean();
|
||||
BeanUtils.copyProperties(source, target, "specialProperty");
|
||||
assertThat("name").isEqualTo(target.getName());
|
||||
assertThat(target.getName()).isEqualTo("name");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -90,15 +90,15 @@ public class BeanWrapperAutoGrowingTests {
|
||||
|
||||
@Test
|
||||
public void getPropertyValueAutoGrow2dArray() {
|
||||
assertNotNull(wrapper.getPropertyValue("multiArray[0][0]"));
|
||||
assertThat(wrapper.getPropertyValue("multiArray[0][0]")).isNotNull();
|
||||
assertThat(bean.getMultiArray()[0]).hasSize(1);
|
||||
assertThat(bean.getMultiArray()[0][0]).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueAutoGrow3dArray() {
|
||||
assertNotNull(wrapper.getPropertyValue("threeDimensionalArray[1][2][3]"));
|
||||
assertThat(bean.getThreeDimensionalArray()[1].length).isEqualTo(3);
|
||||
assertThat(wrapper.getPropertyValue("threeDimensionalArray[1][2][3]")).isNotNull();
|
||||
assertThat(bean.getThreeDimensionalArray()[1]).hasNumberOfRows(3);
|
||||
assertThat(bean.getThreeDimensionalArray()[1][2][3]).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -161,8 +161,8 @@ class BeanWrapperGenericsTests {
|
||||
value2.add(Boolean.TRUE);
|
||||
input.put("2", value2);
|
||||
bw.setPropertyValue("collectionMap", input);
|
||||
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
|
||||
assertThat(gb.getCollectionMap().get(2) instanceof ArrayList).isTrue();
|
||||
assertThat(gb.getCollectionMap().get(1)).isInstanceOf(HashSet.class);
|
||||
assertThat(gb.getCollectionMap().get(2)).isInstanceOf(ArrayList.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -174,7 +174,7 @@ class BeanWrapperGenericsTests {
|
||||
HashSet<Integer> value1 = new HashSet<>();
|
||||
value1.add(1);
|
||||
bw.setPropertyValue("collectionMap[1]", value1);
|
||||
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
|
||||
assertThat(gb.getCollectionMap().get(1)).isInstanceOf(HashSet.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -320,7 +320,7 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfInteger().get("testKey");
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
assertThat(obj).isInstanceOf(Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -334,7 +334,7 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfListOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfListOfInteger().get("testKey").get(0);
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
assertThat(obj).isInstanceOf(Integer.class);
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("listOfMapOfInteger", list);
|
||||
|
||||
Object obj = gb.getListOfMapOfInteger().get(0).get("testKey");
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
assertThat(obj).isInstanceOf(Integer.class);
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfListOfListOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfListOfListOfInteger().get("testKey").get(0).get(0);
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
assertThat(obj).isInstanceOf(Integer.class);
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -246,16 +246,16 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
accessor.setPropertyValue("object", tb);
|
||||
assertThat(target.value).isSameAs(tb);
|
||||
assertThat(target.getObject().get()).isSameAs(tb);
|
||||
assertThat(((Optional<TestBean>) accessor.getPropertyValue("object")).get()).isSameAs(tb);
|
||||
assertThat(target.getObject()).containsSame(tb);
|
||||
assertThat(((Optional<TestBean>) accessor.getPropertyValue("object"))).containsSame(tb);
|
||||
assertThat(target.value.getName()).isEqualTo("x");
|
||||
assertThat(target.getObject().get().getName()).isEqualTo("x");
|
||||
assertThat(accessor.getPropertyValue("object.name")).isEqualTo("x");
|
||||
|
||||
accessor.setPropertyValue("object.name", "y");
|
||||
assertThat(target.value).isSameAs(tb);
|
||||
assertThat(target.getObject().get()).isSameAs(tb);
|
||||
assertThat(((Optional<TestBean>) accessor.getPropertyValue("object")).get()).isSameAs(tb);
|
||||
assertThat(target.getObject()).containsSame(tb);
|
||||
assertThat(((Optional<TestBean>) accessor.getPropertyValue("object"))).containsSame(tb);
|
||||
assertThat(target.value.getName()).isEqualTo("y");
|
||||
assertThat(target.getObject().get().getName()).isEqualTo("y");
|
||||
assertThat(accessor.getPropertyValue("object.name")).isEqualTo("y");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -585,7 +585,7 @@ class ExtendedBeanInfoTests {
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo")).isTrue();
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo")).isTrue();
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSize(bi.getPropertyDescriptors().length);
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSameSizeAs(bi.getPropertyDescriptors());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -711,7 +711,7 @@ class ExtendedBeanInfoTests {
|
||||
BeanInfo bi = Introspector.getBeanInfo(TestBean.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSize(bi.getPropertyDescriptors().length);
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSameSizeAs(bi.getPropertyDescriptors());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+9
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -70,7 +70,7 @@ public class MutablePropertyValuesTests extends AbstractPropertyValuesTests {
|
||||
pvs.addPropertyValue(new PropertyValue("age", "50"));
|
||||
MutablePropertyValues pvs2 = pvs;
|
||||
PropertyValues changes = pvs2.changesSince(pvs);
|
||||
assertThat(changes.getPropertyValues().length == 0).as("changes are empty").isTrue();
|
||||
assertThat(changes.getPropertyValues().length).as("changes are empty").isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,26 +82,28 @@ public class MutablePropertyValuesTests extends AbstractPropertyValuesTests {
|
||||
|
||||
MutablePropertyValues pvs2 = new MutablePropertyValues(pvs);
|
||||
PropertyValues changes = pvs2.changesSince(pvs);
|
||||
assertThat(changes.getPropertyValues().length == 0).as("changes are empty, not of length " + changes.getPropertyValues().length).isTrue();
|
||||
assertThat(changes.getPropertyValues().length).as("changes are empty, not of length " + changes.getPropertyValues().length)
|
||||
.isEqualTo(0);
|
||||
|
||||
pvs2.addPropertyValue(new PropertyValue("forname", "Gordon"));
|
||||
changes = pvs2.changesSince(pvs);
|
||||
assertThat(changes.getPropertyValues().length).as("1 change").isEqualTo(1);
|
||||
PropertyValue fn = changes.getPropertyValue("forname");
|
||||
assertThat(fn != null).as("change is forname").isTrue();
|
||||
assertThat(fn).as("change is forname").isNotNull();
|
||||
assertThat(fn.getValue().equals("Gordon")).as("new value is gordon").isTrue();
|
||||
|
||||
MutablePropertyValues pvs3 = new MutablePropertyValues(pvs);
|
||||
changes = pvs3.changesSince(pvs);
|
||||
assertThat(changes.getPropertyValues().length == 0).as("changes are empty, not of length " + changes.getPropertyValues().length).isTrue();
|
||||
assertThat(changes.getPropertyValues().length).as("changes are empty, not of length " + changes.getPropertyValues().length)
|
||||
.isEqualTo(0);
|
||||
|
||||
// add new
|
||||
pvs3.addPropertyValue(new PropertyValue("foo", "bar"));
|
||||
pvs3.addPropertyValue(new PropertyValue("fi", "fum"));
|
||||
changes = pvs3.changesSince(pvs);
|
||||
assertThat(changes.getPropertyValues().length == 2).as("2 change").isTrue();
|
||||
assertThat(changes.getPropertyValues().length).as("2 change").isEqualTo(2);
|
||||
fn = changes.getPropertyValue("foo");
|
||||
assertThat(fn != null).as("change in foo").isTrue();
|
||||
assertThat(fn).as("change in foo").isNotNull();
|
||||
assertThat(fn.getValue().equals("bar")).as("new value is bar").isTrue();
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user