mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab5a6a5e48 |
@@ -1,33 +1,23 @@
|
||||
Juergen Hoeller <jhoeller@vmware.com>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
|
||||
Phillip Webb <pwebb@vmware.com>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
|
||||
Chris Beams <cbeams@vmware.com>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@pivotal.io>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@gopivotal.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <poutsma@mac.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
|
||||
Andy Clement <aclement@vmware.com>
|
||||
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
|
||||
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
|
||||
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
|
||||
Sam Brannen <sbrannen@vmware.com>
|
||||
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
|
||||
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
|
||||
Juergen Hoeller <jhoeller@pivotal.io> jhoeller <jhoeller@vmware.com>
|
||||
<jhoeller@pivotal.io> <jhoeller@vmware.com>
|
||||
<jhoeller@pivotal.io> <jhoeller@gopivotal.com>
|
||||
<rstoyanchev@pivotal.io> <rstoyanchev@vmware.com>
|
||||
<rstoyanchev@pivotal.io> <rstoyanchev@gopivotal.com>
|
||||
<pwebb@pivotal.io> <pwebb@vmware.com>
|
||||
<pwebb@pivotal.io> <pwebb@gopivotal.com>
|
||||
<cbeams@pivotal.io> <cbeams@vmware.com>
|
||||
<cbeams@pivotal.io> <cbeams@gopivotal.com>
|
||||
<cbeams@pivotal.io> <cbeams@gmail.com>
|
||||
<apoutsma@pivotal.io> <apoutsma@vmware.com>
|
||||
<apoutsma@pivotal.io> <apoutsma@gopivotal.com>
|
||||
<apoutsma@pivotal.io> <poutsma@mac.com>
|
||||
<ogierke@pivotal.io> <ogierke@vmware.com>
|
||||
<ogierke@pivotal.io> <ogierke@gopivotal.com>
|
||||
<dsyer@pivotal.io> <dsyer@vmware.com>
|
||||
<dsyer@pivotal.io> <dsyer@gopivotal.com>
|
||||
<dsyer@pivotal.io> <david_syer@hotmail.com>
|
||||
<aclement@pivotal.io> <aclement@vmware.com>
|
||||
<aclement@pivotal.io> <aclement@gopivotal.com>
|
||||
<aclement@pivotal.io> <andrew.clement@gmail.com>
|
||||
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
|
||||
Nick Williams <nicholas@nicholaswilliams.net>
|
||||
Nick Williams <nicholas@nicholaswilliams.net> Nicholas Williams <nicholas@nicholaswilliams.net>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=8.0.333-librca
|
||||
+23
-23
@@ -27,25 +27,25 @@ configure(allprojects) { project ->
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.7"
|
||||
mavenBom "io.netty:netty-bom:4.1.77.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.20"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.2"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.46.v20220331"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
|
||||
mavenBom "io.netty:netty-bom:4.1.74.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.16"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
|
||||
mavenBom "org.junit:junit-bom:5.8.2"
|
||||
}
|
||||
dependencies {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.1') {
|
||||
entry 'log4j-api'
|
||||
entry 'log4j-core'
|
||||
entry 'log4j-jul'
|
||||
entry 'log4j-slf4j-impl'
|
||||
}
|
||||
dependency "org.slf4j:slf4j-api:1.7.36"
|
||||
dependency "org.slf4j:slf4j-api:1.7.35"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
@@ -67,8 +67,8 @@ configure(allprojects) { project ->
|
||||
dependency "io.reactivex:rxjava:1.3.8"
|
||||
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
|
||||
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.4"
|
||||
dependency "io.smallrye.reactive:mutiny:1.4.0"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
|
||||
dependency "io.smallrye.reactive:mutiny:1.3.1"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
@@ -83,7 +83,7 @@ configure(allprojects) { project ->
|
||||
exclude group: "xpp3", name: "xpp3_min"
|
||||
exclude group: "xmlpull", name: "xmlpull"
|
||||
}
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.18"
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
|
||||
dependency("org.codehaus.jettison:jettison:1.3.8") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
@@ -94,9 +94,9 @@ configure(allprojects) { project ->
|
||||
dependency "org.ogce:xpp3:1.1.6"
|
||||
dependency "org.yaml:snakeyaml:1.30"
|
||||
|
||||
dependency "com.h2database:h2:2.1.212"
|
||||
dependency "com.h2database:h2:2.1.210"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
|
||||
dependency "com.github.librepdf:openpdf:1.3.28"
|
||||
dependency "com.github.librepdf:openpdf:1.3.26"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
@@ -124,22 +124,22 @@ configure(allprojects) { project ->
|
||||
dependency "org.ehcache:jcache:1.0.1"
|
||||
dependency "org.ehcache:ehcache:3.4.0"
|
||||
dependency "org.hibernate:hibernate-core:5.4.33.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.2.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.64') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.58') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.64') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.58') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.2.17.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
|
||||
@@ -150,7 +150,7 @@ configure(allprojects) { project ->
|
||||
}
|
||||
}
|
||||
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.11"
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
@@ -191,14 +191,14 @@ configure(allprojects) { project ->
|
||||
dependency "org.junit.support:testng-engine:1.0.1"
|
||||
dependency "org.hamcrest:hamcrest:2.1"
|
||||
dependency "org.awaitility:awaitility:3.1.6"
|
||||
dependency "org.assertj:assertj-core:3.23.0"
|
||||
dependency "org.assertj:assertj-core:3.22.0"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
|
||||
entry 'xmlunit-assertj'
|
||||
entry('xmlunit-matchers') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '4.6.1') {
|
||||
dependencySet(group: 'org.mockito', version: '4.3.1') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.62.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.58.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.62.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.58.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.3"
|
||||
toolVersion = "9.3"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220531
|
||||
FROM ubuntu:focal-20220113
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
|
||||
@@ -3,18 +3,18 @@ set -e
|
||||
|
||||
case "$1" in
|
||||
java8)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/8u333+2/bellsoft-jdk8u333+2-linux-amd64.tar.gz"
|
||||
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
|
||||
;;
|
||||
java11)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/11.0.15.1+2/bellsoft-jdk11.0.15.1+2-linux-amd64.tar.gz"
|
||||
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
|
||||
;;
|
||||
java17)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.3.1+2/bellsoft-jdk17.0.3.1+2-linux-amd64.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/18.0.1.1+2/bellsoft-jdk18.0.1.1+2-linux-amd64.tar.gz"
|
||||
;;
|
||||
*)
|
||||
java17)
|
||||
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
@@ -14,6 +14,8 @@ rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
|
||||
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.3/concourse-release-scripts-0.3.3.jar
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
###########################################################
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
github-repo: "https://github.com/spring-projects/spring-framework.git"
|
||||
github-repo-name: "spring-projects/spring-framework"
|
||||
sonatype-staging-profile: "org.springframework"
|
||||
docker-hub-organization: "springci"
|
||||
artifactory-server: "https://repo.spring.io"
|
||||
branch: "5.3.x"
|
||||
@@ -8,7 +7,4 @@ milestone: "5.3.x"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
concourse-url: "https://ci.spring.io"
|
||||
registry-mirror-host: docker.repo.spring.io
|
||||
registry-mirror-username: ((artifactory-username))
|
||||
registry-mirror-password: ((artifactory-password))
|
||||
task-timeout: 1h00m
|
||||
|
||||
+10
-23
@@ -12,7 +12,7 @@ anchors:
|
||||
SONATYPE_USERNAME: ((sonatype-username))
|
||||
SONATYPE_PASSWORD: ((sonatype-password))
|
||||
SONATYPE_URL: ((sonatype-url))
|
||||
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
|
||||
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
|
||||
artifactory-task-params: &artifactory-task-params
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
@@ -24,10 +24,6 @@ anchors:
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: ((milestone))
|
||||
registry-mirror-vars: ®istry-mirror-vars
|
||||
registry-mirror-host: ((registry-mirror-host))
|
||||
registry-mirror-username: ((registry-mirror-username))
|
||||
registry-mirror-password: ((registry-mirror-password))
|
||||
slack-fail-params: &slack-fail-params
|
||||
text: >
|
||||
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
|
||||
@@ -45,11 +41,6 @@ anchors:
|
||||
GITHUB_TOKEN: ((github-ci-release-token))
|
||||
|
||||
resource_types:
|
||||
- name: registry-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/registry-image-resource
|
||||
tag: 1.5.0
|
||||
- name: artifactory-resource
|
||||
type: registry-image
|
||||
source:
|
||||
@@ -96,7 +87,7 @@ resources:
|
||||
branch: ((branch))
|
||||
paths: ["ci/images/*"]
|
||||
- name: ci-image
|
||||
type: registry-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
@@ -166,20 +157,13 @@ resources:
|
||||
jobs:
|
||||
- name: build-ci-images
|
||||
plan:
|
||||
- get: git-repo
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- task: build-ci-image
|
||||
privileged: true
|
||||
file: git-repo/ci/tasks/build-ci-image.yml
|
||||
output_mapping:
|
||||
image: ci-image
|
||||
vars:
|
||||
ci-image-name: ci-image
|
||||
<<: *registry-mirror-vars
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- in_parallel:
|
||||
- put: ci-image
|
||||
params:
|
||||
image: ci-image/image.tar
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
|
||||
- name: build
|
||||
serial: true
|
||||
public: true
|
||||
@@ -356,6 +340,7 @@ jobs:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
@@ -400,6 +385,7 @@ jobs:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
@@ -444,6 +430,7 @@ jobs:
|
||||
download_artifacts: true
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
|
||||
@@ -6,11 +6,11 @@ CONFIG_DIR=git-repo/ci/config
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
java -jar /opt/concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
|
||||
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
java -jar /opt/concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
echo "Sync complete"
|
||||
echo $version > version/version
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/oci-build-task
|
||||
tag: 0.9.1
|
||||
registry_mirror:
|
||||
host: ((registry-mirror-host))
|
||||
username: ((registry-mirror-username))
|
||||
password: ((registry-mirror-password))
|
||||
inputs:
|
||||
- name: ci-images-git-repo
|
||||
outputs:
|
||||
- name: image
|
||||
caches:
|
||||
- path: ci-image-cache
|
||||
params:
|
||||
CONTEXT: ci-images-git-repo/ci/images
|
||||
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
|
||||
DOCKER_HUB_AUTH: ((docker-hub-auth))
|
||||
run:
|
||||
path: /bin/sh
|
||||
args:
|
||||
- "-c"
|
||||
- |
|
||||
mkdir -p /root/.docker
|
||||
cat > /root/.docker/config.json <<EOF
|
||||
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
|
||||
EOF
|
||||
build
|
||||
@@ -1,10 +1,5 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/concourse-release-scripts
|
||||
tag: '0.3.4'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
@@ -18,6 +13,6 @@ params:
|
||||
SONATYPE_USER:
|
||||
SONATYPE_PASSWORD:
|
||||
SONATYPE_URL:
|
||||
SONATYPE_STAGING_PROFILE:
|
||||
SONATYPE_STAGING_PROFILE_ID:
|
||||
run:
|
||||
path: git-repo/ci/scripts/promote-version.sh
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
version=5.3.21
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
version=5.3.16
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.stdlib.default.dependency=false
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for advice invocation order for advice configured via the
|
||||
@@ -52,7 +52,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after returning");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after throwing");
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after returning", "after");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after throwing", "after");
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for advice invocation order for advice configured via
|
||||
@@ -65,7 +65,8 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
|
||||
}
|
||||
}
|
||||
@@ -94,7 +95,8 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for the @EnableCaching annotation.
|
||||
@@ -62,7 +62,8 @@ class EnableCachingIntegrationTests {
|
||||
// this test is a bit fragile, but gets the job done, proving that an
|
||||
// attempt was made to look up the AJ aspect. It's due to classpath issues
|
||||
// in .integration-tests that it's not found.
|
||||
assertThatException().isThrownBy(ctx::refresh)
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
ctx::refresh)
|
||||
.withMessageContaining("AspectJCachingConfiguration");
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribu
|
||||
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for the @EnableTransactionManagement annotation.
|
||||
@@ -98,7 +98,7 @@ class EnableTransactionManagementIntegrationTests {
|
||||
// this test is a bit fragile, but gets the job done, proving that an
|
||||
// attempt was made to look up the AJ aspect. It's due to classpath issues
|
||||
// in .integration-tests that it's not found.
|
||||
assertThatException()
|
||||
assertThatExceptionOfType(Exception.class)
|
||||
.isThrownBy(ctx::refresh)
|
||||
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.9"
|
||||
id "com.gradle.enterprise" version "3.8.1"
|
||||
id "io.spring.ge.conventions" version "0.0.9"
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -378,7 +378,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to evaluate join point for arguments " + Arrays.toString(args) +
|
||||
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
|
||||
" - falling back to non-match", ex);
|
||||
}
|
||||
return false;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.util.ClassUtils;
|
||||
/**
|
||||
* AspectJ-based proxy factory, allowing for programmatic building
|
||||
* of proxies which include AspectJ aspects (code style as well
|
||||
* annotation style).
|
||||
* Java 5 annotation style).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,8 +60,8 @@ public class AspectMetadata implements Serializable {
|
||||
private final Class<?> aspectClass;
|
||||
|
||||
/**
|
||||
* AspectJ reflection information.
|
||||
* <p>Re-resolved on deserialization since it isn't serializable itself.
|
||||
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
|
||||
* Re-resolved on deserialization since it isn't serializable itself.
|
||||
*/
|
||||
private transient AjType<?> ajType;
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ public abstract class AopProxyUtils {
|
||||
if (targetClass.isInterface()) {
|
||||
advised.setInterfaces(targetClass);
|
||||
}
|
||||
else if (Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
|
||||
advised.setInterfaces(targetClass.getInterfaces());
|
||||
}
|
||||
specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
@@ -245,4 +245,18 @@ public abstract class AopProxyUtils {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied {@link Class} is a JVM-generated implementation
|
||||
* class for a lambda expression or method reference.
|
||||
* <p>This method makes a best-effort attempt at determining this, based on
|
||||
* checks that work on modern, main stream JVMs.
|
||||
* @param clazz the class to check
|
||||
* @return {@code true} if the class is a lambda implementation class
|
||||
* @since 5.3.16
|
||||
*/
|
||||
static boolean isLambda(Class<?> clazz) {
|
||||
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
|
||||
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -375,22 +375,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
|
||||
* to a plain reflection invocation in case of a fast-class generation failure.
|
||||
*/
|
||||
@Nullable
|
||||
private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)
|
||||
throws Throwable {
|
||||
try {
|
||||
return methodProxy.invoke(target, args);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a return value. Wraps a return of {@code this} if necessary to be the
|
||||
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
||||
@@ -441,7 +425,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
@Override
|
||||
@Nullable
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
}
|
||||
@@ -466,7 +450,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object oldProxy = null;
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -494,7 +478,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -524,7 +508,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -701,7 +685,13 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// it does nothing but a reflective operation on the target, and no hot
|
||||
// swapping or fancy proxying.
|
||||
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
|
||||
retVal = invokeMethod(target, method, argsToUse, methodProxy);
|
||||
try {
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need to create a method invocation...
|
||||
|
||||
+1
-2
@@ -21,7 +21,6 @@ import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.core.NativeDetector;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
|
||||
@@ -61,7 +60,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
"Either an interface or a target is required for proxy creation.");
|
||||
}
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
}
|
||||
return new ObjenesisCglibAopProxy(config);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -424,7 +424,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
|
||||
"- cannot resolve interceptor names " + Arrays.toString(this.interceptorNames));
|
||||
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
|
||||
}
|
||||
|
||||
// Globals can't be last unless we specified a targetSource using the property...
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,6 @@ import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostP
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -86,7 +85,6 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Sam Brannen
|
||||
* @since 13.10.2003
|
||||
* @see #setInterceptorNames
|
||||
* @see #getAdvicesAndAdvisorsForBean
|
||||
@@ -444,8 +442,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
proxyFactory.copyFrom(this);
|
||||
|
||||
if (proxyFactory.isProxyTargetClass()) {
|
||||
// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
|
||||
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass)) {
|
||||
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
|
||||
for (Class<?> ifc : beanClass.getInterfaces()) {
|
||||
proxyFactory.addInterface(ifc);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -183,8 +183,8 @@ public abstract class AopUtils {
|
||||
* may be {@code DefaultFoo}. In this case, the method may be
|
||||
* {@code DefaultFoo.bar()}. This enables attributes on that method to be found.
|
||||
* <p><b>NOTE:</b> In contrast to {@link org.springframework.util.ClassUtils#getMostSpecificMethod},
|
||||
* this method resolves bridge methods in order to retrieve attributes from
|
||||
* the <i>original</i> method definition.
|
||||
* this method resolves Java 5 bridge methods in order to retrieve attributes
|
||||
* from the <i>original</i> method definition.
|
||||
* @param method the method to be invoked, which may come from an interface
|
||||
* @param targetClass the target class for the current invocation.
|
||||
* May be {@code null} or may not even implement the method.
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,8 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple ClassFilter that looks for a specific annotation being present on a class.
|
||||
* Simple ClassFilter that looks for a specific Java 5 annotation
|
||||
* being present on a class.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,8 +26,9 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@link Pointcut} that looks for a specific annotation being present on a
|
||||
* {@linkplain #forClassAnnotation class} or {@linkplain #forMethodAnnotation method}.
|
||||
* Simple Pointcut that looks for a specific Java 5 annotation
|
||||
* being present on a {@link #forClassAnnotation class} or
|
||||
* {@link #forMethodAnnotation method}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,10 +27,9 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks
|
||||
* for a specific annotation being present on a method (checking both the method
|
||||
* on the invoked interface, if any, and the corresponding method on the target
|
||||
* class).
|
||||
* Simple MethodMatcher that looks for a specific Java 5 annotation
|
||||
* being present on a method (checking both the method on the invoked
|
||||
* interface, if any, and the corresponding method on the target class).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Additional parameter name discover tests that need Java 5.
|
||||
* Yes this will re-run the tests from the superclass, but that
|
||||
* doesn't matter in the grand scheme of things...
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AspectJAdviceParameterNameDiscoverAnnotationTests extends AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void testAnnotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
|
||||
|
||||
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
+195
-259
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,11 +17,8 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
|
||||
@@ -30,265 +27,200 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
* Unit tests for the {@link AspectJAdviceParameterNameDiscoverer} class.
|
||||
*
|
||||
* <p>See also {@link TigerAspectJAdviceParameterNameDiscovererTests} for tests relating to annotations.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class AspectJAdviceParameterNameDiscovererTests {
|
||||
public class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Nested
|
||||
class StandardTests {
|
||||
|
||||
@Test
|
||||
void noArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void twoJoinPoints() {
|
||||
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndTwoThrowables() {
|
||||
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwableNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsBindingOneObjectTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousArgsBinding() {
|
||||
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsOnePrimitiveOneObject() {
|
||||
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwingAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allTogetherNow() {
|
||||
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
new String[] {"thisJoinPoint", "ex", "x", "foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBinding() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
|
||||
}
|
||||
@Test
|
||||
public void testNoArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
*/
|
||||
@Nested
|
||||
class AnnotationTests {
|
||||
@Test
|
||||
public void testJoinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testJoinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testTwoJoinPoints() {
|
||||
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void atArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testOneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testOneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void atWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testOneJPAndTwoThrowables() {
|
||||
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void atAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
@Test
|
||||
public void testThrowableNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
@Test
|
||||
public void testReturning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousAnnotationOneVar() {
|
||||
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
|
||||
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
|
||||
}
|
||||
@Test
|
||||
public void testAmbiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotationMedley() {
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
@Test
|
||||
public void testReturningNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
@Test
|
||||
public void testThisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsBindingOneObjectTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousArgsBinding() {
|
||||
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsOnePrimitiveOneObject() {
|
||||
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowingAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllTogetherNow() {
|
||||
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
new String[] {"thisJoinPoint", "ex", "x", "foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceBinding() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
|
||||
private Method getMethod(String name) {
|
||||
protected Method getMethod(String name) {
|
||||
// Assumes no overloading of test methods...
|
||||
for (Method candidate : getClass().getMethods()) {
|
||||
Method[] candidates = getClass().getMethods();
|
||||
for (Method candidate : candidates) {
|
||||
if (candidate.getName().equals(name)) {
|
||||
return candidate;
|
||||
}
|
||||
@@ -296,11 +228,11 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
throw new AssertionError("Bad test specification, no method '" + name + "' found in test class");
|
||||
}
|
||||
|
||||
private void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
|
||||
protected void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
|
||||
assertParameterNames(method, pointcut, null, null, parameterNames);
|
||||
}
|
||||
|
||||
private void assertParameterNames(
|
||||
protected void assertParameterNames(
|
||||
Method method, String pointcut, String returning, String throwing, String[] parameterNames) {
|
||||
|
||||
assertThat(parameterNames.length).as("bad test specification, must have same number of parameter names as method arguments").isEqualTo(method.getParameterCount());
|
||||
@@ -311,8 +243,8 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
discoverer.setThrowingName(throwing);
|
||||
String[] discoveredNames = discoverer.getParameterNames(method);
|
||||
|
||||
String formattedExpectedNames = Arrays.toString(parameterNames);
|
||||
String formattedActualNames = Arrays.toString(discoveredNames);
|
||||
String formattedExpectedNames = format(parameterNames);
|
||||
String formattedActualNames = format(discoveredNames);
|
||||
|
||||
assertThat(discoveredNames.length).as("Expecting " + parameterNames.length + " parameter names in return set '" +
|
||||
formattedExpectedNames + "', but found " + discoveredNames.length +
|
||||
@@ -325,23 +257,37 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
|
||||
protected void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
|
||||
assertException(method, pointcut, null, null, exceptionType, message);
|
||||
}
|
||||
|
||||
private void assertException(Method method, String pointcut, String returning,
|
||||
protected void assertException(Method method, String pointcut, String returning,
|
||||
String throwing, Class<? extends Throwable> exceptionType, String message) {
|
||||
|
||||
AspectJAdviceParameterNameDiscoverer discoverer = new AspectJAdviceParameterNameDiscoverer(pointcut);
|
||||
discoverer.setRaiseExceptions(true);
|
||||
discoverer.setReturningName(returning);
|
||||
discoverer.setThrowingName(throwing);
|
||||
assertThatExceptionOfType(exceptionType)
|
||||
.isThrownBy(() -> discoverer.getParameterNames(method))
|
||||
assertThatExceptionOfType(exceptionType).isThrownBy(() ->
|
||||
discoverer.getParameterNames(method))
|
||||
.withMessageContaining(message);
|
||||
}
|
||||
|
||||
|
||||
private static String format(String[] names) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('(');
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
sb.append(names[i]);
|
||||
if ((i + 1) < names.length) {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// Methods to discover parameter names for
|
||||
|
||||
public void noArgs() {
|
||||
@@ -383,14 +329,4 @@ class AspectJAdviceParameterNameDiscovererTests {
|
||||
public void theBigOne(JoinPoint jp, Throwable x, int y, Object foo) {
|
||||
}
|
||||
|
||||
public void oneAnnotation(MyAnnotation ann) {}
|
||||
|
||||
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
|
||||
|
||||
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
|
||||
|
||||
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
|
||||
+1
-286
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 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,9 +17,6 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
@@ -28,8 +25,6 @@ import org.aspectj.weaver.tools.PointcutPrimitive;
|
||||
import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import test.annotation.EmptySpringAnnotation;
|
||||
import test.annotation.transaction.Tx;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
@@ -61,19 +56,12 @@ public class AspectJExpressionPointcutTests {
|
||||
|
||||
private Method setSomeNumber;
|
||||
|
||||
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
setAge = TestBean.class.getMethod("setAge", int.class);
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class);
|
||||
|
||||
// Assumes no overloading
|
||||
for (Method method : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,279 +299,6 @@ public class AspectJExpressionPointcutTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
// TODO this will currently map, would be nice for optimization
|
||||
//assertTrue(ajexp.matches(HasGeneric.class));
|
||||
//assertFalse(ajexp.matches(TestBean.class));
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchVarargs() throws Exception {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
class MyTemplate {
|
||||
public int queryForInt(String sql, Object... params) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
String expression = "execution(int *.*(String, Object...))";
|
||||
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
|
||||
jdbcVarArgs.setExpression(expression);
|
||||
|
||||
assertThat(jdbcVarArgs.matches(
|
||||
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
|
||||
MyTemplate.class)).isTrue();
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
|
||||
String expression = "@within(test.annotation.transaction.Tx)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
|
||||
String expression = "within(@test.annotation.transaction.Tx *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
|
||||
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation.transaction.*) *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithFQN() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnCglibProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(true);
|
||||
BeanA proxy = (BeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnDynamicProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(false);
|
||||
IBeanA proxy = (IBeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithWildcard() throws Exception {
|
||||
String expression = "execution(@(test.annotation..*) * *(..))";
|
||||
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
|
||||
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
// True because it maybeMatches with potential argument subtypes
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
|
||||
String expression = "execution(* *(*, @(test..*) *))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
}
|
||||
|
||||
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
public static class HasTransactionalAnnotation {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
public Object bar(String foo) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EmptySpringAnnotation
|
||||
public static class SpringAnnotated {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface IBeanA {
|
||||
|
||||
@Tx
|
||||
int getAge();
|
||||
}
|
||||
|
||||
|
||||
static class BeanA implements IBeanA {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Tx
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
static class BeanB {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
|
||||
|
||||
/**
|
||||
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer};
|
||||
* see supertype for remaining tests.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TigerAspectJAdviceParameterNameDiscovererTests extends AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void testAtThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousAnnotationOneVar() {
|
||||
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
|
||||
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationMedley() {
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
|
||||
|
||||
public void oneAnnotation(MyAnnotation ann) {}
|
||||
|
||||
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
|
||||
|
||||
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import test.annotation.EmptySpringAnnotation;
|
||||
import test.annotation.transaction.Tx;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Java 5 specific {@link AspectJExpressionPointcutTests}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
private Method getAge;
|
||||
|
||||
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
// Assumes no overloading
|
||||
for (Method method : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
// TODO this will currently map, would be nice for optimization
|
||||
//assertTrue(ajexp.matches(HasGeneric.class));
|
||||
//assertFalse(ajexp.matches(TestBean.class));
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchVarargs() throws Exception {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
class MyTemplate {
|
||||
public int queryForInt(String sql, Object... params) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
String expression = "execution(int *.*(String, Object...))";
|
||||
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
|
||||
jdbcVarArgs.setExpression(expression);
|
||||
|
||||
assertThat(jdbcVarArgs.matches(
|
||||
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
|
||||
MyTemplate.class)).isTrue();
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
|
||||
String expression = "@within(test.annotation.transaction.Tx)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
|
||||
String expression = "within(@test.annotation.transaction.Tx *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
|
||||
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation.transaction.*) *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithFQN() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnCglibProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(true);
|
||||
BeanA proxy = (BeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnDynamicProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(false);
|
||||
IBeanA proxy = (IBeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithWildcard() throws Exception {
|
||||
String expression = "execution(@(test.annotation..*) * *(..))";
|
||||
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
|
||||
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
// True because it maybeMatches with potential argument subtypes
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
|
||||
String expression = "execution(* *(*, @(test..*) *))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
}
|
||||
|
||||
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
public static class HasTransactionalAnnotation {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
public Object bar(String foo) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EmptySpringAnnotation
|
||||
public static class SpringAnnotated {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface IBeanA {
|
||||
|
||||
@Tx
|
||||
int getAge();
|
||||
}
|
||||
|
||||
|
||||
static class BeanA implements IBeanA {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Tx
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
static class BeanB {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.framework;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -133,4 +134,61 @@ public class AopProxyUtilsTests {
|
||||
AopProxyUtils.proxiedUserInterfaces(proxy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLambda() {
|
||||
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
|
||||
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
|
||||
|
||||
assertIsLambda(this.instanceLambdaExpression);
|
||||
assertIsLambda(this::instanceStringFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLambda() {
|
||||
assertIsNotLambda(new EnigmaSupplier());
|
||||
|
||||
assertIsNotLambda(new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return "anonymous inner class";
|
||||
}
|
||||
});
|
||||
|
||||
assertIsNotLambda(new Fake$$LambdaSupplier());
|
||||
}
|
||||
|
||||
private static void assertIsLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
|
||||
}
|
||||
|
||||
private static void assertIsNotLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
|
||||
}
|
||||
|
||||
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
|
||||
|
||||
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
|
||||
|
||||
private static String staticStringFactory() {
|
||||
return "static string factory";
|
||||
}
|
||||
|
||||
private String instanceStringFactory() {
|
||||
return "instance string factory";
|
||||
}
|
||||
|
||||
private static class EnigmaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "enigma";
|
||||
}
|
||||
}
|
||||
|
||||
private static class Fake$$LambdaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "fake lambda";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.testfixture.TimeStamped;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Also tests AdvisedSupport and ProxyCreatorSupport superclasses.
|
||||
@@ -277,7 +277,7 @@ public class ProxyFactoryTests {
|
||||
|
||||
assertThat(config.getAdvisors().length == oldCount).isTrue();
|
||||
|
||||
assertThatRuntimeException()
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.as("Existing object won't implement this interface any more")
|
||||
.isThrownBy(ts::getTimeStamp); // Existing reference will fail
|
||||
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.aop.testfixture.advice.MyThrowsHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -64,7 +63,9 @@ public class ThrowsAdviceInterceptorTests {
|
||||
Exception ex = new Exception();
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
assertThatException().isThrownBy(() -> ti.invoke(mi)).isSameAs(ex);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
ti.invoke(mi))
|
||||
.isSameAs(ex);
|
||||
assertThat(th.getCalls()).isEqualTo(0);
|
||||
}
|
||||
|
||||
|
||||
+13
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
@@ -106,44 +104,44 @@ public class TransactionAspectTests {
|
||||
@Test
|
||||
public void defaultCommitOnAnnotatedClass() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRollbackOnAnnotatedClass() throws Throwable {
|
||||
RuntimeException ex = new RuntimeException();
|
||||
assertThatRuntimeException()
|
||||
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
|
||||
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
|
||||
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
final Exception ex = new Exception();
|
||||
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(ex), ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
Exception rollbackProvokingException = new RuntimeException();
|
||||
final Exception rollbackProvokingException = new RuntimeException();
|
||||
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(rollbackProvokingException),
|
||||
rollbackProvokingException);
|
||||
}
|
||||
@@ -167,9 +165,8 @@ public class TransactionAspectTests {
|
||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||
txManager.clear();
|
||||
assertThat(txManager.begun).isEqualTo(0);
|
||||
assertThatExceptionOfType(Throwable.class)
|
||||
.isThrownBy(toc::performTransactionalOperation)
|
||||
.isSameAs(expected);
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(
|
||||
toc::performTransactionalOperation).isSameAs(expected);
|
||||
assertThat(txManager.begun).isEqualTo(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -691,25 +691,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects.
|
||||
* <p>The following table provides a non-exhaustive set of examples of source
|
||||
* and target property types that can be copied as well as source and target
|
||||
* property types that cannot be copied.
|
||||
* <table border="1">
|
||||
* <tr><th>source property type</th><th>target property type</th><th>copy supported</th></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Integer}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Number}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Integer>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<?>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<? extends Number>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code String}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code Number}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Long>}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Number>}</td><td>no</td></tr>
|
||||
* </table>
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @throws BeansException if the copying failed
|
||||
@@ -726,10 +708,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
@@ -747,10 +726,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param ignoreProperties array of property names to ignore
|
||||
@@ -767,8 +743,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* when matching properties in the source and target objects.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
|
||||
+7
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,8 +22,6 @@ import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -288,17 +286,9 @@ public final class CachedIntrospectionResults {
|
||||
// This call is slow so we do it once.
|
||||
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (Class.class == beanClass && !("name".equals(pd.getName()) ||
|
||||
(pd.getName().endsWith("Name") && String.class == pd.getPropertyType()))) {
|
||||
// Only allow all name variants of Class properties
|
||||
continue;
|
||||
}
|
||||
if (URL.class == beanClass && "content".equals(pd.getName())) {
|
||||
// Only allow URL attribute introspection, not content resolution
|
||||
continue;
|
||||
}
|
||||
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
|
||||
// Ignore read-only properties such as ClassLoader - no need to bind to those
|
||||
if (Class.class == beanClass &&
|
||||
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
|
||||
// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those
|
||||
continue;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
@@ -347,10 +337,6 @@ public final class CachedIntrospectionResults {
|
||||
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
|
||||
// against a declared read method, so we prefer read method descriptors here.
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
|
||||
// Ignore read-only properties such as ClassLoader - no need to bind to those
|
||||
continue;
|
||||
}
|
||||
this.propertyDescriptors.put(pd.getName(), pd);
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
@@ -368,7 +354,7 @@ public final class CachedIntrospectionResults {
|
||||
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (!this.propertyDescriptors.containsKey(method.getName()) &&
|
||||
!readMethodNames.contains(method.getName()) && isPlainAccessor(method)) {
|
||||
!readMethodNames.contains((method.getName())) && isPlainAccessor(method)) {
|
||||
this.propertyDescriptors.put(method.getName(),
|
||||
new GenericTypeAwarePropertyDescriptor(beanClass, method.getName(), method, null, null));
|
||||
readMethodNames.add(method.getName());
|
||||
@@ -377,10 +363,8 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
|
||||
private boolean isPlainAccessor(Method method) {
|
||||
if (Modifier.isStatic(method.getModifiers()) ||
|
||||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
|
||||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
isInvalidReadOnlyPropertyType(method.getReturnType())) {
|
||||
if (method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -393,12 +377,6 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
|
||||
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
|
||||
ClassLoader.class.isAssignableFrom(returnType) ||
|
||||
ProtectionDomain.class.isAssignableFrom(returnType)));
|
||||
}
|
||||
|
||||
|
||||
BeanInfo getBeanInfo() {
|
||||
return this.beanInfo;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,9 +23,8 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Common interface for classes that can access named properties
|
||||
* (such as bean properties of an object or fields in an object).
|
||||
*
|
||||
* <p>Serves as base interface for {@link BeanWrapper}.
|
||||
* (such as bean properties of an object or fields in an object)
|
||||
* Serves as base interface for {@link BeanWrapper}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support package for beans-style handling of annotations.
|
||||
* Support package for beans-style handling of Java 5 annotations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
* that enforces required JavaBean properties to have been configured.
|
||||
* Required bean properties are detected through an annotation:
|
||||
* Required bean properties are detected through a Java 5 annotation:
|
||||
* by default, Spring's {@link Required} annotation.
|
||||
*
|
||||
* <p>The motivation for the existence of this BeanPostProcessor is to allow
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,8 +20,8 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving a value by evaluating it as an expression,
|
||||
* if applicable.
|
||||
* Strategy interface for resolving a value through evaluating it
|
||||
* as an expression, if applicable.
|
||||
*
|
||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||
* contain a default implementation of this strategy. However,
|
||||
@@ -36,13 +36,12 @@ public interface BeanExpressionResolver {
|
||||
/**
|
||||
* Evaluate the given value as an expression, if applicable;
|
||||
* return the value as-is otherwise.
|
||||
* @param value the value to evaluate as an expression
|
||||
* @param beanExpressionContext the bean expression context to use when
|
||||
* evaluating the expression
|
||||
* @param value the value to check
|
||||
* @param evalContext the evaluation context
|
||||
* @return the resolved value (potentially the given value as-is)
|
||||
* @throws BeansException if evaluation failed
|
||||
*/
|
||||
@Nullable
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException;
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException;
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support package for the Java {@link java.util.ServiceLoader} facility.
|
||||
* Support package for the Java 6 ServiceLoader facility.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+2
-2
@@ -1844,7 +1844,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
@@ -1868,7 +1868,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
String initMethodName = mbd.getInitMethodName();
|
||||
if (StringUtils.hasLength(initMethodName) &&
|
||||
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
|
||||
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
|
||||
!mbd.isExternallyManagedInitMethod(initMethodName)) {
|
||||
invokeCustomInitMethod(beanName, bean, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -985,7 +985,7 @@ class ConstructorResolver {
|
||||
|
||||
|
||||
/**
|
||||
* Delegate for checking Java's {@link ConstructorProperties} annotation.
|
||||
* Delegate for checking Java 6's {@link ConstructorProperties} annotation.
|
||||
*/
|
||||
private static class ConstructorPropertiesChecker {
|
||||
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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,9 +585,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (!matchFound) {
|
||||
// In case of FactoryBean, try to match FactoryBean instance itself next.
|
||||
beanName = FACTORY_BEAN_PREFIX + beanName;
|
||||
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
|
||||
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
|
||||
}
|
||||
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
|
||||
}
|
||||
}
|
||||
if (matchFound) {
|
||||
|
||||
+2
-3
@@ -52,7 +52,6 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see AbstractBeanFactory
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
@@ -110,12 +109,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
this.beanName = beanName;
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.invokeDisposableBean = (bean instanceof DisposableBean &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null &&
|
||||
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
||||
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
|
||||
if (!this.invokeAutoCloseable) {
|
||||
|
||||
+5
-7
@@ -17,7 +17,7 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
@@ -31,8 +31,6 @@ import org.springframework.lang.Nullable;
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 27.05.2003
|
||||
* @param <E> the element type
|
||||
*/
|
||||
@@ -57,16 +55,16 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance containing an arbitrary number of elements.
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the list
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @return a {@code ManagedList} containing the specified elements
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E> ManagedList<E> of(E... elements) {
|
||||
ManagedList<E> list = new ManagedList<>();
|
||||
Collections.addAll(list, elements);
|
||||
list.addAll(Arrays.asList(elements));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K,V> ManagedMap<K,V> ofEntries(Entry<? extends K, ? extends V>... entries) {
|
||||
ManagedMap<K,V > map = new ManagedMap<>();
|
||||
|
||||
+5
-7
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -30,8 +30,6 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 21.01.2004
|
||||
* @param <E> the element type
|
||||
*/
|
||||
@@ -56,16 +54,16 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance containing an arbitrary number of elements.
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the set
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @return a {@code ManagedSet} containing the specified elements
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E> ManagedSet<E> of(E... elements) {
|
||||
ManagedSet<E> set = new ManagedSet<>();
|
||||
Collections.addAll(set, elements);
|
||||
set.addAll(Arrays.asList(elements));
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
+8
-95
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -49,7 +49,6 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see GenericBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
@@ -437,7 +436,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method or field is an externally managed configuration member.
|
||||
* Check whether the given method or field is an externally managed configuration member.
|
||||
*/
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -447,7 +446,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed configuration methods and fields (as an immutable Set).
|
||||
* Return all externally managed configuration methods and fields (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<Member> getExternallyManagedConfigMembers() {
|
||||
@@ -459,15 +458,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration initialization method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PostConstruct} annotation.
|
||||
* <p>The supplied {@code initMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
* Register an externally managed configuration initialization method.
|
||||
*/
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -479,10 +470,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method.
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the supplied {@code initMethod}.
|
||||
* Check whether the given method name indicates an externally managed initialization method.
|
||||
*/
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -491,40 +479,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedInitMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed initialization method that has been
|
||||
* {@linkplain #registerExternallyManagedInitMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedInitMethod(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedInitMethods != null) {
|
||||
for (String candidate : this.externallyManagedInitMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed initialization methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the initialization methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedInitMethods() {
|
||||
@@ -536,15 +492,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration destruction method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PreDestroy} annotation.
|
||||
* <p>The supplied {@code destroyMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
* Register an externally managed configuration destruction method.
|
||||
*/
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -556,10 +504,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method.
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the supplied {@code destroyMethod}.
|
||||
* Check whether the given method name indicates an externally managed destruction method.
|
||||
*/
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -569,39 +514,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedDestroyMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed destruction method that has been
|
||||
* {@linkplain #registerExternallyManagedDestroyMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedDestroyMethod(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedDestroyMethods != null) {
|
||||
for (String candidate : this.externallyManagedDestroyMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed destruction methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the destruction methods in the returned set.
|
||||
* Return all externally managed destruction methods (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedDestroyMethods() {
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -43,7 +43,6 @@ import org.springframework.core.io.ContextResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceEditor;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.WritableResource;
|
||||
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
@@ -103,7 +102,6 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
|
||||
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
|
||||
doRegisterEditor(registry, Resource.class, baseEditor);
|
||||
doRegisterEditor(registry, ContextResource.class, baseEditor);
|
||||
doRegisterEditor(registry, WritableResource.class, baseEditor);
|
||||
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
|
||||
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
|
||||
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,7 @@ inline fun <reified T : Any> ListableBeanFactory.getBeansOfType(includeNonSingle
|
||||
|
||||
/**
|
||||
* Extension for [ListableBeanFactory.getBeanNamesForAnnotation] providing a
|
||||
* `getBeanNamesForAnnotation<Foo>()` variant.
|
||||
* `getBeansOfType<Foo>()` variant.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
@@ -64,6 +64,6 @@ inline fun <reified T : Annotation> ListableBeanFactory.getBeansWithAnnotation()
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): T? =
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): Annotation? =
|
||||
findAnnotationOnBean(beanName, T::class.java)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -203,25 +203,8 @@ class BeanUtilsTests {
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Integer} can be copied to {@code Number}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesFromSubTypeToSuperType() {
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
integerHolder.setNumber(42);
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerHolder, numberHolder);
|
||||
assertThat(integerHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<Integer>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToInteger() {
|
||||
void copyPropertiesHonorsGenericTypeMatches() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
IntegerListHolder2 integerListHolder2 = new IntegerListHolder2();
|
||||
@@ -231,68 +214,6 @@ class BeanUtilsTests {
|
||||
assertThat(integerListHolder2.getList()).containsOnly(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<?>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromWildcardToWildcard() {
|
||||
List<?> list = Arrays.asList("foo", 42);
|
||||
WildcardListHolder1 wildcardListHolder1 = new WildcardListHolder1();
|
||||
wildcardListHolder1.setList(list);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
assertThat(wildcardListHolder2.getList()).isEmpty();
|
||||
|
||||
BeanUtils.copyProperties(wildcardListHolder1, wildcardListHolder2);
|
||||
assertThat(wildcardListHolder1.getList()).isEqualTo(list);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, wildcardListHolder2);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(Arrays.asList(42));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<? extends Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesForUpperBoundedWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
NumberUpperBoundedWildcardListHolder numberListHolder = new NumberUpperBoundedWildcardListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, numberListHolder);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).hasSize(1);
|
||||
assertThat(numberListHolder.getList().contains(Integer.valueOf(42))).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Number} can NOT be copied to {@code Integer}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotCopyeFromSuperTypeToSubType() {
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
numberHolder.setNumber(Integer.valueOf(42));
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
|
||||
BeanUtils.copyProperties(numberHolder, integerHolder);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(integerHolder.getNumber()).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Long>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatches() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
@@ -304,20 +225,6 @@ class BeanUtilsTests {
|
||||
assertThat(longListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatchesFromSubTypeToSuperType() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
integerListHolder.getList().add(42);
|
||||
NumberListHolder numberListHolder = new NumberListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder, numberListHolder);
|
||||
assertThat(integerListHolder.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
@Test // gh-26531
|
||||
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() throws Exception {
|
||||
Order original = new Order("test", Arrays.asList("foo", "bar"));
|
||||
@@ -506,90 +413,6 @@ class BeanUtilsTests {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberHolder {
|
||||
|
||||
private Number number;
|
||||
|
||||
public Number getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Number number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerHolder {
|
||||
|
||||
private Integer number;
|
||||
|
||||
public Integer getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Integer number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder1 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder2 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberUpperBoundedWildcardListHolder {
|
||||
|
||||
private List<? extends Number> list = new ArrayList<>();
|
||||
|
||||
public List<? extends Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<? extends Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberListHolder {
|
||||
|
||||
private List<Number> list = new ArrayList<>();
|
||||
|
||||
public List<Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerListHolder1 {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,9 +23,6 @@ import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
@@ -108,7 +105,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
.satisfies(ex -> assertThat(ex.getPossibleMatches()).containsExactly("age"));
|
||||
}
|
||||
|
||||
@Test // Can't be shared; there is no such thing as a read-only field
|
||||
@Test // Can't be shared; there is no such thing as a read-only field
|
||||
void setReadOnlyMapProperty() {
|
||||
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
|
||||
TypedReadOnlyMapClient target = new TypedReadOnlyMapClient();
|
||||
@@ -154,58 +151,18 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyDescriptors() throws Exception {
|
||||
void propertyDescriptors() {
|
||||
TestBean target = new TestBean();
|
||||
target.setSpouse(new TestBean());
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("name", "a");
|
||||
accessor.setPropertyValue("spouse.name", "b");
|
||||
|
||||
assertThat(target.getName()).isEqualTo("a");
|
||||
assertThat(target.getSpouse().getName()).isEqualTo("b");
|
||||
assertThat(accessor.getPropertyValue("name")).isEqualTo("a");
|
||||
assertThat(accessor.getPropertyValue("spouse.name")).isEqualTo("b");
|
||||
assertThat(accessor.getPropertyDescriptor("name").getPropertyType()).isEqualTo(String.class);
|
||||
assertThat(accessor.getPropertyDescriptor("spouse.name").getPropertyType()).isEqualTo(String.class);
|
||||
|
||||
assertThat(accessor.isReadableProperty("class.package")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.module")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.name")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
|
||||
assertThat(accessor.getPropertyValue("class.name")).isEqualTo(TestBean.class.getName());
|
||||
assertThat(accessor.getPropertyValue("class.simpleName")).isEqualTo(TestBean.class.getSimpleName());
|
||||
assertThat(accessor.getPropertyDescriptor("class.name").getPropertyType()).isEqualTo(String.class);
|
||||
assertThat(accessor.getPropertyDescriptor("class.simpleName").getPropertyType()).isEqualTo(String.class);
|
||||
|
||||
accessor = createAccessor(new DefaultResourceLoader());
|
||||
|
||||
assertThat(accessor.isReadableProperty("class.package")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.module")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.name")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("classLoader")).isTrue();
|
||||
assertThat(accessor.isWritableProperty("classLoader")).isTrue();
|
||||
OverridingClassLoader ocl = new OverridingClassLoader(getClass().getClassLoader());
|
||||
accessor.setPropertyValue("classLoader", ocl);
|
||||
assertThat(accessor.getPropertyValue("classLoader")).isSameAs(ocl);
|
||||
|
||||
accessor = createAccessor(new UrlResource("https://spring.io"));
|
||||
|
||||
assertThat(accessor.isReadableProperty("class.package")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.module")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("class.name")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("URL.protocol")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("URL.host")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("URL.port")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("URL.file")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("URL.content")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
|
||||
assertThat(accessor.isReadableProperty("filename")).isTrue();
|
||||
assertThat(accessor.isReadableProperty("description")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+107
-90
@@ -26,6 +26,7 @@ import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -94,7 +95,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
@@ -178,8 +178,10 @@ class DefaultListableBeanFactoryTests {
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
|
||||
assertBeanNamesForType(TestBean.class, false, false);
|
||||
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
@@ -210,8 +212,10 @@ class DefaultListableBeanFactoryTests {
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
|
||||
assertBeanNamesForType(TestBean.class, false, false);
|
||||
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
@@ -241,8 +245,10 @@ class DefaultListableBeanFactoryTests {
|
||||
registerBeanDefinitions(p);
|
||||
|
||||
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
|
||||
assertBeanNamesForType(TestBean.class, false, false);
|
||||
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
|
||||
assertThat(beanNames).hasSize(0);
|
||||
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
@@ -272,8 +278,10 @@ class DefaultListableBeanFactoryTests {
|
||||
registerBeanDefinitions(p);
|
||||
lbf.preInstantiateSingletons();
|
||||
|
||||
assertThat(DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isFalse();
|
||||
assertBeanNamesForType(TestBean.class, true, false, "x1");
|
||||
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(1);
|
||||
assertThat(beanNames[0]).isEqualTo("x1");
|
||||
assertThat(lbf.containsSingleton("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("&x1")).isTrue();
|
||||
@@ -308,10 +316,14 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(lbf.isTypeMatch("&x2", Object.class)).isTrue();
|
||||
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
|
||||
assertThat(lbf.getType("&x2")).isEqualTo(DummyFactory.class);
|
||||
assertThat(lbf.getAliases("x1")).containsExactly("x2");
|
||||
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
|
||||
assertThat(lbf.getAliases("x2")).containsExactly("x1");
|
||||
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
|
||||
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
|
||||
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
|
||||
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
|
||||
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -321,7 +333,9 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("x1", rbd);
|
||||
|
||||
TestBeanFactory.initialized = false;
|
||||
assertBeanNamesForType(TestBean.class, true, false, "x1");
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(1);
|
||||
assertThat(beanNames[0]).isEqualTo("x1");
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("&x1")).isFalse();
|
||||
@@ -344,7 +358,9 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("x1", rbd);
|
||||
|
||||
TestBeanFactory.initialized = false;
|
||||
assertBeanNamesForType(TestBean.class, true, false, "x1");
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(1);
|
||||
assertThat(beanNames[0]).isEqualTo("x1");
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("&x1")).isFalse();
|
||||
@@ -369,7 +385,9 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("x1", rbd);
|
||||
|
||||
TestBeanFactory.initialized = false;
|
||||
assertBeanNamesForType(TestBean.class, true, false, "x1");
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(1);
|
||||
assertThat(beanNames[0]).isEqualTo("x1");
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("&x1")).isFalse();
|
||||
@@ -395,7 +413,9 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("x1", rbd);
|
||||
|
||||
TestBeanFactory.initialized = false;
|
||||
assertBeanNamesForType(TestBean.class, true, false, "x1");
|
||||
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
|
||||
assertThat(beanNames).hasSize(1);
|
||||
assertThat(beanNames[0]).isEqualTo("x1");
|
||||
assertThat(lbf.containsSingleton("x1")).isFalse();
|
||||
assertThat(lbf.containsBean("x1")).isTrue();
|
||||
assertThat(lbf.containsBean("&x1")).isFalse();
|
||||
@@ -428,10 +448,14 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(lbf.isTypeMatch("&x2", Object.class)).isFalse();
|
||||
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
|
||||
assertThat(lbf.getType("&x2")).isNull();
|
||||
assertThat(lbf.getAliases("x1")).containsExactly("x2");
|
||||
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
|
||||
assertThat(lbf.getAliases("x2")).containsExactly("x1");
|
||||
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
|
||||
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
|
||||
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
|
||||
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
|
||||
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
|
||||
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -595,7 +619,8 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerSingleton("string", "A");
|
||||
|
||||
TestBean self = (TestBean) lbf.getBean("self");
|
||||
assertThat(self.getStringArray()).containsExactly("A");
|
||||
assertThat(self.getStringArray()).hasSize(1);
|
||||
assertThat(self.getStringArray()).contains("A");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -608,7 +633,8 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerSingleton("string", "A");
|
||||
|
||||
TestBean self = (TestBean) lbf.getBean("self");
|
||||
assertThat(self.getStringArray()).containsExactly("A");
|
||||
assertThat(self.getStringArray()).hasSize(1);
|
||||
assertThat(self.getStringArray()).contains("A");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -640,7 +666,8 @@ class DefaultListableBeanFactoryTests {
|
||||
.withCauseInstanceOf(NotWritablePropertyException.class)
|
||||
.satisfies(ex -> {
|
||||
NotWritablePropertyException cause = (NotWritablePropertyException) ex.getCause();
|
||||
assertThat(cause.getPossibleMatches()).containsExactly("age");
|
||||
assertThat(cause.getPossibleMatches()).hasSize(1);
|
||||
assertThat(cause.getPossibleMatches()[0]).isEqualTo("age");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -658,7 +685,7 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf = new DefaultListableBeanFactory();
|
||||
p = new Properties();
|
||||
p.setProperty("kerry.(class)", TestBean.class.getName());
|
||||
p.setProperty("kerry.(scope)", BeanDefinition.SCOPE_PROTOTYPE);
|
||||
p.setProperty("kerry.(scope)", "prototype");
|
||||
p.setProperty("kerry.age", "35");
|
||||
registerBeanDefinitions(p);
|
||||
kerry1 = (TestBean) lbf.getBean("kerry");
|
||||
@@ -1118,7 +1145,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(lbf.containsBean("singletonObject")).isTrue();
|
||||
assertThat(lbf.isSingleton("singletonObject")).isTrue();
|
||||
assertThat(lbf.getType("singletonObject")).isEqualTo(TestBean.class);
|
||||
assertThat(lbf.getAliases("singletonObject")).isEmpty();
|
||||
assertThat(lbf.getAliases("singletonObject").length).isEqualTo(0);
|
||||
DependenciesBean test = (DependenciesBean) lbf.getBean("test");
|
||||
assertThat(lbf.getBean("singletonObject")).isEqualTo(singletonObject);
|
||||
assertThat(test.getSpouse()).isEqualTo(singletonObject);
|
||||
@@ -1764,12 +1791,12 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(bean.beanName).isEqualTo("bd1");
|
||||
assertThat(bean.spouseAge).isEqualTo(42);
|
||||
|
||||
assertThat(lbf.getBeanNamesForType(ConstructorDependency.class)).hasSize(1);
|
||||
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class)).hasSize(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class))).hasSize(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class))).isEmpty();
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true)).hasSize(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true)).isEmpty();
|
||||
assertThat(lbf.getBeanNamesForType(ConstructorDependency.class).length).isEqualTo(1);
|
||||
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class).length).isEqualTo(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)).length).isEqualTo(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)).length).isEqualTo(0);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true).length).isEqualTo(1);
|
||||
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true).length).isEqualTo(0);
|
||||
}
|
||||
|
||||
private RootBeanDefinition createConstructorDependencyBeanDefinition(int age) {
|
||||
@@ -1834,45 +1861,46 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void getBeanNamesForTypeBeforeFactoryBeanCreation() {
|
||||
FactoryBeanThatShouldntBeCalled.instantiated = false;
|
||||
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
|
||||
assertThat(lbf.containsSingleton("factoryBean")).isFalse();
|
||||
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isFalse();
|
||||
|
||||
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
|
||||
String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanNamesForTypeAfterFactoryBeanCreation() {
|
||||
FactoryBeanThatShouldntBeCalled.instantiated = false;
|
||||
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
|
||||
lbf.getBean("&factoryBean");
|
||||
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isTrue();
|
||||
assertThat(lbf.containsSingleton("factoryBean")).isTrue();
|
||||
|
||||
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
|
||||
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
|
||||
}
|
||||
String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
@Test // gh-28616
|
||||
void getBeanNamesForTypeWithPrototypeScopedFactoryBean() {
|
||||
FactoryBeanThatShouldntBeCalled.instantiated = false;
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class);
|
||||
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
lbf.registerBeanDefinition("factoryBean", beanDefinition);
|
||||
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isFalse();
|
||||
assertThat(lbf.containsSingleton("factoryBean")).isFalse();
|
||||
beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
// We should not find any beans of the following types if the FactoryBean itself is prototype-scoped.
|
||||
assertBeanNamesForType(Runnable.class, false, false);
|
||||
assertBeanNamesForType(Callable.class, false, false);
|
||||
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false);
|
||||
assertBeanNamesForType(FactoryBean.class, false, false);
|
||||
beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
|
||||
beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
|
||||
assertThat(beanNames.length).isEqualTo(1);
|
||||
assertThat(beanNames[0]).isEqualTo("&factoryBean");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2137,7 +2165,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
|
||||
lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2145,7 +2174,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
|
||||
lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2153,7 +2183,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
|
||||
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> lbf.getBeansOfType(String.class));
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
|
||||
lbf.getBeansOfType(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2180,7 +2211,8 @@ class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
|
||||
lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2204,13 +2236,7 @@ class DefaultListableBeanFactoryTests {
|
||||
@Test
|
||||
void prototypeFactoryBeanNotEagerlyCalled() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
|
||||
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
|
||||
}
|
||||
|
||||
@Test
|
||||
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
|
||||
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
|
||||
lbf.preInstantiateSingletons();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2250,6 +2276,13 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(factory.initialized).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
|
||||
lbf.registerBeanDefinition("test",
|
||||
new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
|
||||
lbf.preInstantiateSingletons();
|
||||
}
|
||||
|
||||
@Test
|
||||
void prototypeStringCreatedRepeatedly() {
|
||||
RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
|
||||
@@ -2429,7 +2462,10 @@ class DefaultListableBeanFactoryTests {
|
||||
lbf.registerBeanDefinition("fmWithArgs", factoryMethodDefinitionWithArgs);
|
||||
|
||||
assertThat(lbf.getBeanDefinitionCount()).isEqualTo(4);
|
||||
assertBeanNamesForType(TestBean.class, true, true, "fmWithProperties", "fmWithArgs");
|
||||
List<String> tbNames = Arrays.asList(lbf.getBeanNamesForType(TestBean.class));
|
||||
assertThat(tbNames.contains("fmWithProperties")).isTrue();
|
||||
assertThat(tbNames.contains("fmWithArgs")).isTrue();
|
||||
assertThat(tbNames.size()).isEqualTo(2);
|
||||
|
||||
TestBean tb = (TestBean) lbf.getBean("fmWithProperties");
|
||||
TestBean second = (TestBean) lbf.getBean("fmWithProperties");
|
||||
@@ -2633,19 +2669,6 @@ class DefaultListableBeanFactoryTests {
|
||||
return (new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, prefix);
|
||||
}
|
||||
|
||||
private void assertBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit, String... names) {
|
||||
if (names.length == 0) {
|
||||
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
|
||||
.as("bean names for type " + type.getName())
|
||||
.isEmpty();
|
||||
}
|
||||
else {
|
||||
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
|
||||
.as("bean names for type " + type.getName())
|
||||
.containsExactly(names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class NoDependencies {
|
||||
|
||||
@@ -2836,12 +2859,6 @@ class DefaultListableBeanFactoryTests {
|
||||
public static class FactoryBeanThatShouldntBeCalled<T extends Repository<S, ID>, S, ID extends Serializable>
|
||||
extends RepositoryFactoryBeanSupport<T, S, ID> implements Runnable, Callable<T> {
|
||||
|
||||
static boolean instantiated = false;
|
||||
|
||||
{
|
||||
instantiated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getObject() {
|
||||
throw new IllegalStateException();
|
||||
|
||||
+14
-14
@@ -25,61 +25,61 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ManagedList}.
|
||||
*
|
||||
* @author Rick Evans
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
class ManagedListTests {
|
||||
public class ManagedListTests {
|
||||
|
||||
@Test
|
||||
void mergeSunnyDay() {
|
||||
public void mergeSunnyDay() {
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = ManagedList.of("three");
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two", "three");
|
||||
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeWithNullParent() {
|
||||
public void mergeWithNullParent() {
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThat(child.merge(null)).isSameAs(child);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeNotAllowedWhenMergeNotEnabled() {
|
||||
public void mergeNotAllowedWhenMergeNotEnabled() {
|
||||
ManagedList child = new ManagedList();
|
||||
assertThatIllegalStateException().isThrownBy(() -> child.merge(null));
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
child.merge(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeWithIncompatibleParentType() {
|
||||
public void mergeWithNonCompatibleParentType() {
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> child.merge("hello"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
child.merge("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeEmptyChild() {
|
||||
public void mergeEmptyChild() {
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = new ManagedList();
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two");
|
||||
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergedChildValuesDoNotOverrideTheParents() {
|
||||
public void mergeChildValuesOverrideTheParents() {
|
||||
// doesn't make much sense in the context of a list...
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
assertThat(mergedList).as("merge() obviously did not work.").containsExactly("one", "two", "one");
|
||||
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-15
@@ -25,62 +25,61 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ManagedSet}.
|
||||
*
|
||||
* @author Rick Evans
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
class ManagedSetTests {
|
||||
public class ManagedSetTests {
|
||||
|
||||
@Test
|
||||
void mergeSunnyDay() {
|
||||
public void mergeSunnyDay() {
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = ManagedSet.of("three");
|
||||
child.add("three");
|
||||
child.add("four");
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
assertThat(mergedSet).as("merge() obviously did not work.").containsExactly("one", "two", "three", "four");
|
||||
assertThat(mergedSet.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeWithNullParent() {
|
||||
public void mergeWithNullParent() {
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThat(child.merge(null)).isSameAs(child);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeNotAllowedWhenMergeNotEnabled() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new ManagedSet().merge(null));
|
||||
public void mergeNotAllowedWhenMergeNotEnabled() {
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
new ManagedSet().merge(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeWithNonCompatibleParentType() {
|
||||
public void mergeWithNonCompatibleParentType() {
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> child.merge("hello"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
child.merge("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeEmptyChild() {
|
||||
public void mergeEmptyChild() {
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = new ManagedSet();
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
assertThat(mergedSet).as("merge() obviously did not work.").containsExactly("one", "two");
|
||||
assertThat(mergedSet.size()).as("merge() obviously did not work.").isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergeChildValuesOverrideTheParents() {
|
||||
public void mergeChildValuesOverrideTheParents() {
|
||||
// asserts that the set contract is not violated during a merge() operation...
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
assertThat(mergedSet).as("merge() obviously did not work.").containsExactly("one", "two");
|
||||
assertThat(mergedSet.size()).as("merge() obviously did not work.").isEqualTo(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-3
@@ -58,7 +58,6 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.testfixture.security.TestPrincipal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
@@ -304,14 +303,14 @@ public class CallbacksSecurityTests {
|
||||
Method method = bean.getClass().getMethod("destroy");
|
||||
method.setAccessible(true);
|
||||
|
||||
assertThatException().isThrownBy(() ->
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
method.invoke(bean);
|
||||
return null;
|
||||
}, acc));
|
||||
|
||||
Class<ConstructorBean> cl = ConstructorBean.class;
|
||||
assertThatException().isThrownBy(() ->
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
cl.newInstance(), acc));
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,8 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
|
||||
/**
|
||||
* With Spring 3.1, bean id attributes (and all other id attributes across the
|
||||
@@ -39,23 +40,22 @@ import static org.assertj.core.api.Assertions.assertThatException;
|
||||
* @see org.springframework.beans.factory.xml.XmlBeanFactoryTests#withDuplicateName
|
||||
* @see org.springframework.beans.factory.xml.XmlBeanFactoryTests#withDuplicateNameInAlias
|
||||
*/
|
||||
class DuplicateBeanIdTests {
|
||||
public class DuplicateBeanIdTests {
|
||||
|
||||
@Test
|
||||
void duplicateBeanIdsWithinSameNestingLevelRaisesError() {
|
||||
public void duplicateBeanIdsWithinSameNestingLevelRaisesError() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
|
||||
assertThatException().as("duplicate ids in same nesting level").isThrownBy(() ->
|
||||
assertThatExceptionOfType(Exception.class).as("duplicate ids in same nesting level").isThrownBy(() ->
|
||||
reader.loadBeanDefinitions(new ClassPathResource("DuplicateBeanIdTests-sameLevel-context.xml", this.getClass())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void duplicateBeanIdsAcrossNestingLevels() {
|
||||
public void duplicateBeanIdsAcrossNestingLevels() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
|
||||
reader.loadBeanDefinitions(new ClassPathResource("DuplicateBeanIdTests-multiLevel-context.xml", this.getClass()));
|
||||
TestBean testBean = bf.getBean(TestBean.class); // there should be only one
|
||||
assertThat(testBean.getName()).isEqualTo("nested");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-5
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.springframework.beans.factory
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
/**
|
||||
* Mock object based tests for ListableBeanFactory Kotlin extensions
|
||||
@@ -79,12 +77,10 @@ class ListableBeanFactoryExtensionsTests {
|
||||
verify { lbf.getBeansWithAnnotation(Bar::class.java) }
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
@Test
|
||||
fun `findAnnotationOnBean with String and reified type parameters`() {
|
||||
val name = "bar"
|
||||
every { lbf.findAnnotationOnBean(name, Bar::class.java) } returns Bar::class.createInstance()
|
||||
val annotation: Bar? = lbf.findAnnotationOnBean(name)
|
||||
lbf.findAnnotationOnBean<Bar>(name)
|
||||
verify { lbf.findAnnotationOnBean(name, Bar::class.java) }
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,6 @@ import javax.lang.model.element.Element;
|
||||
|
||||
/**
|
||||
* Provide the list of stereotypes that match an {@link Element}.
|
||||
*
|
||||
* <p>If an element has one or more stereotypes, it is referenced in the index
|
||||
* of candidate components and each stereotype can be queried individually.
|
||||
*
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.contextsupport.testfixture.jcache.JCacheableService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
@@ -86,8 +86,8 @@ public class JCacheCustomInterceptorTests {
|
||||
|
||||
@Test
|
||||
public void customInterceptorAppliesWithCheckedException() {
|
||||
assertThatRuntimeException()
|
||||
.isThrownBy(() -> cs.cacheWithCheckedException("id", true))
|
||||
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
|
||||
cs.cacheWithCheckedException("id", true))
|
||||
.withCauseExactlyInstanceOf(IOException.class);
|
||||
}
|
||||
|
||||
|
||||
+28
-90
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 @@ import java.util.Set;
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.ConstraintValidatorFactory;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Payload;
|
||||
import javax.validation.Valid;
|
||||
@@ -44,7 +43,6 @@ import org.hibernate.validator.HibernateValidatorFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
@@ -54,18 +52,18 @@ import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
class ValidatorFactoryTests {
|
||||
@SuppressWarnings("resource")
|
||||
public class ValidatorFactoryTests {
|
||||
|
||||
@Test
|
||||
void simpleValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
@SuppressWarnings("cast")
|
||||
public void testSimpleValidation() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -80,15 +78,15 @@ class ValidatorFactoryTests {
|
||||
|
||||
Validator nativeValidator = validator.unwrap(Validator.class);
|
||||
assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleValidationWithCustomProvider() {
|
||||
@SuppressWarnings("resource")
|
||||
@SuppressWarnings("cast")
|
||||
public void testSimpleValidationWithCustomProvider() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setProviderClass(HibernateValidator.class);
|
||||
validator.afterPropertiesSet();
|
||||
@@ -104,15 +102,14 @@ class ValidatorFactoryTests {
|
||||
|
||||
Validator nativeValidator = validator.unwrap(Validator.class);
|
||||
assertThat(nativeValidator.getClass().getName().startsWith("org.hibernate")).isTrue();
|
||||
assertThat(validator.unwrap(ValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class)).isInstanceOf(HibernateValidatorFactory.class);
|
||||
assertThat(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
assertThat(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleValidationWithClassLevel() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSimpleValidationWithClassLevel() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -125,13 +122,10 @@ class ValidatorFactoryTests {
|
||||
ConstraintViolation<?> cv = iterator.next();
|
||||
assertThat(cv.getPropertyPath().toString()).isEqualTo("");
|
||||
assertThat(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidationFieldType() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSpringValidationFieldType() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -141,16 +135,11 @@ class ValidatorFactoryTests {
|
||||
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(person, "person");
|
||||
validator.validate(person, errors);
|
||||
assertThat(errors.getErrorCount()).isEqualTo(1);
|
||||
assertThat(errors.getFieldError("address").getRejectedValue())
|
||||
.as("Field/Value type mismatch")
|
||||
.isInstanceOf(ValidAddress.class);
|
||||
|
||||
validator.destroy();
|
||||
assertThat(errors.getFieldError("address").getRejectedValue()).isInstanceOf(ValidAddress.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSpringValidation() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -175,13 +164,10 @@ class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.contains("NotNull.street")).isTrue();
|
||||
assertThat(errorCodes.contains("NotNull.java.lang.String")).isTrue();
|
||||
assertThat(errorCodes.contains("NotNull")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidationWithClassLevel() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSpringValidationWithClassLevel() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -196,12 +182,10 @@ class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.size()).isEqualTo(2);
|
||||
assertThat(errorCodes.contains("NameAddressValid.person")).isTrue();
|
||||
assertThat(errorCodes.contains("NameAddressValid")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidationWithAutowiredValidator() {
|
||||
public void testSpringValidationWithAutowiredValidator() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LocalValidatorFactoryBean.class);
|
||||
LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class);
|
||||
@@ -218,14 +202,11 @@ class ValidatorFactoryTests {
|
||||
assertThat(errorCodes.size()).isEqualTo(2);
|
||||
assertThat(errorCodes.contains("NameAddressValid.person")).isTrue();
|
||||
assertThat(errorCodes.contains("NameAddressValid")).isTrue();
|
||||
|
||||
validator.destroy();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidationWithErrorInListElement() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSpringValidationWithErrorInListElement() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -240,13 +221,10 @@ class ValidatorFactoryTests {
|
||||
assertThat(fieldError.getField()).isEqualTo("address.street");
|
||||
fieldError = result.getFieldError("addressList[0].street");
|
||||
assertThat(fieldError.getField()).isEqualTo("addressList[0].street");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void springValidationWithErrorInSetElement() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testSpringValidationWithErrorInSetElement() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -261,13 +239,10 @@ class ValidatorFactoryTests {
|
||||
assertThat(fieldError.getField()).isEqualTo("address.street");
|
||||
fieldError = result.getFieldError("addressSet[].street");
|
||||
assertThat(fieldError.getField()).isEqualTo("addressSet[].street");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void innerBeanValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testInnerBeanValidation() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -276,13 +251,10 @@ class ValidatorFactoryTests {
|
||||
validator.validate(mainBean, errors);
|
||||
Object rejected = errors.getFieldValue("inner.value");
|
||||
assertThat(rejected).isNull();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validationWithOptionalField() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testValidationWithOptionalField() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -291,13 +263,10 @@ class ValidatorFactoryTests {
|
||||
validator.validate(mainBean, errors);
|
||||
Object rejected = errors.getFieldValue("inner.value");
|
||||
assertThat(rejected).isNull();
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void listValidation() {
|
||||
@SuppressWarnings("resource")
|
||||
public void testListValidation() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
@@ -313,34 +282,6 @@ class ValidatorFactoryTests {
|
||||
assertThat(fieldError).isNotNull();
|
||||
assertThat(fieldError.getRejectedValue()).isEqualTo("X");
|
||||
assertThat(errors.getFieldValue("list[1]")).isEqualTo("X");
|
||||
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withConstraintValidatorFactory() {
|
||||
ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory(new DefaultListableBeanFactory());
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setConstraintValidatorFactory(cvf);
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
assertThat(validator.getConstraintValidatorFactory()).isSameAs(cvf);
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withCustomInitializer() {
|
||||
ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory(new DefaultListableBeanFactory());
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
validator.setConfigurationInitializer(configuration -> configuration.constraintValidatorFactory(cvf));
|
||||
validator.afterPropertiesSet();
|
||||
|
||||
assertThat(validator.getConstraintValidatorFactory()).isSameAs(cvf);
|
||||
validator.destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -439,8 +380,8 @@ class ValidatorFactoryTests {
|
||||
}
|
||||
boolean valid = (value.name == null || !value.address.street.contains(value.name));
|
||||
if (!valid && "Phil".equals(value.name)) {
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
|
||||
.addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate(
|
||||
context.getDefaultConstraintMessageTemplate()).addPropertyNode("address").addConstraintViolation().disableDefaultConstraintViolation();
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@@ -476,7 +417,6 @@ class ValidatorFactoryTests {
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
@@ -485,8 +425,8 @@ class ValidatorFactoryTests {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Constraint(validatedBy = InnerValidator.class)
|
||||
public @interface InnerValid {
|
||||
@Constraint(validatedBy=InnerValidator.class)
|
||||
public static @interface InnerValid {
|
||||
|
||||
String message() default "NOT VALID";
|
||||
|
||||
@@ -506,8 +446,7 @@ class ValidatorFactoryTests {
|
||||
public boolean isValid(InnerBean bean, ConstraintValidatorContext context) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
if (bean.getValue() == null) {
|
||||
context.buildConstraintViolationWithTemplate("NULL")
|
||||
.addPropertyNode("value").addConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("NULL").addPropertyNode("value").addConstraintViolation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -555,8 +494,7 @@ class ValidatorFactoryTests {
|
||||
boolean valid = true;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if ("X".equals(list.get(i))) {
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
|
||||
.addBeanNode().inIterable().atIndex(i).addConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addBeanNode().inIterable().atIndex(i).addConstraintViolation();
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ import org.springframework.util.StringValueResolver;
|
||||
*
|
||||
* <p>The common annotations supported by this post-processor are available in
|
||||
* Java 6 (JDK 1.6) as well as in Java EE 5/6 (which provides a standalone jar for
|
||||
* its common annotations as well, allowing for use in any based application).
|
||||
* its common annotations as well, allowing for use in any Java 5 based application).
|
||||
*
|
||||
* <p>For default usage, resolving resource names as Spring bean names,
|
||||
* simply define the following in your application context:
|
||||
|
||||
+7
-7
@@ -138,7 +138,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException {
|
||||
public Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {
|
||||
if (!StringUtils.hasLength(value)) {
|
||||
return value;
|
||||
}
|
||||
@@ -148,21 +148,21 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
||||
this.expressionCache.put(value, expr);
|
||||
}
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(beanExpressionContext);
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||
if (sec == null) {
|
||||
sec = new StandardEvaluationContext(beanExpressionContext);
|
||||
sec = new StandardEvaluationContext(evalContext);
|
||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
sec.addPropertyAccessor(new EnvironmentAccessor());
|
||||
sec.setBeanResolver(new BeanFactoryResolver(beanExpressionContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(beanExpressionContext.getBeanFactory().getBeanClassLoader()));
|
||||
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||
sec.setTypeConverter(new StandardTypeConverter(() -> {
|
||||
ConversionService cs = beanExpressionContext.getBeanFactory().getConversionService();
|
||||
ConversionService cs = evalContext.getBeanFactory().getConversionService();
|
||||
return (cs != null ? cs : DefaultConversionService.getSharedInstance());
|
||||
}));
|
||||
customizeEvaluationContext(sec);
|
||||
this.evaluationCache.put(beanExpressionContext, sec);
|
||||
this.evaluationCache.put(evalContext, sec);
|
||||
}
|
||||
return expr.getValue(sec);
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,9 +37,9 @@ public class SimpleLocaleContext implements LocaleContext {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code SimpleLocaleContext} that exposes the specified {@link Locale}.
|
||||
* <p>Every {@link #getLocale()} call will return this locale.
|
||||
* @param locale the {@code Locale} to expose, or {@code null} for no specific one
|
||||
* Create a new SimpleLocaleContext that exposes the specified Locale.
|
||||
* Every {@link #getLocale()} call will return this Locale.
|
||||
* @param locale the Locale to expose, or {@code null} for no specific one
|
||||
*/
|
||||
public SimpleLocaleContext(@Nullable Locale locale) {
|
||||
this.locale = locale;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -143,7 +143,7 @@ public class NotificationListenerRegistrar extends NotificationListenerHolder
|
||||
this.actualObjectNames = getResolvedObjectNames();
|
||||
if (this.actualObjectNames != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registering NotificationListener for MBeans " + Arrays.toString(this.actualObjectNames));
|
||||
logger.debug("Registering NotificationListener for MBeans " + Arrays.asList(this.actualObjectNames));
|
||||
}
|
||||
for (ObjectName actualObjectName : this.actualObjectNames) {
|
||||
this.server.addNotificationListener(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -762,7 +762,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
* <p>The default implementation delegates to {@link JmxUtils#isMBean},
|
||||
* which checks for {@link javax.management.DynamicMBean} classes as well
|
||||
* as classes with corresponding "*MBean" interface (Standard MBeans)
|
||||
* or corresponding "*MXBean" interface (Java MXBeans).
|
||||
* or corresponding "*MXBean" interface (Java 6 MXBeans).
|
||||
* @param beanClass the bean class to analyze
|
||||
* @return whether the class qualifies as an MBean
|
||||
* @see org.springframework.jmx.support.JmxUtils#isMBean(Class)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link JmxAttributeSource} interface that
|
||||
* Implementation of the {@code JmxAttributeSource} interface that
|
||||
* reads annotations and exposes the corresponding attributes.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import org.springframework.jmx.export.naming.MetadataNamingStrategy;
|
||||
|
||||
/**
|
||||
* Convenient subclass of Spring's standard {@link MBeanExporter},
|
||||
* activating annotation usage for JMX exposure of Spring beans:
|
||||
* activating Java 5 annotation usage for JMX exposure of Spring beans:
|
||||
* {@link ManagedResource}, {@link ManagedAttribute}, {@link ManagedOperation}, etc.
|
||||
*
|
||||
* <p>Sets a {@link MetadataNamingStrategy} and a {@link MetadataMBeanInfoAssembler}
|
||||
|
||||
+1
-2
@@ -27,8 +27,7 @@ import org.springframework.jmx.support.MetricType;
|
||||
/**
|
||||
* Method-level annotation that indicates to expose a given bean property as a
|
||||
* JMX attribute, with added descriptor properties to indicate that it is a metric.
|
||||
*
|
||||
* <p>Only valid when used on a JavaBean getter.
|
||||
* Only valid when used on a JavaBean getter.
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
* @since 3.0
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,12 +27,10 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Type-level annotation that indicates a JMX notification emitted by a bean.
|
||||
*
|
||||
* <p>This annotation is a {@linkplain java.lang.annotation.Repeatable repeatable}
|
||||
* annotation.
|
||||
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
* @see ManagedNotifications
|
||||
* @see org.springframework.jmx.export.metadata.ManagedNotification
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
+3
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2016 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,12 +24,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Type-level annotation used as a container for one or more
|
||||
* {@code @ManagedNotification} declarations.
|
||||
*
|
||||
* <p>Note, however, that use of the {@code @ManagedNotifications} container
|
||||
* is completely optional since {@code @ManagedNotification} is a
|
||||
* {@linkplain java.lang.annotation.Repeatable repeatable} annotation.
|
||||
* Type-level annotation that indicates JMX notifications emitted by a bean,
|
||||
* containing multiple {@link ManagedNotification ManagedNotifications}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
|
||||
+4
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,11 +23,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation that indicates to expose a given method as a JMX operation,
|
||||
* corresponding to the {@link org.springframework.jmx.export.metadata.ManagedOperation}
|
||||
* attribute.
|
||||
*
|
||||
* <p>Only valid when used on a method that is not a JavaBean getter or setter.
|
||||
* Method-level annotation that indicates to expose a given method as a
|
||||
* JMX operation, corresponding to the {@code ManagedOperation} attribute.
|
||||
* Only valid when used on a method that is not a JavaBean getter or setter.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,15 +24,15 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation used to provide metadata about operation parameters, corresponding
|
||||
* to a {@link org.springframework.jmx.export.metadata.ManagedOperationParameter} attribute.
|
||||
* Method-level annotation used to provide metadata about operation parameters,
|
||||
* corresponding to a {@code ManagedOperationParameter} attribute.
|
||||
* Used as part of a {@link ManagedOperationParameters} annotation.
|
||||
*
|
||||
* <p>This annotation is a {@linkplain java.lang.annotation.Repeatable repeatable}
|
||||
* annotation.
|
||||
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
* @see ManagedOperationParameters
|
||||
* @see ManagedOperationParameters#value
|
||||
* @see org.springframework.jmx.export.metadata.ManagedOperationParameter
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
|
||||
+3
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,12 +23,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation used as a container for one or more
|
||||
* {@code @ManagedOperationParameter} declarations.
|
||||
*
|
||||
* <p>Note, however, that use of the {@code @ManagedOperationParameters} container
|
||||
* is completely optional since {@code @ManagedOperationParameter} is a
|
||||
* {@linkplain java.lang.annotation.Repeatable repeatable} annotation.
|
||||
* Method-level annotation used to provide metadata about operation parameters,
|
||||
* corresponding to an array of {@code ManagedOperationParameter} attributes.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
/**
|
||||
* Class-level annotation that indicates to register instances of a class with a JMX server,
|
||||
* corresponding to the {@link org.springframework.jmx.export.metadata.ManagedResource} attribute.
|
||||
* Class-level annotation that indicates to register instances of a class
|
||||
* with a JMX server, corresponding to the {@code ManagedResource} attribute.
|
||||
*
|
||||
* <p><b>Note:</b> This annotation is marked as inherited, allowing for generic
|
||||
* management-aware base classes. In such a scenario, it is recommended to
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Annotations for MBean exposure.
|
||||
*
|
||||
* <p>Hooked into Spring's JMX export infrastructure via a special
|
||||
* {@link org.springframework.jmx.export.metadata.JmxAttributeSource} implementation.
|
||||
* Java 5 annotations for MBean exposure.
|
||||
* Hooked into Spring's JMX export infrastructure
|
||||
* via a special JmxAttributeSource implementation.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.util.StringUtils;
|
||||
* <p>Uses the {@link JmxAttributeSource} strategy interface, so that
|
||||
* metadata can be read using any supported implementation. Out of the box,
|
||||
* {@link org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource}
|
||||
* introspects a well-defined set of annotations that come with Spring.
|
||||
* introspects a well-defined set of Java 5 annotations that come with Spring.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -255,7 +255,7 @@ public abstract class JmxUtils {
|
||||
* Determine whether the given bean class qualifies as an MBean as-is.
|
||||
* <p>This implementation checks for {@link javax.management.DynamicMBean}
|
||||
* classes as well as classes with corresponding "*MBean" interface
|
||||
* (Standard MBeans) or corresponding "*MXBean" interface (Java MXBeans).
|
||||
* (Standard MBeans) or corresponding "*MXBean" interface (Java 6 MXBeans).
|
||||
* @param clazz the bean class to analyze
|
||||
* @return whether the class qualifies as an MBean
|
||||
* @see org.springframework.jmx.export.MBeanExporter#isMBean(Class)
|
||||
@@ -289,7 +289,7 @@ public abstract class JmxUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Java MXBean interface for the given class, if any
|
||||
* Return the Java 6 MXBean interface exists for the given class, if any
|
||||
* (that is, an interface whose name ends with "MXBean" and/or
|
||||
* carries an appropriate MXBean annotation).
|
||||
* @param clazz the class to check
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Annotation support for asynchronous method execution.
|
||||
* Java 5 annotation for asynchronous method execution.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+2
-26
@@ -72,8 +72,6 @@ import org.springframework.util.concurrent.ListenableFutureTask;
|
||||
* {@link org.springframework.scheduling.concurrent.ConcurrentTaskExecutor} adapter.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rémy Guihard
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see org.springframework.core.task.TaskExecutor
|
||||
* @see java.util.concurrent.ThreadPoolExecutor
|
||||
@@ -157,7 +155,7 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
|
||||
|
||||
/**
|
||||
* Set the ThreadPoolExecutor's keep-alive seconds.
|
||||
* <p>Default is 60.
|
||||
* Default is 60.
|
||||
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
|
||||
*/
|
||||
public void setKeepAliveSeconds(int keepAliveSeconds) {
|
||||
@@ -180,7 +178,7 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
|
||||
|
||||
/**
|
||||
* Set the capacity for the ThreadPoolExecutor's BlockingQueue.
|
||||
* <p>Default is {@code Integer.MAX_VALUE}.
|
||||
* Default is {@code Integer.MAX_VALUE}.
|
||||
* <p>Any positive value will lead to a LinkedBlockingQueue instance;
|
||||
* any other value will lead to a SynchronousQueue instance.
|
||||
* @see java.util.concurrent.LinkedBlockingQueue
|
||||
@@ -190,15 +188,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
|
||||
this.queueCapacity = queueCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capacity for the ThreadPoolExecutor's BlockingQueue.
|
||||
* @since 5.3.21
|
||||
* @see #setQueueCapacity(int)
|
||||
*/
|
||||
public int getQueueCapacity() {
|
||||
return this.queueCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether to allow core threads to time out. This enables dynamic
|
||||
* growing and shrinking even in combination with a non-zero queue (since
|
||||
@@ -327,19 +316,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
|
||||
return this.threadPoolExecutor.getPoolSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current queue size.
|
||||
* @since 5.3.21
|
||||
* @see java.util.concurrent.ThreadPoolExecutor#getQueue()
|
||||
*/
|
||||
public int getQueueSize() {
|
||||
if (this.threadPoolExecutor == null) {
|
||||
// Not initialized yet: assume no queued tasks.
|
||||
return 0;
|
||||
}
|
||||
return this.threadPoolExecutor.getQueue().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of currently active threads.
|
||||
* @see java.util.concurrent.ThreadPoolExecutor#getActiveCount()
|
||||
|
||||
+2
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,6 @@ import org.springframework.lang.Nullable;
|
||||
* @see ScheduledTaskRegistrar#scheduleCronTask(CronTask)
|
||||
* @see ScheduledTaskRegistrar#scheduleFixedRateTask(FixedRateTask)
|
||||
* @see ScheduledTaskRegistrar#scheduleFixedDelayTask(FixedDelayTask)
|
||||
* @see ScheduledFuture
|
||||
*/
|
||||
public final class ScheduledTask {
|
||||
|
||||
@@ -55,24 +54,11 @@ public final class ScheduledTask {
|
||||
|
||||
/**
|
||||
* Trigger cancellation of this scheduled task.
|
||||
* <p>This variant will force interruption of the task if still running.
|
||||
* @see #cancel(boolean)
|
||||
*/
|
||||
public void cancel() {
|
||||
cancel(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger cancellation of this scheduled task.
|
||||
* @param mayInterruptIfRunning whether to force interruption of the task
|
||||
* if still running (specify {@code false} to allow the task to complete)
|
||||
* @since 5.3.18
|
||||
* @see ScheduledFuture#cancel(boolean)
|
||||
*/
|
||||
public void cancel(boolean mayInterruptIfRunning) {
|
||||
ScheduledFuture<?> future = this.future;
|
||||
if (future != null) {
|
||||
future.cancel(mayInterruptIfRunning);
|
||||
future.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-15
@@ -18,7 +18,6 @@ package org.springframework.scheduling.support;
|
||||
|
||||
import java.time.DateTimeException;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.time.temporal.ValueRange;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -169,25 +168,22 @@ abstract class CronField {
|
||||
* day-of-month, month, day-of-week.
|
||||
*/
|
||||
protected enum Type {
|
||||
NANO(ChronoField.NANO_OF_SECOND, ChronoUnit.SECONDS),
|
||||
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoUnit.MINUTES, ChronoField.NANO_OF_SECOND),
|
||||
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoUnit.HOURS, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
HOUR(ChronoField.HOUR_OF_DAY, ChronoUnit.DAYS, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoUnit.MONTHS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MONTH(ChronoField.MONTH_OF_YEAR, ChronoUnit.YEARS, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoUnit.WEEKS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
|
||||
NANO(ChronoField.NANO_OF_SECOND),
|
||||
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
HOUR(ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MONTH(ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
|
||||
|
||||
|
||||
private final ChronoField field;
|
||||
|
||||
private final ChronoUnit higherOrder;
|
||||
|
||||
private final ChronoField[] lowerOrders;
|
||||
|
||||
|
||||
Type(ChronoField field, ChronoUnit higherOrder, ChronoField... lowerOrders) {
|
||||
Type(ChronoField field, ChronoField... lowerOrders) {
|
||||
this.field = field;
|
||||
this.higherOrder = higherOrder;
|
||||
this.lowerOrders = lowerOrders;
|
||||
}
|
||||
|
||||
@@ -270,9 +266,17 @@ abstract class CronField {
|
||||
* @return the rolled forward temporal
|
||||
*/
|
||||
public <T extends Temporal & Comparable<? super T>> T rollForward(T temporal) {
|
||||
T result = this.higherOrder.addTo(temporal, 1);
|
||||
ValueRange range = result.range(this.field);
|
||||
return this.field.adjustInto(result, range.getMinimum());
|
||||
int current = get(temporal);
|
||||
ValueRange range = temporal.range(this.field);
|
||||
long amount = range.getMaximum() - current + 1;
|
||||
T result = this.field.getBaseUnit().addTo(temporal, amount);
|
||||
current = get(result);
|
||||
range = result.range(this.field);
|
||||
// adjust for daylight savings
|
||||
if (current != range.getMinimum()) {
|
||||
result = this.field.adjustInto(result, range.getMinimum());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,7 +36,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.scripting.ScriptFactory} implementation based
|
||||
* on the JSR-223 script engine abstraction (as included in Java).
|
||||
* on the JSR-223 script engine abstraction (as included in Java 6+).
|
||||
* Supports JavaScript, Groovy, JRuby, and other JSR-223 compliant engines.
|
||||
*
|
||||
* <p>Typically used in combination with a
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Subclass of {@link ModelMap} that implements the {@link Model} interface.
|
||||
* Java 5 specific like the {@code Model} interface itself.
|
||||
*
|
||||
* <p>This is an implementation class exposed to handler methods by Spring MVC, typically via
|
||||
* a declaration of the {@link org.springframework.ui.Model} interface. There is no need to
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,11 +22,9 @@ import java.util.Map;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Interface that defines a holder for model attributes.
|
||||
*
|
||||
* <p>Primarily designed for adding attributes to the model.
|
||||
*
|
||||
* <p>Allows for accessing the overall model as a {@code java.util.Map}.
|
||||
* Java-5-specific interface that defines a holder for model attributes.
|
||||
* Primarily designed for adding attributes to the model.
|
||||
* Allows for accessing the overall model as a {@code java.util.Map}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,20 +51,18 @@ import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Binder that allows for setting property values on a target object, including
|
||||
* support for validation and binding result analysis.
|
||||
*
|
||||
* <p>The binding process can be customized by specifying allowed field patterns,
|
||||
* Binder that allows for setting property values onto a target object,
|
||||
* including support for validation and binding result analysis.
|
||||
* The binding process can be customized through specifying allowed fields,
|
||||
* required fields, custom editors, etc.
|
||||
*
|
||||
* <p><strong>WARNING</strong>: Data binding can lead to security issues by exposing
|
||||
* parts of the object graph that are not meant to be accessed or modified by
|
||||
* external clients. Therefore the design and use of data binding should be considered
|
||||
* carefully with regard to security. For more details, please refer to the dedicated
|
||||
* sections on data binding for
|
||||
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder-model-design">Spring Web MVC</a> and
|
||||
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-ann-initbinder-model-design">Spring WebFlux</a>
|
||||
* in the reference manual.
|
||||
* <p>Note that there are potential security implications in failing to set an array
|
||||
* of allowed fields. In the case of HTTP form POST data for example, malicious clients
|
||||
* can attempt to subvert an application by supplying values for fields or properties
|
||||
* that do not exist on the form. In some cases this could lead to illegal data being
|
||||
* set on command objects <i>or their nested objects</i>. For this reason, it is
|
||||
* <b>highly recommended to specify the {@link #setAllowedFields allowedFields} property</b>
|
||||
* on the DataBinder.
|
||||
*
|
||||
* <p>The binding results can be examined via the {@link BindingResult} interface,
|
||||
* extending the {@link Errors} interface: see the {@link #getBindingResult()} method.
|
||||
@@ -98,7 +96,6 @@ import org.springframework.util.StringUtils;
|
||||
* @author Rob Harrop
|
||||
* @author Stephane Nicoll
|
||||
* @author Kazuki Shimizu
|
||||
* @author Sam Brannen
|
||||
* @see #setAllowedFields
|
||||
* @see #setRequiredFields
|
||||
* @see #registerCustomEditor
|
||||
@@ -421,21 +418,15 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register field patterns that should be allowed for binding.
|
||||
* <p>Default is all fields.
|
||||
* <p>Restrict this for example to avoid unwanted modifications by malicious
|
||||
* Register fields that should be allowed for binding. Default is all fields.
|
||||
* Restrict this for example to avoid unwanted modifications by malicious
|
||||
* users when binding HTTP request parameters.
|
||||
* <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality.
|
||||
* <p>The default implementation of this method stores allowed field patterns
|
||||
* in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
|
||||
* form. Subclasses which override this method must therefore take this into
|
||||
* account.
|
||||
* <p>More sophisticated matching can be implemented by overriding the
|
||||
* {@link #isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>disallowed</i> field patterns.
|
||||
* @param allowedFields array of allowed field patterns
|
||||
* <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
|
||||
* arbitrary number of pattern parts), as well as direct equality. More
|
||||
* sophisticated matching can be implemented by overriding the
|
||||
* {@code isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>disallowed</i> fields.
|
||||
* @param allowedFields array of field names
|
||||
* @see #setDisallowedFields
|
||||
* @see #isAllowed(String)
|
||||
*/
|
||||
@@ -444,9 +435,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field patterns that should be allowed for binding.
|
||||
* @return array of allowed field patterns
|
||||
* @see #setAllowedFields(String...)
|
||||
* Return the fields that should be allowed for binding.
|
||||
* @return array of field names
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getAllowedFields() {
|
||||
@@ -454,44 +444,25 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register field patterns that should <i>not</i> be allowed for binding.
|
||||
* <p>Default is none.
|
||||
* <p>Mark fields as disallowed, for example to avoid unwanted
|
||||
* Register fields that should <i>not</i> be allowed for binding. Default
|
||||
* is none. Mark fields as disallowed for example to avoid unwanted
|
||||
* modifications by malicious users when binding HTTP request parameters.
|
||||
* <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality.
|
||||
* <p>The default implementation of this method stores disallowed field patterns
|
||||
* in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
|
||||
* form. As of Spring Framework 5.2.21, the default implementation also transforms
|
||||
* disallowed field patterns to {@linkplain String#toLowerCase() lowercase} to
|
||||
* support case-insensitive pattern matching in {@link #isAllowed}. Subclasses
|
||||
* which override this method must therefore take both of these transformations
|
||||
* into account.
|
||||
* <p>More sophisticated matching can be implemented by overriding the
|
||||
* {@link #isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>allowed</i> field patterns.
|
||||
* @param disallowedFields array of disallowed field patterns
|
||||
* <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
|
||||
* arbitrary number of pattern parts), as well as direct equality.
|
||||
* More sophisticated matching can be implemented by overriding the
|
||||
* {@code isAllowed} method.
|
||||
* <p>Alternatively, specify a list of <i>allowed</i> fields.
|
||||
* @param disallowedFields array of field names
|
||||
* @see #setAllowedFields
|
||||
* @see #isAllowed(String)
|
||||
*/
|
||||
public void setDisallowedFields(@Nullable String... disallowedFields) {
|
||||
if (disallowedFields == null) {
|
||||
this.disallowedFields = null;
|
||||
}
|
||||
else {
|
||||
String[] fieldPatterns = new String[disallowedFields.length];
|
||||
for (int i = 0; i < fieldPatterns.length; i++) {
|
||||
fieldPatterns[i] = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]).toLowerCase();
|
||||
}
|
||||
this.disallowedFields = fieldPatterns;
|
||||
}
|
||||
this.disallowedFields = PropertyAccessorUtils.canonicalPropertyNames(disallowedFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field patterns that should <i>not</i> be allowed for binding.
|
||||
* @return array of disallowed field patterns
|
||||
* @see #setDisallowedFields(String...)
|
||||
* Return the fields that should <i>not</i> be allowed for binding.
|
||||
* @return array of field names
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getDisallowedFields() {
|
||||
@@ -803,20 +774,16 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given field is allowed for binding.
|
||||
* <p>Invoked for each passed-in property value.
|
||||
* <p>Checks for {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
|
||||
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
|
||||
* well as direct equality, in the configured lists of allowed field patterns
|
||||
* and disallowed field patterns.
|
||||
* <p>Matching against allowed field patterns is case-sensitive; whereas,
|
||||
* matching against disallowed field patterns is case-insensitive.
|
||||
* <p>A field matching a disallowed pattern will not be accepted even if it
|
||||
* also happens to match a pattern in the allowed list.
|
||||
* <p>Can be overridden in subclasses, but care must be taken to honor the
|
||||
* aforementioned contract.
|
||||
* Return if the given field is allowed for binding.
|
||||
* Invoked for each passed-in property value.
|
||||
* <p>The default implementation checks for "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
|
||||
* matches (with an arbitrary number of pattern parts), as well as direct equality,
|
||||
* in the specified lists of allowed fields and disallowed fields. A field matching
|
||||
* a disallowed pattern will not be accepted even if it also happens to match a
|
||||
* pattern in the allowed list.
|
||||
* <p>Can be overridden in subclasses.
|
||||
* @param field the field to check
|
||||
* @return {@code true} if the field is allowed
|
||||
* @return if the field is allowed
|
||||
* @see #setAllowedFields
|
||||
* @see #setDisallowedFields
|
||||
* @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String)
|
||||
@@ -825,7 +792,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
String[] allowed = getAllowedFields();
|
||||
String[] disallowed = getDisallowedFields();
|
||||
return ((ObjectUtils.isEmpty(allowed) || PatternMatchUtils.simpleMatch(allowed, field)) &&
|
||||
(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field.toLowerCase())));
|
||||
(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 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,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.validation.Configuration;
|
||||
import javax.validation.ConstraintValidatorFactory;
|
||||
@@ -114,9 +113,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
|
||||
private final Map<String, String> validationPropertyMap = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
private Consumer<Configuration<?>> configurationInitializer;
|
||||
|
||||
@Nullable
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@@ -238,18 +234,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
return this.validationPropertyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a callback for customizing the Bean Validation {@code Configuration} instance,
|
||||
* as an alternative to overriding the {@link #postProcessConfiguration(Configuration)}
|
||||
* method in custom {@code LocalValidatorFactoryBean} subclasses.
|
||||
* <p>This enables convenient customizations for application purposes. Infrastructure
|
||||
* extensions may keep overriding the {@link #postProcessConfiguration} template method.
|
||||
* @since 5.3.19
|
||||
*/
|
||||
public void setConfigurationInitializer(Consumer<Configuration<?>> configurationInitializer) {
|
||||
this.configurationInitializer = configurationInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
@@ -328,9 +312,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
this.validationPropertyMap.forEach(configuration::addProperty);
|
||||
|
||||
// Allow for custom post-processing before we actually build the ValidatorFactory.
|
||||
if (this.configurationInitializer != null) {
|
||||
this.configurationInitializer.accept(configuration);
|
||||
}
|
||||
postProcessConfiguration(configuration);
|
||||
|
||||
try {
|
||||
|
||||
+11
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -38,9 +37,7 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class AfterAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
public class AfterAdviceBindingTests {
|
||||
|
||||
private AdviceBindingCollaborator mockCollaborator;
|
||||
|
||||
@@ -50,8 +47,9 @@ class AfterAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
public void setup() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
AdviceBindingTestAspect afterAdviceAspect = (AdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
|
||||
testBeanProxy = (ITestBean) ctx.getBean("testBean");
|
||||
@@ -64,44 +62,39 @@ class AfterAdviceBindingTests {
|
||||
afterAdviceAspect.setCollaborator(mockCollaborator);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void oneIntArg() {
|
||||
public void testOneIntArg() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntArg(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneObjectArgBindingProxyWithThis() {
|
||||
public void testOneObjectArgBindingProxyWithThis() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneObjectArgBindingTarget() {
|
||||
public void testOneObjectArgBindingTarget() {
|
||||
testBeanProxy.getDoctor();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneIntAndOneObjectArgs() {
|
||||
public void testOneIntAndOneObjectArgs() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntAndOneObject(5,this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void needsJoinPoint() {
|
||||
public void testNeedsJoinPoint() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPoint("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
void needsJoinPointStaticPart() {
|
||||
public void testNeedsJoinPointStaticPart() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPointStaticPart("getAge");
|
||||
}
|
||||
|
||||
+17
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -40,9 +39,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class AfterReturningAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
public class AfterReturningAdviceBindingTests {
|
||||
|
||||
private AfterReturningAdviceBindingTestAspect afterAdviceAspect;
|
||||
|
||||
@@ -54,8 +51,9 @@ class AfterReturningAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
public void setup() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
afterAdviceAspect = (AfterReturningAdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
|
||||
@@ -69,63 +67,58 @@ class AfterReturningAdviceBindingTests {
|
||||
this.testBeanTarget = (TestBean) ((Advised)testBeanProxy).getTargetSource().getTarget();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void oneIntArg() {
|
||||
public void testOneIntArg() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntArg(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneObjectArg() {
|
||||
public void testOneObjectArg() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneIntAndOneObjectArgs() {
|
||||
public void testOneIntAndOneObjectArgs() {
|
||||
testBeanProxy.setAge(5);
|
||||
verify(mockCollaborator).oneIntAndOneObject(5,this.testBeanProxy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void needsJoinPoint() {
|
||||
public void testNeedsJoinPoint() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPoint("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
void needsJoinPointStaticPart() {
|
||||
public void testNeedsJoinPointStaticPart() {
|
||||
testBeanProxy.getAge();
|
||||
verify(mockCollaborator).needsJoinPointStaticPart("getAge");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningString() {
|
||||
public void testReturningString() {
|
||||
testBeanProxy.setName("adrian");
|
||||
testBeanProxy.getName();
|
||||
verify(mockCollaborator).oneString("adrian");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningObject() {
|
||||
public void testReturningObject() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).oneObjectArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningBean() {
|
||||
public void testReturningBean() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).oneTestBeanArg(this.testBeanTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningBeanArray() {
|
||||
public void testReturningBeanArray() {
|
||||
this.testBeanTarget.setSpouse(new TestBean());
|
||||
ITestBean[] spouses = this.testBeanTarget.getSpouses();
|
||||
testBeanProxy.getSpouses();
|
||||
@@ -133,20 +126,20 @@ class AfterReturningAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void noInvokeWhenReturningParameterTypeDoesNotMatch() {
|
||||
public void testNoInvokeWhenReturningParameterTypeDoesNotMatch() {
|
||||
testBeanProxy.setSpouse(this.testBeanProxy);
|
||||
testBeanProxy.getSpouse();
|
||||
verifyNoInteractions(mockCollaborator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningByType() {
|
||||
public void testReturningByType() {
|
||||
testBeanProxy.returnsThis();
|
||||
verify(mockCollaborator).objectMatchNoArgs();
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningPrimitive() {
|
||||
public void testReturningPrimitive() {
|
||||
testBeanProxy.setAge(20);
|
||||
testBeanProxy.haveBirthday();
|
||||
verify(mockCollaborator).oneInt(20);
|
||||
|
||||
+11
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -34,9 +33,7 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class AfterThrowingAdviceBindingTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
public class AfterThrowingAdviceBindingTests {
|
||||
|
||||
private ITestBean testBean;
|
||||
|
||||
@@ -46,8 +43,9 @@ class AfterThrowingAdviceBindingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
afterThrowingAdviceAspect = (AfterThrowingAdviceBindingTestAspect) ctx.getBean("testAspect");
|
||||
@@ -56,21 +54,16 @@ class AfterThrowingAdviceBindingTests {
|
||||
afterThrowingAdviceAspect.setCollaborator(mockCollaborator);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void simpleAfterThrowing() throws Throwable {
|
||||
public void testSimpleAfterThrowing() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new Throwable()));
|
||||
verify(mockCollaborator).noArgs();
|
||||
}
|
||||
|
||||
@Test
|
||||
void afterThrowingWithBinding() throws Throwable {
|
||||
public void testAfterThrowingWithBinding() throws Throwable {
|
||||
Throwable t = new Throwable();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(t));
|
||||
@@ -78,7 +71,7 @@ class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void afterThrowingWithNamedTypeRestriction() throws Throwable {
|
||||
public void testAfterThrowingWithNamedTypeRestriction() throws Throwable {
|
||||
Throwable t = new Throwable();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(t));
|
||||
@@ -88,7 +81,7 @@ class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void afterThrowingWithRuntimeExceptionBinding() throws Throwable {
|
||||
public void testAfterThrowingWithRuntimeExceptionBinding() throws Throwable {
|
||||
RuntimeException ex = new RuntimeException();
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(ex));
|
||||
@@ -96,14 +89,14 @@ class AfterThrowingAdviceBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void afterThrowingWithTypeSpecified() throws Throwable {
|
||||
public void testAfterThrowingWithTypeSpecified() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new Throwable()));
|
||||
verify(mockCollaborator).noArgsOnThrowableMatch();
|
||||
}
|
||||
|
||||
@Test
|
||||
void afterThrowingWithRuntimeTypeSpecified() throws Throwable {
|
||||
public void testAfterThrowingWithRuntimeTypeSpecified() throws Throwable {
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
this.testBean.exceptional(new RuntimeException()));
|
||||
verify(mockCollaborator).noArgsOnRuntimeExceptionMatch();
|
||||
|
||||
+6
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.aspectj;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -34,9 +33,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class AspectAndAdvicePrecedenceTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
public class AspectAndAdvicePrecedenceTests {
|
||||
|
||||
private PrecedenceTestAspect highPrecedenceAspect;
|
||||
|
||||
@@ -50,8 +47,9 @@ class AspectAndAdvicePrecedenceTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
highPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("highPrecedenceAspect");
|
||||
lowPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("lowPrecedenceAspect");
|
||||
highPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("highPrecedenceSpringAdvice");
|
||||
@@ -59,14 +57,9 @@ class AspectAndAdvicePrecedenceTests {
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testAdviceOrder() {
|
||||
public void testAdviceOrder() {
|
||||
PrecedenceTestAspect.Collaborator collaborator = new PrecedenceVerifyingCollaborator();
|
||||
this.highPrecedenceAspect.setCollaborator(collaborator);
|
||||
this.lowPrecedenceAspect.setCollaborator(collaborator);
|
||||
|
||||
+19
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
@@ -30,22 +31,29 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class AspectJExpressionPointcutAdvisorTests {
|
||||
public class AspectJExpressionPointcutAdvisorTests {
|
||||
|
||||
@Test
|
||||
void pointcutting() {
|
||||
private ITestBean testBean;
|
||||
|
||||
private CallCountingInterceptor interceptor;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
testBean = (ITestBean) ctx.getBean("testBean");
|
||||
interceptor = (CallCountingInterceptor) ctx.getBean("interceptor");
|
||||
}
|
||||
|
||||
ITestBean testBean = ctx.getBean("testBean", ITestBean.class);
|
||||
CallCountingInterceptor interceptor = ctx.getBean("interceptor", CallCountingInterceptor.class);
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(0);
|
||||
|
||||
@Test
|
||||
public void testPointcutting() {
|
||||
assertThat(interceptor.getCount()).as("Count should be 0").isEqualTo(0);
|
||||
testBean.getSpouses();
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(1);
|
||||
assertThat(interceptor.getCount()).as("Count should be 1").isEqualTo(1);
|
||||
testBean.getSpouse();
|
||||
assertThat(interceptor.getCount()).as("Count").isEqualTo(1);
|
||||
|
||||
ctx.close();
|
||||
assertThat(interceptor.getCount()).as("Count should be 1").isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,8 +18,6 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
|
||||
@@ -37,9 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class BeanNamePointcutAtAspectTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
public class BeanNamePointcutAtAspectTests {
|
||||
|
||||
private ITestBean testBean1;
|
||||
|
||||
@@ -48,24 +44,19 @@ class BeanNamePointcutAtAspectTests {
|
||||
private CounterAspect counterAspect;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
@org.junit.jupiter.api.BeforeEach
|
||||
public void setup() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
counterAspect = (CounterAspect) ctx.getBean("counterAspect");
|
||||
testBean1 = (ITestBean) ctx.getBean("testBean1");
|
||||
testBean3 = (ITestBean) ctx.getBean("testBean3");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.ctx.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
void matchingBeanName() {
|
||||
public void testMatchingBeanName() {
|
||||
boolean condition = testBean1 instanceof Advised;
|
||||
assertThat(condition).as("Expected a proxy").isTrue();
|
||||
|
||||
@@ -76,7 +67,7 @@ class BeanNamePointcutAtAspectTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonMatchingBeanName() {
|
||||
public void testNonMatchingBeanName() {
|
||||
boolean condition = testBean3 instanceof Advised;
|
||||
assertThat(condition).as("Didn't expect a proxy").isFalse();
|
||||
|
||||
@@ -85,7 +76,7 @@ class BeanNamePointcutAtAspectTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void programmaticProxyCreation() {
|
||||
public void testProgrammaticProxyCreation() {
|
||||
ITestBean testBean = new TestBean();
|
||||
|
||||
AspectJProxyFactory factory = new AspectJProxyFactory();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user