Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Buildmaster 967637d763 Release v5.3.1 2020-11-10 08:59:43 +00:00
491 changed files with 4941 additions and 14286 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
<!--
!!! For Security Vulnerabilities, please go to https://spring.io/security-policy !!!
!!! For Security Vulnerabilities, please go to https://pivotal.io/security !!!
-->
**Affects:** \<Spring Framework version>
@@ -14,4 +14,4 @@ Thanks for taking the time to create an issue. Please read the following:
Issue or Pull Request? Create only one, not both. GitHub treats them as the same.
If unsure, start with an issue, and if you submit a pull request later, the
issue will be closed as superseded.
-->
-->
+1 -1
View File
@@ -1,4 +1,4 @@
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [![Build Status](https://ci.spring.io/api/v1/teams/spring-framework/pipelines/spring-framework-5.3.x/jobs/build/badge)](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [![Revved up by Gradle Enterprise](https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.spring.io/scans?search.rootProjectNames=spring)
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [![Build Status](https://ci.spring.io/api/v1/teams/spring-framework/pipelines/spring-framework-5.3.x/jobs/build/badge)](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build")
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
+39 -40
View File
@@ -1,16 +1,15 @@
plugins {
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.5.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.4.30' apply false
id 'org.jetbrains.kotlin.jvm' version '1.4.10' apply false
id 'org.jetbrains.dokka' version '0.10.1' apply false
id 'org.asciidoctor.jvm.convert' version '3.1.0'
id 'org.asciidoctor.jvm.pdf' version '3.1.0'
id 'de.undercouch.download' version '4.1.1'
id "io.freefair.aspectj" version '5.1.1' apply false
id "com.github.ben-manes.versions" version '0.28.0'
id "com.github.johnrengelman.shadow" version "6.1.0" apply false
id "me.champeau.gradle.jmh" version "0.5.2" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.30" apply false
id "me.champeau.gradle.jmh" version "0.5.0" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.10" apply false
}
ext {
@@ -26,18 +25,18 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.1"
mavenBom "io.netty:netty-bom:4.1.59.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.4"
mavenBom "com.fasterxml.jackson:jackson-bom:2.11.3"
mavenBom "io.netty:netty-bom:4.1.53.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.0"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR8"
mavenBom "io.rsocket:rsocket-bom:1.1.0"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.36.v20210114"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.30"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.2"
mavenBom "org.junit:junit-bom:5.7.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.34.v20201102"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.10"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.1"
mavenBom "org.junit:junit-bom:5.7.0"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.0') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.13.3') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
@@ -54,7 +53,7 @@ configure(allprojects) { project ->
entry 'aspectjtools'
entry 'aspectjweaver'
}
dependencySet(group: 'org.codehaus.groovy', version: '3.0.7') {
dependencySet(group: 'org.codehaus.groovy', version: '3.0.6') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
@@ -64,8 +63,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.0.10"
dependency "io.reactivex.rxjava2:rxjava:2.2.19"
dependency "io.reactivex.rxjava3:rxjava:3.0.7"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "com.caucho:hessian:4.0.63"
@@ -74,13 +73,13 @@ configure(allprojects) { project ->
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.6"
dependency "com.google.protobuf:protobuf-java-util:3.14.0"
dependency "com.google.protobuf:protobuf-java-util:3.13.0"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.15") {
dependency("com.thoughtworks.xstream:xstream:1.4.13") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.10"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.8"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -96,8 +95,8 @@ configure(allprojects) { project ->
}
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.8"
dependency "com.github.librepdf:openpdf:1.3.25"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.6"
dependency "com.github.librepdf:openpdf:1.3.22"
dependency "com.rometools:rome:1.15.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.3"
@@ -124,23 +123,23 @@ configure(allprojects) { project ->
dependency "net.sf.ehcache:ehcache:2.10.6"
dependency "org.ehcache:jcache:1.0.1"
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.28.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.hibernate:hibernate-core:5.4.23.Final"
dependency "org.hibernate:hibernate-validator:6.1.6.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.43') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.39') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.43') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.39') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.4.Final') {
dependencySet(group: 'io.undertow', version: '2.2.2.Final') {
entry 'undertow-core'
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
@@ -155,15 +154,15 @@ configure(allprojects) { project ->
entry 'okhttp'
entry 'mockwebserver'
}
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
dependency("org.apache.httpcomponents:httpclient:4.5.12") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.3'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.5"
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.2'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.4"
dependency "org.jruby:jruby:9.2.13.0"
dependency "org.python:jython-standalone:2.7.1"
@@ -182,7 +181,7 @@ configure(allprojects) { project ->
exclude group: "dom4j", name: "dom4j"
}
dependency("junit:junit:4.13.2") {
dependency("junit:junit:4.13.1") {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
@@ -191,25 +190,25 @@ configure(allprojects) { project ->
dependency "org.testng:testng:7.3.0"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.19.0"
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
dependency "org.assertj:assertj-core:3.18.0"
dependencySet(group: 'org.xmlunit', version: '2.6.2') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '3.7.7') {
dependencySet(group: 'org.mockito', version: '3.6.0') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.10.2"
dependency "io.mockk:mockk:1.10.0"
dependency("net.sourceforge.htmlunit:htmlunit:2.47.1") {
dependency("net.sourceforge.htmlunit:htmlunit:2.44.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.47.1") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.44.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -237,8 +236,8 @@ configure(allprojects) { project ->
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.10"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.8"
dependency "joda-time:joda-time:2.10.6"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.7"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -340,7 +339,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.39"
toolVersion = "8.36.2"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -381,8 +380,8 @@ configure([rootProject] + javaProjects) { project ->
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
"https://junit.org/junit5/docs/5.7.1/api/"
"https://junit.org/junit4/javadoc/4.13.1/",
"https://junit.org/junit5/docs/5.7.0/api/"
] as String[]
}
+2 -2
View File
@@ -3,7 +3,7 @@ logging:
io.spring.concourse: DEBUG
distribute:
optional-deployments:
- '.*\.zip'
- '.*\\.zip'
spring:
main:
banner-mode: off
banner-mode: off
+6 -3
View File
@@ -3,13 +3,16 @@ set -e
case "$1" in
java8)
echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u282-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u282b08.tar.gz"
echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u265-b01/OpenJDK8U-jdk_x64_linux_hotspot_8u265b01.tar.gz"
;;
java11)
echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.8_10.tar.gz"
;;
java14)
echo "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_linux_hotspot_14.0.2_12.tar.gz"
;;
java15)
echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_linux_hotspot_15.0.2_7.tar.gz"
echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15%2B36/OpenJDK15U-jdk_x64_linux_hotspot_15_36.tar.gz"
;;
*)
echo $"Unknown java version"
+1 -4
View File
@@ -5,11 +5,8 @@ set -ex
# UTILS
###########################################################
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
dpkg-reconfigure --frontend noninteractive tzdata
apt-get install --no-install-recommends -y ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.3/concourse-java.sh > /opt/concourse-java.sh
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20210119
FROM ubuntu:bionic-20200713
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20210119
FROM ubuntu:bionic-20200713
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
@@ -0,0 +1,8 @@
FROM ubuntu:bionic-20200713
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java14
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20210119
FROM ubuntu:bionic-20200713
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
+50 -4
View File
@@ -37,17 +37,17 @@ anchors:
resource_types:
- name: artifactory-resource
type: registry-image
type: docker-image
source:
repository: springio/artifactory-resource
tag: 0.0.12
- name: github-status-resource
type: registry-image
type: docker-image
source:
repository: dpb587/github-status-resource
tag: master
- name: slack-notification
type: registry-image
type: docker-image
source:
repository: cfcommunity/slack-notification-resource
tag: latest
@@ -87,6 +87,12 @@ resources:
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-jdk11-ci-image
- name: spring-framework-jdk14-ci-image
type: docker-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-jdk14-ci-image
- name: spring-framework-jdk15-ci-image
type: docker-image
icon: docker
@@ -117,6 +123,14 @@ resources:
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk11-build
- name: repo-status-jdk14-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk14-build
- name: repo-status-jdk15-build
type: github-status-resource
icon: eye-check-outline
@@ -162,6 +176,10 @@ jobs:
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk11-ci-image/Dockerfile
- put: spring-framework-jdk14-ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk14-ci-image/Dockerfile
- put: spring-framework-jdk15-ci-image
params:
build: ci-images-git-repo/ci/images
@@ -250,6 +268,34 @@ jobs:
<<: *slack-fail-params
- put: repo-status-jdk11-build
params: { state: "success", commit: "git-repo" }
- name: jdk14-build
serial: true
public: true
plan:
- get: spring-framework-jdk14-ci-image
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk14-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
privileged: true
timeout: ((task-timeout))
image: spring-framework-jdk14-ci-image
file: git-repo/ci/tasks/check-project.yml
params:
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
on_failure:
do:
- put: repo-status-jdk14-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk14-build
params: { state: "success", commit: "git-repo" }
- name: jdk15-build
serial: true
public: true
@@ -434,7 +480,7 @@ jobs:
groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk15-build"]
jobs: ["build", "jdk11-build", "jdk14-build", "jdk15-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone","promote-rc", "promote-release", "sync-to-maven-central"]
- name: "ci-images"
+2 -2
View File
@@ -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 /opt/concourse-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
java -jar /opt/concourse-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
java -jar /opt/concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
distribute $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
distribute $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
echo "Promotion complete"
echo $version > version/version
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.4
version=5.3.1
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+2 -2
View File
@@ -3,7 +3,7 @@ configurations {
}
dependencies {
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.5.0")
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.3.RELEASE")
}
repositories {
@@ -113,7 +113,7 @@ dokka {
}
task downloadResources(type: Download) {
def version = "0.2.5"
def version = "0.2.2.RELEASE"
src "https://repo.spring.io/release/io/spring/docresources/" +
"spring-doc-resources/$version/spring-doc-resources-${version}.zip"
dest project.file("$buildDir/docs/spring-doc-resources.zip")
+2 -10
View File
@@ -29,11 +29,12 @@ eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
}
// Use separate main/test outputs (prevents WTP from packaging test classes)
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
eclipse.classpath.file.beforeMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
if (it.output.startsWith("bin/")) {
if(it.output.startsWith("bin/")) {
it.output = null
}
}
@@ -55,15 +56,6 @@ eclipse.classpath.file.whenMerged { classpath ->
}
}
// Ensure that JMH sources and resources are treated as test classpath entries
// so that they can see test fixtures.
// https://github.com/melix/jmh-gradle-plugin/issues/157
eclipse.classpath.file.whenMerged {
entries.findAll { it.path =~ /src\/jmh\/(java|resources)/ }.each {
it.entryAttributes['test'] = 'true'
}
}
// Allow projects to be used as WTP modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
+2 -22
View File
@@ -1,37 +1,17 @@
apply plugin: 'org.springframework.build.compile'
apply plugin: 'org.springframework.build.optional-dependencies'
// Uncomment the following for Shadow support in the jmhJar block.
// Currently commented out due to ZipException: archive is not a ZIP archive
// apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'me.champeau.gradle.jmh'
apply from: "$rootDir/gradle/publications.gradle"
dependencies {
jmh 'org.openjdk.jmh:jmh-core:1.25'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.25'
jmh 'org.openjdk.jmh:jmh-core:1.23'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.23'
jmh 'net.sf.jopt-simple:jopt-simple:4.6'
}
jmh {
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}
jmhJar {
// Uncomment the following for Shadow's Transformer support.
// mergeServiceFiles()
// append('META-INF/spring.handlers')
// append('META-INF/spring.schemas')
// append('META-INF/spring.tooling')
exclude 'LICENSE'
exclude 'THIRD-PARTY'
exclude 'META-INF/license.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE*'
exclude 'META-INF/NOTICE'
exclude 'META-INF/THIRD-PARTY'
}
jar {
manifest.attributes["Implementation-Title"] = project.name
manifest.attributes["Implementation-Version"] = project.version
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+2 -2
View File
@@ -6,8 +6,8 @@ pluginManagement {
}
plugins {
id "com.gradle.enterprise" version "3.5.1"
id "io.spring.ge.conventions" version "0.0.7"
id "com.gradle.enterprise" version "3.2"
id "io.spring.gradle-enterprise-conventions" version "0.0.2"
}
include "spring-aop"
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -350,8 +350,17 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return this.discoveredThrowingType;
}
private static boolean isVariableName(String name) {
return AspectJProxyUtils.isVariableName(name);
private boolean isVariableName(String name) {
char[] chars = name.toCharArray();
if (!Character.isJavaIdentifierStart(chars[0])) {
return false;
}
for (int i = 1; i < chars.length; i++) {
if (!Character.isJavaIdentifierPart(chars[i])) {
return false;
}
}
return true;
}
@@ -631,6 +640,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
@@ -470,10 +470,22 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
*/
@Nullable
private String maybeExtractVariableName(@Nullable String candidateToken) {
if (AspectJProxyUtils.isVariableName(candidateToken)) {
if (!StringUtils.hasLength(candidateToken)) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
Character.isLowerCase(candidateToken.charAt(0))) {
char[] tokenChars = candidateToken.toCharArray();
for (char tokenChar : tokenChars) {
if (!Character.isJavaIdentifierPart(tokenChar)) {
return null;
}
}
return candidateToken;
}
return null;
else {
return null;
}
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -21,8 +21,6 @@ import java.util.List;
import org.springframework.aop.Advisor;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* Utility methods for working with AspectJ proxies.
@@ -75,19 +73,4 @@ public abstract class AspectJProxyUtils {
((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
}
static boolean isVariableName(@Nullable String name) {
if (!StringUtils.hasLength(name)) {
return false;
}
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
return false;
}
for (int i = 1; i < name.length(); i++) {
if (!Character.isJavaIdentifierPart(name.charAt(i))) {
return false;
}
}
return true;
}
}
@@ -51,7 +51,6 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.util.StringUtils;
import org.springframework.util.comparator.InstanceComparator;
@@ -71,11 +70,7 @@ import org.springframework.util.comparator.InstanceComparator;
@SuppressWarnings("serial")
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
// Exclude @Pointcut methods
private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
.and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
private static final Comparator<Method> adviceMethodComparator;
private static final Comparator<Method> METHOD_COMPARATOR;
static {
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
@@ -91,7 +86,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
}
@@ -165,10 +160,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(adviceMethodComparator);
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
@@ -48,7 +48,6 @@ import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.core.KotlinDetector;
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -753,17 +752,10 @@ class CglibAopProxy implements AopProxy, Serializable {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
// Propagate original exception if declared on the target method
// (with callers expecting it). Always propagate it for Kotlin code
// since checked exceptions do not have to be explicitly declared there.
if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) {
throw ex;
}
else {
// Checked exception thrown in the interceptor but not declared on the
// target method signature -> apply an UndeclaredThrowableException,
// aligned with standard JDK dynamic proxy behavior.
throw new UndeclaredThrowableException(ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -20,7 +20,6 @@ import java.io.Serializable;
import java.lang.reflect.Proxy;
import org.springframework.aop.SpringProxy;
import org.springframework.core.NativeDetector;
/**
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
@@ -48,10 +47,17 @@ import org.springframework.core.NativeDetector;
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
if (!IN_NATIVE_IMAGE &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -116,7 +116,7 @@ public abstract class AbstractPoolingTargetSource extends AbstractPrototypeBased
/**
* Return an IntroductionAdvisor that provides a mixin
* Return an IntroductionAdvisor that providing a mixin
* exposing statistics about the pool maintained by this object.
*/
public DefaultIntroductionAdvisor getPoolingConfigMixin() {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -59,8 +59,7 @@ public abstract aspect AbstractTransactionAspect extends TransactionAspectSuppor
@Override
public void destroy() {
// An aspect is basically a singleton -> cleanup on destruction
clearTransactionManagerCache();
clearTransactionManagerCache(); // An aspect is basically a singleton
}
@SuppressAjWarnings("adviceDidNotMatch")
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
<bean id="bean1" class="org.springframework.beans.factory.ConcurrentBeanFactoryBenchmark$ConcurrentBean"
<beans>
<bean id="bean1" class="org.springframework.beans.factory.ConcurrentBeanFactoryTests$ConcurrentBean"
scope="prototype">
<property name="date" value="2004/08/08"/>
</bean>
<bean id="bean2" class="org.springframework.beans.factory.ConcurrentBeanFactoryBenchmark$ConcurrentBean"
<bean id="bean2" class="org.springframework.beans.factory.ConcurrentBeanFactoryTests$ConcurrentBean"
scope="prototype">
<property name="date" value="2000/02/02"/>
</bean>
@@ -268,7 +268,10 @@ public abstract class BeanUtils {
public static <T> Constructor<T> findPrimaryConstructor(Class<T> clazz) {
Assert.notNull(clazz, "Class must not be null");
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(clazz)) {
return KotlinDelegate.findPrimaryConstructor(clazz);
Constructor<T> kotlinPrimaryConstructor = KotlinDelegate.findPrimaryConstructor(clazz);
if (kotlinPrimaryConstructor != null) {
return kotlinPrimaryConstructor;
}
}
return null;
}
@@ -540,7 +543,6 @@ public abstract class BeanUtils {
if (targetType == null || targetType.isArray() || unknownEditorTypes.contains(targetType)) {
return null;
}
ClassLoader cl = targetType.getClassLoader();
if (cl == null) {
try {
@@ -557,34 +559,28 @@ public abstract class BeanUtils {
return null;
}
}
String targetTypeName = targetType.getName();
String editorName = targetTypeName + "Editor";
try {
Class<?> editorClass = cl.loadClass(editorName);
if (editorClass != null) {
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
unknownEditorTypes.add(targetType);
return null;
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
return (PropertyEditor) instantiateClass(editorClass);
unknownEditorTypes.add(targetType);
return null;
}
// Misbehaving ClassLoader returned null instead of ClassNotFoundException
// - fall back to unknown editor type registration below
return (PropertyEditor) instantiateClass(editorClass);
}
catch (ClassNotFoundException ex) {
// Ignore - fall back to unknown editor type registration below
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
}
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
}
/**
@@ -776,14 +772,7 @@ public abstract class BeanUtils {
if (readMethod != null) {
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);
ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);
// Ignore generic types in assignable check if either ResolvableType has unresolvable generics.
boolean isAssignable =
(sourceResolvableType.hasUnresolvableGenerics() || targetResolvableType.hasUnresolvableGenerics() ?
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) :
targetResolvableType.isAssignableFrom(sourceResolvableType));
if (isAssignable) {
if (targetResolvableType.isAssignableFrom(sourceResolvableType)) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -41,10 +41,10 @@ public class TypeMismatchException extends PropertyAccessException {
private String propertyName;
@Nullable
private final transient Object value;
private transient Object value;
@Nullable
private final Class<?> requiredType;
private Class<?> requiredType;
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -628,58 +628,45 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
value = resolveFieldValue(field, bean, beanName);
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
}
@@ -708,16 +695,58 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
if (arguments != null) {
try {
@@ -742,59 +771,6 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
}
return arguments;
}
@Nullable
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
int argumentCount = method.getParameterCount();
Object[] arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
return arguments;
}
}
@@ -141,7 +141,8 @@ public class InjectionMetadata {
* Return an {@code InjectionMetadata} instance, possibly for empty elements.
* @param elements the elements to inject (possibly empty)
* @param clazz the target class
* @return a new {@link #InjectionMetadata(Class, Collection)} instance
* @return a new {@link #InjectionMetadata(Class, Collection)} instance,
* or {@link #EMPTY} in case of no elements
* @since 5.2
*/
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -52,7 +52,6 @@ import org.springframework.util.StringUtils;
* @author Dave Syer
* @author Juergen Hoeller
* @author Sam Brannen
* @author Brian Clozel
* @since 4.1
*/
public abstract class YamlProcessor {
@@ -129,11 +128,10 @@ public abstract class YamlProcessor {
/**
* Set the supported types that can be loaded from YAML documents.
* <p>If no supported types are configured, only Java standard classes
* (as defined in {@link org.yaml.snakeyaml.constructor.SafeConstructor})
* encountered in YAML documents will be supported.
* If an unsupported type is encountered, an {@link IllegalStateException}
* will be thrown when the corresponding YAML node is processed.
* <p>If no supported types are configured, all types encountered in YAML
* documents will be supported. If an unsupported type is encountered, an
* {@link IllegalStateException} will be thrown when the corresponding YAML
* node is processed.
* @param supportedTypes the supported types, or an empty array to clear the
* supported types
* @since 5.1.16
@@ -184,8 +182,12 @@ public abstract class YamlProcessor {
protected Yaml createYaml() {
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false);
return new Yaml(new FilteringConstructor(loaderOptions), new Representer(),
new DumperOptions(), loaderOptions);
if (!this.supportedTypes.isEmpty()) {
return new Yaml(new FilteringConstructor(loaderOptions), new Representer(),
new DumperOptions(), loaderOptions);
}
return new Yaml(loaderOptions);
}
private boolean process(MatchCallback callback, Yaml yaml, Resource resource) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -73,7 +73,6 @@ import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.NamedThreadLocal;
import org.springframework.core.NativeDetector;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.ResolvableType;
@@ -124,6 +123,14 @@ import org.springframework.util.StringUtils;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
/** Strategy for creating bean instances. */
private InstantiationStrategy instantiationStrategy;
@@ -177,7 +184,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
if (NativeDetector.inNativeImage()) {
if (IN_NATIVE_IMAGE) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
@@ -1015,11 +1022,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
throw ex;
}
catch (BeanCreationException ex) {
// Don't swallow a linkage error since it contains a full stacktrace on
// first occurrence... and just a plain NoClassDefFoundError afterwards.
if (ex.contains(LinkageError.class)) {
throw ex;
}
// Instantiation failure, maybe too early...
if (logger.isDebugEnabled()) {
logger.debug("Bean creation exception on singleton FactoryBean type check: " + ex);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -1194,8 +1194,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
this.primary == that.primary &&
this.nonPublicAccessAllowed == that.nonPublicAccessAllowed &&
this.lenientConstructorResolution == that.lenientConstructorResolution &&
equalsConstructorArgumentValues(that) &&
equalsPropertyValues(that) &&
ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues) &&
ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues) &&
ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
@@ -1208,30 +1208,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
super.equals(other));
}
private boolean equalsConstructorArgumentValues(AbstractBeanDefinition other) {
if (!hasConstructorArgumentValues()) {
return !other.hasConstructorArgumentValues();
}
return ObjectUtils.nullSafeEquals(this.constructorArgumentValues, other.constructorArgumentValues);
}
private boolean equalsPropertyValues(AbstractBeanDefinition other) {
if (!hasPropertyValues()) {
return !other.hasPropertyValues();
}
return ObjectUtils.nullSafeEquals(this.propertyValues, other.propertyValues);
}
@Override
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
if (hasConstructorArgumentValues()) {
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
}
if (hasPropertyValues()) {
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
}
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
hashCode = 29 * hashCode + super.hashCode();
@@ -250,7 +250,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
@@ -264,7 +264,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
@@ -342,7 +342,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
@@ -355,7 +355,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
@@ -377,7 +377,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
@@ -395,19 +395,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
@SuppressWarnings("unchecked")
<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return (T) convertedBean;
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
@@ -67,7 +67,6 @@ import org.springframework.util.StringUtils;
/**
* Delegate for resolving constructors and factory methods.
*
* <p>Performs constructor resolution through argument matching.
*
* @author Juergen Hoeller
@@ -86,7 +85,7 @@ class ConstructorResolver {
private static final Object[] EMPTY_ARGS = new Object[0];
/**
* Marker for autowired arguments in a cached argument array, to be replaced
* Marker for autowired arguments in a cached argument array, to be later replaced
* by a {@linkplain #resolveAutowiredArgument resolved autowired argument}.
*/
private static final Object autowiredArgumentMarker = new Object();
@@ -150,7 +149,7 @@ class ConstructorResolver {
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
@@ -411,7 +410,6 @@ class ConstructorResolver {
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
factoryClass = factoryBean.getClass();
isStatic = false;
}
@@ -446,7 +444,7 @@ class ConstructorResolver {
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
@@ -818,7 +816,7 @@ class ConstructorResolver {
* Resolve the prepared arguments stored in the given bean definition.
*/
private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
Executable executable, Object[] argsToResolve) {
Executable executable, Object[] argsToResolve, boolean fallback) {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
@@ -831,7 +829,7 @@ class ConstructorResolver {
Object argValue = argsToResolve[argIndex];
MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
if (argValue == autowiredArgumentMarker) {
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, true);
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, fallback);
}
else if (argValue instanceof BeanMetadataElement) {
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
@@ -1231,7 +1231,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
if (candidateNames.length == 1) {
return resolveNamedBean(candidateNames[0], requiredType, args);
String beanName = candidateNames[0];
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
@@ -1250,11 +1251,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance == null) {
return null;
}
if (beanInstance instanceof Class) {
return resolveNamedBean(candidateName, requiredType, args);
if (beanInstance == null || beanInstance instanceof Class) {
beanInstance = getBean(candidateName, requiredType.toClass(), args);
}
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
}
@@ -1266,17 +1264,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return null;
}
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
String beanName, ResolvableType requiredType, @Nullable Object[] args) throws BeansException {
Object bean = getBean(beanName, null, args);
if (bean instanceof NullBean) {
return null;
}
return new NamedBeanHolder<T>(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass()));
}
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -119,16 +119,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
@@ -172,6 +170,66 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
/**
* If the current value of the given beanDefinition's "destroyMethodName" property is
* {@link AbstractBeanDefinition#INFER_METHOD}, then attempt to infer a destroy method.
* Candidate methods are currently limited to public, no-arg methods named "close" or
* "shutdown" (whether declared locally or inherited). The given BeanDefinition's
* "destroyMethodName" is updated to be null if no such method is found, otherwise set
* to the name of the inferred method. This constant serves as the default for the
* {@code @Bean#destroyMethod} attribute and the value of the constant may also be
* used in XML within the {@code <bean destroy-method="">} or {@code
* <beans default-destroy-method="">} attributes.
* <p>Also processes the {@link java.io.Closeable} and {@link java.lang.AutoCloseable}
* interfaces, reflectively calling the "close" method on implementing beans as well.
*/
@Nullable
private String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
if (!(bean instanceof DisposableBean)) {
try {
return bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
return bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
return null;
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
/**
* Search for all DestructionAwareBeanPostProcessors in the List.
* @param processors the List to search
* @return the filtered List of DestructionAwareBeanPostProcessors
*/
@Nullable
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(
List<DestructionAwareBeanPostProcessor> processors, Object bean) {
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
if (!CollectionUtils.isEmpty(processors)) {
filteredPostProcessors = new ArrayList<>(processors.size());
for (DestructionAwareBeanPostProcessor processor : processors) {
if (processor.requiresDestruction(bean)) {
filteredPostProcessors.add(processor);
}
}
}
return filteredPostProcessors;
}
@Override
public void run() {
destroy();
@@ -326,50 +384,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
}
/**
* If the current value of the given beanDefinition's "destroyMethodName" property is
* {@link AbstractBeanDefinition#INFER_METHOD}, then attempt to infer a destroy method.
* Candidate methods are currently limited to public, no-arg methods named "close" or
* "shutdown" (whether declared locally or inherited). The given BeanDefinition's
* "destroyMethodName" is updated to be null if no such method is found, otherwise set
* to the name of the inferred method. This constant serves as the default for the
* {@code @Bean#destroyMethod} attribute and the value of the constant may also be
* used in XML within the {@code <bean destroy-method="">} or {@code
* <beans default-destroy-method="">} attributes.
* <p>Also processes the {@link java.io.Closeable} and {@link java.lang.AutoCloseable}
* interfaces, reflectively calling the "close" method on implementing beans as well.
*/
@Nullable
private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
try {
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
return StringUtils.hasLength(destroyMethodName);
}
/**
@@ -388,25 +408,4 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
return false;
}
/**
* Search for all DestructionAwareBeanPostProcessors in the List.
* @param processors the List to search
* @return the filtered List of DestructionAwareBeanPostProcessors
*/
@Nullable
private static List<DestructionAwareBeanPostProcessor> filterPostProcessors(
List<DestructionAwareBeanPostProcessor> processors, Object bean) {
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
if (!CollectionUtils.isEmpty(processors)) {
filteredPostProcessors = new ArrayList<>(processors.size());
for (DestructionAwareBeanPostProcessor processor : processors) {
if (processor.requiresDestruction(bean)) {
filteredPostProcessors.add(processor);
}
}
}
return filteredPostProcessors;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -86,10 +86,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
@Nullable
volatile Method factoryMethodToIntrospect;
/** Package-visible field for caching a resolved destroy method name (also for inferred). */
@Nullable
volatile String resolvedDestroyMethodName;
/** Common lock for the four constructor fields below. */
final Object constructorArgumentLock = new Object();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -19,16 +19,12 @@ package org.springframework.beans;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.net.URL;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -200,29 +196,6 @@ class BeanUtilsTests {
assertThat(longListHolder.getList()).isEmpty();
}
@Test // gh-26531
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() throws Exception {
Order original = new Order("test", Arrays.asList("foo", "bar"));
// Create a Proxy that loses the generic type information for the getLineItems() method.
OrderSummary proxy = proxyOrder(original);
assertThat(OrderSummary.class.getDeclaredMethod("getLineItems").toGenericString())
.contains("java.util.List<java.lang.String>");
assertThat(proxy.getClass().getDeclaredMethod("getLineItems").toGenericString())
.contains("java.util.List")
.doesNotContain("<java.lang.String>");
// Ensure that our custom Proxy works as expected.
assertThat(proxy.getId()).isEqualTo("test");
assertThat(proxy.getLineItems()).containsExactly("foo", "bar");
// Copy from proxy to target.
Order target = new Order();
BeanUtils.copyProperties(proxy, target);
assertThat(target.getId()).isEqualTo("test");
assertThat(target.getLineItems()).containsExactly("foo", "bar");
}
@Test
void copyPropertiesWithEditable() throws Exception {
TestBean tb = new TestBean();
@@ -660,77 +633,4 @@ class BeanUtilsTests {
}
}
@SuppressWarnings("unused")
private static class Order {
private String id;
private List<String> lineItems;
Order() {
}
Order(String id, List<String> lineItems) {
this.id = id;
this.lineItems = lineItems;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<String> getLineItems() {
return this.lineItems;
}
public void setLineItems(List<String> lineItems) {
this.lineItems = lineItems;
}
@Override
public String toString() {
return "Order [id=" + this.id + ", lineItems=" + this.lineItems + "]";
}
}
private interface OrderSummary {
String getId();
List<String> getLineItems();
}
private OrderSummary proxyOrder(Order order) {
return (OrderSummary) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<?>[] { OrderSummary.class }, new OrderInvocationHandler(order));
}
private static class OrderInvocationHandler implements InvocationHandler {
private final Order order;
OrderInvocationHandler(Order order) {
this.order = order;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// Ignore args since OrderSummary doesn't declare any methods with arguments,
// and we're not supporting equals(Object), etc.
return Order.class.getDeclaredMethod(method.getName()).invoke(this.order);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
@@ -63,8 +63,9 @@ public class BeanFactoryUtilsTests {
@BeforeEach
public void setup() {
public void setUp() {
// Interesting hierarchical factory to test counts.
// Slow to read so we cache it.
DefaultListableBeanFactory grandParent = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(grandParent).loadBeanDefinitions(ROOT_CONTEXT);
@@ -92,7 +93,7 @@ public class BeanFactoryUtilsTests {
* Check that override doesn't count as two separate beans.
*/
@Test
public void testHierarchicalCountBeansWithOverride() {
public void testHierarchicalCountBeansWithOverride() throws Exception {
// Leaf count
assertThat(this.listableBeanFactory.getBeanDefinitionCount() == 1).isTrue();
// Count minus duplicate
@@ -100,14 +101,14 @@ public class BeanFactoryUtilsTests {
}
@Test
public void testHierarchicalNamesWithNoMatch() {
public void testHierarchicalNamesWithNoMatch() throws Exception {
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, NoOp.class));
assertThat(names.size()).isEqualTo(0);
}
@Test
public void testHierarchicalNamesWithMatchOnlyInRoot() {
public void testHierarchicalNamesWithMatchOnlyInRoot() throws Exception {
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, IndexedTestBean.class));
assertThat(names.size()).isEqualTo(1);
@@ -117,7 +118,7 @@ public class BeanFactoryUtilsTests {
}
@Test
public void testGetBeanNamesForTypeWithOverride() {
public void testGetBeanNamesForTypeWithOverride() throws Exception {
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class));
// includes 2 TestBeans from FactoryBeans (DummyFactory definitions)
@@ -235,7 +236,7 @@ public class BeanFactoryUtilsTests {
}
@Test
public void testHierarchicalResolutionWithOverride() {
public void testHierarchicalResolutionWithOverride() throws Exception {
Object test3 = this.listableBeanFactory.getBean("test3");
Object test = this.listableBeanFactory.getBean("test");
@@ -275,14 +276,14 @@ public class BeanFactoryUtilsTests {
}
@Test
public void testHierarchicalNamesForAnnotationWithNoMatch() {
public void testHierarchicalNamesForAnnotationWithNoMatch() throws Exception {
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, Override.class));
assertThat(names.size()).isEqualTo(0);
}
@Test
public void testHierarchicalNamesForAnnotationWithMatchOnlyInRoot() {
public void testHierarchicalNamesForAnnotationWithMatchOnlyInRoot() throws Exception {
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, TestAnnotation.class));
assertThat(names.size()).isEqualTo(1);
@@ -292,7 +293,7 @@ public class BeanFactoryUtilsTests {
}
@Test
public void testGetBeanNamesForAnnotationWithOverride() {
public void testGetBeanNamesForAnnotationWithOverride() throws Exception {
AnnotatedBean annotatedBean = new AnnotatedBean();
this.listableBeanFactory.registerSingleton("anotherAnnotatedBean", annotatedBean);
List<String> names = Arrays.asList(
@@ -432,7 +433,6 @@ public class BeanFactoryUtilsTests {
String basePackage() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@ControllerAdvice
@interface RestControllerAdvice {
@@ -444,23 +444,18 @@ public class BeanFactoryUtilsTests {
String basePackage() default "";
}
@ControllerAdvice("com.example")
static class ControllerAdviceClass {
}
@RestControllerAdvice("com.example")
static class RestControllerAdviceClass {
}
static class TestBeanSmartFactoryBean implements SmartFactoryBean<TestBean> {
private final TestBean testBean = new TestBean("enigma", 42);
private final boolean singleton;
private final boolean prototype;
TestBeanSmartFactoryBean(boolean singleton, boolean prototype) {
@@ -483,7 +478,7 @@ public class BeanFactoryUtilsTests {
return TestBean.class;
}
public TestBean getObject() {
public TestBean getObject() throws Exception {
// We don't really care if the actual instance is a singleton or prototype
// for the tests that use this factory.
return this.testBean;
@@ -785,13 +785,12 @@ class DefaultListableBeanFactoryTests {
factory.registerBeanDefinition("child", childDefinition);
factory.registerAlias("parent", "alias");
TestBean child = factory.getBean("child", TestBean.class);
TestBean child = (TestBean) factory.getBean("child");
assertThat(child.getName()).isEqualTo(EXPECTED_NAME);
assertThat(child.getAge()).isEqualTo(EXPECTED_AGE);
BeanDefinition mergedBeanDefinition1 = factory.getMergedBeanDefinition("child");
BeanDefinition mergedBeanDefinition2 = factory.getMergedBeanDefinition("child");
Object mergedBeanDefinition2 = factory.getMergedBeanDefinition("child");
assertThat(mergedBeanDefinition1).as("Use cached merged bean definition").isSameAs(mergedBeanDefinition2);
assertThat(mergedBeanDefinition2).as("Use cached merged bean definition").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -1839,7 +1838,8 @@ class DefaultListableBeanFactoryTests {
assertThat(factoryBean).as("The FactoryBean should have been registered.").isNotNull();
FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
assertThat(bean.getFactoryBean()).as("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.").isEqualTo(factoryBean);
Object mergedBeanDefinition2 = bean.getFactoryBean();
assertThat(mergedBeanDefinition2).as("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -2388,7 +2388,8 @@ class DefaultListableBeanFactoryTests {
BeanWithDestroyMethod.closeCount = 0;
lbf.preInstantiateSingletons();
lbf.destroySingletons();
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(1);
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -2402,7 +2403,8 @@ class DefaultListableBeanFactoryTests {
BeanWithDestroyMethod.closeCount = 0;
lbf.preInstantiateSingletons();
lbf.destroySingletons();
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(2);
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -2417,7 +2419,8 @@ class DefaultListableBeanFactoryTests {
BeanWithDestroyMethod.closeCount = 0;
lbf.preInstantiateSingletons();
lbf.destroySingletons();
assertThat(BeanWithDestroyMethod.closeCount).as("Destroy methods invoked").isEqualTo(1);
Object mergedBeanDefinition2 = BeanWithDestroyMethod.closeCount;
assertThat(mergedBeanDefinition2).as("Destroy methods invoked").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -2539,15 +2542,14 @@ class DefaultListableBeanFactoryTests {
factory.registerBeanDefinition("child", child);
AbstractBeanDefinition def = (AbstractBeanDefinition) factory.getBeanDefinition("child");
assertThat(def.getScope()).as("Child 'scope' not overriding parent scope (it must).").isEqualTo(theChildScope);
Object mergedBeanDefinition2 = def.getScope();
assertThat(mergedBeanDefinition2).as("Child 'scope' not overriding parent scope (it must).").isEqualTo(mergedBeanDefinition2);
}
@Test
void scopeInheritanceForChildBeanDefinitions() {
String theParentScope = "bonanza!";
RootBeanDefinition parent = new RootBeanDefinition();
parent.setScope(theParentScope);
parent.setScope("bonanza!");
AbstractBeanDefinition child = new ChildBeanDefinition("parent");
child.setBeanClass(TestBean.class);
@@ -2557,7 +2559,8 @@ class DefaultListableBeanFactoryTests {
factory.registerBeanDefinition("child", child);
BeanDefinition def = factory.getMergedBeanDefinition("child");
assertThat(def.getScope()).as("Child 'scope' not inherited").isEqualTo(theParentScope);
Object mergedBeanDefinition2 = def.getScope();
assertThat(mergedBeanDefinition2).as("Child 'scope' not inherited").isEqualTo(mergedBeanDefinition2);
}
@Test
@@ -2593,12 +2596,15 @@ class DefaultListableBeanFactoryTests {
});
lbf.preInstantiateSingletons();
TestBean tb = (TestBean) lbf.getBean("test");
assertThat(tb.getName()).as("Name was set on field by IAPP").isEqualTo(nameSetOnField);
Object mergedBeanDefinition2 = tb.getName();
assertThat(mergedBeanDefinition2).as("Name was set on field by IAPP").isEqualTo(mergedBeanDefinition2);
if (!skipPropertyPopulation) {
assertThat(tb.getAge()).as("Property value still set").isEqualTo(ageSetByPropertyValue);
Object mergedBeanDefinition21 = tb.getAge();
assertThat(mergedBeanDefinition21).as("Property value still set").isEqualTo(mergedBeanDefinition21);
}
else {
assertThat(tb.getAge()).as("Property value was NOT set and still has default value").isEqualTo(0);
Object mergedBeanDefinition21 = tb.getAge();
assertThat(mergedBeanDefinition21).as("Property value was NOT set and still has default value").isEqualTo(mergedBeanDefinition21);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -297,121 +297,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
}
@Test
public void testOptionalResourceInjectionWithSingletonRemoval() {
RootBeanDefinition rbd = new RootBeanDefinition(OptionalResourceInjectionBean.class);
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", rbd);
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
IndexedTestBean itb = new IndexedTestBean();
bf.registerSingleton("indexedTestBean", itb);
NestedTestBean ntb1 = new NestedTestBean();
bf.registerSingleton("nestedTestBean1", ntb1);
NestedTestBean ntb2 = new NestedTestBean();
bf.registerSingleton("nestedTestBean2", ntb2);
OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
bf.destroySingleton("testBean");
bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isNull();
assertThat(bean.getTestBean2()).isNull();
assertThat(bean.getTestBean3()).isNull();
assertThat(bean.getTestBean4()).isNull();
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
bf.registerSingleton("testBean", tb);
bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
}
@Test
public void testOptionalResourceInjectionWithBeanDefinitionRemoval() {
RootBeanDefinition rbd = new RootBeanDefinition(OptionalResourceInjectionBean.class);
rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", rbd);
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
IndexedTestBean itb = new IndexedTestBean();
bf.registerSingleton("indexedTestBean", itb);
NestedTestBean ntb1 = new NestedTestBean();
bf.registerSingleton("nestedTestBean1", ntb1);
NestedTestBean ntb2 = new NestedTestBean();
bf.registerSingleton("nestedTestBean2", ntb2);
OptionalResourceInjectionBean bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean2()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean3()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean4()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
bf.removeBeanDefinition("testBean");
bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isNull();
assertThat(bean.getTestBean2()).isNull();
assertThat(bean.getTestBean3()).isNull();
assertThat(bean.getTestBean4()).isNull();
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
bean = (OptionalResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean2()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean3()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getTestBean4()).isSameAs(bf.getBean("testBean"));
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
}
@Test
public void testOptionalCollectionResourceInjection() {
RootBeanDefinition rbd = new RootBeanDefinition(OptionalCollectionResourceInjectionBean.class);
@@ -648,83 +533,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
assertThat(bean.getBeanFactory()).isSameAs(bf);
}
@Test
public void testConstructorResourceInjectionWithSingletonRemoval() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", bd);
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
NestedTestBean ntb = new NestedTestBean();
bf.registerSingleton("nestedTestBean", ntb);
ConstructorResourceInjectionBean bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isSameAs(ntb);
assertThat(bean.getBeanFactory()).isSameAs(bf);
bf.destroySingleton("nestedTestBean");
bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isNull();
assertThat(bean.getBeanFactory()).isSameAs(bf);
bf.registerSingleton("nestedTestBean", ntb);
bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isSameAs(ntb);
assertThat(bean.getBeanFactory()).isSameAs(bf);
}
@Test
public void testConstructorResourceInjectionWithBeanDefinitionRemoval() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", bd);
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
bf.registerBeanDefinition("nestedTestBean", new RootBeanDefinition(NestedTestBean.class));
ConstructorResourceInjectionBean bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isSameAs(bf.getBean("nestedTestBean"));
assertThat(bean.getBeanFactory()).isSameAs(bf);
bf.removeBeanDefinition("nestedTestBean");
bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isNull();
assertThat(bean.getBeanFactory()).isSameAs(bf);
bf.registerBeanDefinition("nestedTestBean", new RootBeanDefinition(NestedTestBean.class));
bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb);
assertThat(bean.getTestBean3()).isSameAs(tb);
assertThat(bean.getTestBean4()).isSameAs(tb);
assertThat(bean.getNestedTestBean()).isSameAs(bf.getBean("nestedTestBean"));
assertThat(bean.getBeanFactory()).isSameAs(bf);
}
@Test
public void testConstructorResourceInjectionWithNullFromFactoryBean() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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,11 +17,9 @@
package org.springframework.beans.factory.config;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.constructor.ConstructorException;
@@ -30,6 +28,7 @@ import org.yaml.snakeyaml.scanner.ScannerException;
import org.springframework.core.io.ByteArrayResource;
import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.entry;
@@ -40,12 +39,10 @@ import static org.assertj.core.api.Assertions.entry;
* @author Dave Syer
* @author Juergen Hoeller
* @author Sam Brannen
* @author Brian Clozel
*/
class YamlProcessorTests {
private final YamlProcessor processor = new YamlProcessor() {
};
private final YamlProcessor processor = new YamlProcessor() {};
@Test
@@ -82,8 +79,8 @@ class YamlProcessorTests {
void badResource() {
setYaml("foo: bar\ncd\nspam:\n foo: baz");
assertThatExceptionOfType(ScannerException.class)
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("line 3, column 1");
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("line 3, column 1");
}
@Test
@@ -130,8 +127,8 @@ class YamlProcessorTests {
Map<String, Object> bar = (Map<String, Object>) map.get("bar");
assertThat(bar.get("spam")).isEqualTo("bucket");
List<Object> keysFromProperties = new ArrayList<>(properties.keySet());
List<String> keysFromFlattenedMap = new ArrayList<>(flattenedMap.keySet());
List<Object> keysFromProperties = properties.keySet().stream().collect(toList());
List<String> keysFromFlattenedMap = flattenedMap.keySet().stream().collect(toList());
assertThat(keysFromProperties).containsExactlyInAnyOrderElementsOf(keysFromFlattenedMap);
// Keys in the Properties object are sorted.
assertThat(keysFromProperties).containsExactly("bar.spam", "cat", "foo");
@@ -141,23 +138,14 @@ class YamlProcessorTests {
}
@Test
void standardTypesSupportedByDefault() throws Exception {
setYaml("value: !!set\n ? first\n ? second");
this.processor.process((properties, map) -> {
assertThat(properties).containsExactly(entry("value[0]", "first"), entry("value[1]", "second"));
assertThat(map.get("value")).isInstanceOf(Set.class);
Set<String> set = (Set<String>) map.get("value");
assertThat(set).containsExactly("first", "second");
});
}
@Test
void customTypeNotSupportedByDefault() throws Exception {
void customTypeSupportedByDefault() throws Exception {
URL url = new URL("https://localhost:9000/");
setYaml("value: !!java.net.URL [\"" + url + "\"]");
assertThatExceptionOfType(ConstructorException.class)
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("Unsupported type encountered in YAML document: java.net.URL");
this.processor.process((properties, map) -> {
assertThat(properties).containsExactly(entry("value", url));
assertThat(map).containsExactly(entry("value", url));
});
}
@Test
@@ -180,8 +168,8 @@ class YamlProcessorTests {
setYaml("value: !!java.net.URL [\"https://localhost:9000/\"]");
assertThatExceptionOfType(ConstructorException.class)
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("Unsupported type encountered in YAML document: java.net.URL");
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("Unsupported type encountered in YAML document: java.net.URL");
}
private void setYaml(String yaml) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -133,16 +133,6 @@ public class BeanDefinitionTests {
assertThat(bd.equals(otherBd)).isTrue();
assertThat(otherBd.equals(bd)).isTrue();
assertThat(bd.hashCode() == otherBd.hashCode()).isTrue();
bd.getPropertyValues();
assertThat(bd.equals(otherBd)).isTrue();
assertThat(otherBd.equals(bd)).isTrue();
assertThat(bd.hashCode() == otherBd.hashCode()).isTrue();
bd.getConstructorArgumentValues();
assertThat(bd.equals(otherBd)).isTrue();
assertThat(otherBd.equals(bd)).isTrue();
assertThat(bd.hashCode() == otherBd.hashCode()).isTrue();
}
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -31,8 +31,7 @@ import org.springframework.core.annotation.AliasFor;
*
* <p>In contrast to the {@link Cacheable @Cacheable} annotation, this annotation
* does not cause the advised method to be skipped. Rather, it always causes the
* method to be invoked and its result to be stored in the associated cache if the
* {@link #condition()} and {@link #unless()} expressions match accordingly. Note
* method to be invoked and its result to be stored in the associated cache. Note
* that Java8's {@code Optional} return types are automatically handled and its
* content is stored in the cache if present.
*
@@ -119,15 +118,10 @@ public @interface CachePut {
/**
* Spring Expression Language (SpEL) expression used for making the cache
* put operation conditional.
* <p>This expression is evaluated after the method has been called due to the
* nature of the put operation and can therefore refer to the {@code result}.
* <p>Default is {@code ""}, meaning the method result is always cached.
* <p>The SpEL expression evaluates against a dedicated context that provides the
* following meta-data:
* <ul>
* <li>{@code #result} for a reference to the result of the method invocation. For
* supported wrappers such as {@code Optional}, {@code #result} refers to the actual
* object, not the wrapper</li>
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
* references to the {@link java.lang.reflect.Method method}, target object, and
* affected cache(s) respectively.</li>
@@ -142,6 +136,8 @@ public @interface CachePut {
/**
* Spring Expression Language (SpEL) expression used to veto the cache put operation.
* <p>Unlike {@link #condition}, this expression is evaluated after the method
* has been called and can therefore refer to the {@code result}.
* <p>Default is {@code ""}, meaning that caching is never vetoed.
* <p>The SpEL expression evaluates against a dedicated context that provides the
* following meta-data:
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -16,8 +16,6 @@
package org.springframework.context;
import java.util.function.Consumer;
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;
import org.springframework.util.Assert;
@@ -25,12 +23,11 @@ import org.springframework.util.Assert;
/**
* An {@link ApplicationEvent} that carries an arbitrary payload.
*
* <p>Mainly intended for internal use within the framework.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @since 4.2
* @param <T> the payload type of the event
* @see ApplicationEventPublisher#publishEvent(Object)
* @see ApplicationListener#forPayload(Consumer)
*/
@SuppressWarnings("serial")
public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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,10 +26,10 @@ import org.springframework.core.io.ResourceLoader;
* the {@link org.springframework.context.ApplicationContextAware} interface.
*
* <p>Note that {@link org.springframework.core.io.Resource} dependencies can also
* be exposed as bean properties of type {@code Resource} or {@code Resource[]},
* populated via Strings with automatic type conversion by the bean factory. This
* removes the need for implementing any callback interface just for the purpose
* of accessing specific file resources.
* be exposed as bean properties of type {@code Resource}, populated via Strings
* with automatic type conversion by the bean factory. This removes the need for
* implementing any callback interface just for the purpose of accessing a
* specific file resource.
*
* <p>You typically need a {@link ResourceLoader} when your application object has to
* access a variety of file resources whose names are calculated. A good strategy is
@@ -48,7 +48,7 @@ import org.springframework.core.io.ResourceLoader;
* default; see also the {@code ResourcePatternUtils.getResourcePatternResolver} method.
*
* <p>As an alternative to a {@code ResourcePatternResolver} dependency, consider
* exposing bean properties of type {@code Resource[]} array, populated via pattern
* exposing bean properties of type {@code Resource} array, populated via pattern
* Strings with automatic type conversion by the bean factory at binding time.
*
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -52,7 +52,6 @@ import org.springframework.context.ApplicationStartupAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration;
import org.springframework.core.NativeDetector;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.Environment;
@@ -105,6 +104,13 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private static final String IMPORT_REGISTRY_BEAN_NAME =
ConfigurationClassPostProcessor.class.getName() + ".importRegistry";
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
private final Log logger = LogFactory.getLog(getClass());
@@ -421,11 +427,15 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) {
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
enhanceConfigClasses.end();
return;
}
if (IN_NATIVE_IMAGE) {
throw new BeanDefinitionStoreException("@Configuration classes need to be marked as " +
"proxyBeanMethods=false. Found: " + configBeanDefs.keySet());
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -24,8 +24,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.core.ResolvableType;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;
import org.springframework.util.ErrorHandler;
@@ -57,7 +58,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
private ErrorHandler errorHandler;
@Nullable
private volatile Log lazyLogger;
private ApplicationStartup applicationStartup;
/**
@@ -126,6 +127,22 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
return this.errorHandler;
}
/**
* Set the {@link ApplicationStartup} to track event listener invocations during startup.
* @since 5.3
*/
public void setApplicationStartup(@Nullable ApplicationStartup applicationStartup) {
this.applicationStartup = applicationStartup;
}
/**
* Return the current application startup for this multicaster.
*/
@Nullable
public ApplicationStartup getApplicationStartup() {
return this.applicationStartup;
}
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
@@ -139,6 +156,16 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else if (this.applicationStartup != null) {
StartupStep invocationStep = this.applicationStartup.start("spring.event.invoke-listener");
invokeListener(listener, event);
invocationStep.tag("event", event::toString);
if (eventType != null) {
invocationStep.tag("eventType", eventType::toString);
}
invocationStep.tag("listener", listener::toString);
invocationStep.end();
}
else {
invokeListener(listener, event);
}
@@ -177,18 +204,12 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -66,7 +66,6 @@ import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
import org.springframework.core.NativeDetector;
import org.springframework.core.ResolvableType;
import org.springframework.core.SpringProperties;
import org.springframework.core.annotation.AnnotationUtils;
@@ -165,6 +164,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
@@ -705,7 +711,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
@@ -746,7 +752,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
@@ -809,7 +815,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
this.applicationEventMulticaster = simpleApplicationEventMulticaster;
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
@@ -937,7 +945,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
if (!IN_NATIVE_IMAGE) {
LiveBeansView.registerApplicationContext(this);
}
}
@@ -1048,7 +1056,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
logger.debug("Closing " + this);
}
if (!NativeDetector.inNativeImage()) {
if (!IN_NATIVE_IMAGE) {
LiveBeansView.unregisterApplicationContext(this);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -17,7 +17,6 @@
package org.springframework.context.support;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -75,11 +74,6 @@ class ContextTypeMatchClassLoader extends DecoratingClassLoader implements Smart
return (clazz.getClassLoader() instanceof ContextOverridingClassLoader);
}
@Override
public Class<?> publicDefineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) {
return defineClass(name, b, 0, b.length, protectionDomain);
}
/**
* ClassLoader to be created for each loaded class.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -59,19 +59,6 @@ final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
@@ -205,19 +192,6 @@ final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -106,6 +106,7 @@ public @interface DateTimeFormat {
/**
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX},
* e.g. "2000-10-31T01:30:00.000-05:00".
* <p>This is the default if no annotation value is specified.
*/
DATE_TIME,
@@ -19,13 +19,14 @@ package org.springframework.scheduling.support;
import java.time.DateTimeException;
import java.time.temporal.Temporal;
import java.time.temporal.ValueRange;
import java.util.BitSet;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Efficient bitwise-operator extension of {@link CronField}.
* Efficient {@link BitSet}-based extension of {@link CronField}.
* Created using the {@code parse*} methods.
*
* @author Arjen Poutsma
@@ -129,8 +130,8 @@ final class BitsCronField extends CronField {
result.setBits(range);
}
else {
String rangeStr = field.substring(0, slashPos);
String deltaStr = field.substring(slashPos + 1);
String rangeStr = value.substring(0, slashPos);
String deltaStr = value.substring(slashPos + 1);
ValueRange range = parseRange(rangeStr, type);
if (rangeStr.indexOf('-') == -1) {
range = ValueRange.of(range.getMinimum(), type.range().getMaximum());
@@ -1,97 +0,0 @@
/*
* 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.
* 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.scheduling.support;
import java.time.temporal.Temporal;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Extension of {@link CronField} that wraps an array of cron fields.
*
* @author Arjen Poutsma
* @since 5.3.3
*/
final class CompositeCronField extends CronField {
private final CronField[] fields;
private final String value;
private CompositeCronField(Type type, CronField[] fields, String value) {
super(type);
this.fields = fields;
this.value = value;
}
/**
* Composes the given fields into a {@link CronField}.
*/
public static CronField compose(CronField[] fields, Type type, String value) {
Assert.notEmpty(fields, "Fields must not be empty");
Assert.hasLength(value, "Value must not be empty");
if (fields.length == 1) {
return fields[0];
}
else {
return new CompositeCronField(type, fields, value);
}
}
@Nullable
@Override
public <T extends Temporal & Comparable<? super T>> T nextOrSame(T temporal) {
T result = null;
for (CronField field : this.fields) {
T candidate = field.nextOrSame(temporal);
if (result == null ||
candidate != null && candidate.compareTo(result) < 0) {
result = candidate;
}
}
return result;
}
@Override
public int hashCode() {
return this.value.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CompositeCronField)) {
return false;
}
CompositeCronField other = (CompositeCronField) o;
return type() == other.type() &&
this.value.equals(other.value);
}
@Override
public String toString() {
return type() + " '" + this.value + "'";
}
}
@@ -20,10 +20,8 @@ import java.time.DateTimeException;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.ValueRange;
import java.util.function.BiFunction;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -79,18 +77,11 @@ abstract class CronField {
* Parse the given value into a days of months {@code CronField}, the fourth entry of a cron expression.
*/
public static CronField parseDaysOfMonth(String value) {
if (!QuartzCronField.isQuartzDaysOfMonthField(value)) {
return BitsCronField.parseDaysOfMonth(value);
if (value.contains("L") || value.contains("W")) {
return QuartzCronField.parseDaysOfMonth(value);
}
else {
return parseList(value, Type.DAY_OF_MONTH, (field, type) -> {
if (QuartzCronField.isQuartzDaysOfMonthField(field)) {
return QuartzCronField.parseDaysOfMonth(field);
}
else {
return BitsCronField.parseDaysOfMonth(field);
}
});
return BitsCronField.parseDaysOfMonth(value);
}
}
@@ -107,32 +98,15 @@ abstract class CronField {
*/
public static CronField parseDaysOfWeek(String value) {
value = replaceOrdinals(value, DAYS);
if (!QuartzCronField.isQuartzDaysOfWeekField(value)) {
return BitsCronField.parseDaysOfWeek(value);
if (value.contains("L") || value.contains("#")) {
return QuartzCronField.parseDaysOfWeek(value);
}
else {
return parseList(value, Type.DAY_OF_WEEK, (field, type) -> {
if (QuartzCronField.isQuartzDaysOfWeekField(field)) {
return QuartzCronField.parseDaysOfWeek(field);
}
else {
return BitsCronField.parseDaysOfWeek(field);
}
});
return BitsCronField.parseDaysOfWeek(value);
}
}
private static CronField parseList(String value, Type type, BiFunction<String, Type, CronField> parseFieldFunction) {
Assert.hasLength(value, "Value must not be empty");
String[] fields = StringUtils.delimitedListToStringArray(value, ",");
CronField[] cronFields = new CronField[fields.length];
for (int i = 0; i < fields.length; i++) {
cronFields[i] = parseFieldFunction.apply(fields[i], type);
}
return CompositeCronField.compose(cronFields, type, value);
}
private static String replaceOrdinals(String value, String[] list) {
value = value.toUpperCase();
for (int i = 0; i < list.length; i++) {
@@ -38,6 +38,24 @@ import org.springframework.util.Assert;
*/
final class QuartzCronField extends CronField {
/**
* Temporal adjuster that returns the last weekday of the month.
*/
private static final TemporalAdjuster lastWeekdayOfMonth = temporal -> {
Temporal lastDayOfMonth = TemporalAdjusters.lastDayOfMonth().adjustInto(temporal);
int dayOfWeek = lastDayOfMonth.get(ChronoField.DAY_OF_WEEK);
if (dayOfWeek == 6) { // Saturday
return lastDayOfMonth.minus(1, ChronoUnit.DAYS);
}
else if (dayOfWeek == 7) { // Sunday
return lastDayOfMonth.minus(2, ChronoUnit.DAYS);
}
else {
return lastDayOfMonth;
}
};
private final Type rollForwardType;
private final TemporalAdjuster adjuster;
@@ -60,12 +78,6 @@ final class QuartzCronField extends CronField {
this.rollForwardType = rollForwardType;
}
/**
* Returns whether the given value is a Quartz day-of-month field.
*/
public static boolean isQuartzDaysOfMonthField(String value) {
return value.contains("L") || value.contains("W");
}
/**
* Parse the given value into a days of months {@code QuartzCronField}, the fourth entry of a cron expression.
@@ -79,11 +91,11 @@ final class QuartzCronField extends CronField {
throw new IllegalArgumentException("Unrecognized characters before 'L' in '" + value + "'");
}
else if (value.length() == 2 && value.charAt(1) == 'W') { // "LW"
adjuster = lastWeekdayOfMonth();
adjuster = lastWeekdayOfMonth;
}
else {
if (value.length() == 1) { // "L"
adjuster = lastDayOfMonth();
adjuster = TemporalAdjusters.lastDayOfMonth();
}
else { // "L-[0-9]+"
int offset = Integer.parseInt(value.substring(idx + 1));
@@ -113,13 +125,6 @@ final class QuartzCronField extends CronField {
throw new IllegalArgumentException("No 'L' or 'W' found in '" + value + "'");
}
/**
* Returns whether the given value is a Quartz day-of-week field.
*/
public static boolean isQuartzDaysOfWeekField(String value) {
return value.contains("L") || value.contains("#");
}
/**
* Parse the given value into a days of week {@code QuartzCronField}, the sixth entry of a cron expression.
* Expects a "L" or "#" in the given value.
@@ -137,7 +142,7 @@ final class QuartzCronField extends CronField {
}
else { // "[0-7]L"
DayOfWeek dayOfWeek = parseDayOfWeek(value.substring(0, idx));
adjuster = lastInMonth(dayOfWeek);
adjuster = TemporalAdjusters.lastInMonth(dayOfWeek);
}
return new QuartzCronField(Type.DAY_OF_WEEK, Type.DAY_OF_MONTH, adjuster, value);
}
@@ -153,17 +158,14 @@ final class QuartzCronField extends CronField {
// "[0-7]#[0-9]+"
DayOfWeek dayOfWeek = parseDayOfWeek(value.substring(0, idx));
int ordinal = Integer.parseInt(value.substring(idx + 1));
if (ordinal <= 0) {
throw new IllegalArgumentException("Ordinal '" + ordinal + "' in '" + value +
"' must be positive number ");
}
TemporalAdjuster adjuster = dayOfWeekInMonth(ordinal, dayOfWeek);
TemporalAdjuster adjuster = TemporalAdjusters.dayOfWeekInMonth(ordinal, dayOfWeek);
return new QuartzCronField(Type.DAY_OF_WEEK, Type.DAY_OF_MONTH, adjuster, value);
}
throw new IllegalArgumentException("No 'L' or '#' found in '" + value + "'");
}
private static DayOfWeek parseDayOfWeek(String value) {
int dayOfWeek = Integer.parseInt(value);
if (dayOfWeek == 0) {
@@ -178,54 +180,6 @@ final class QuartzCronField extends CronField {
}
}
/**
* Returns an adjuster that resets to midnight.
*/
private static TemporalAdjuster atMidnight() {
return temporal -> {
if (temporal.isSupported(ChronoField.NANO_OF_DAY)) {
return temporal.with(ChronoField.NANO_OF_DAY, 0);
}
else {
return temporal;
}
};
}
/**
* Returns an adjuster that returns a new temporal set to the last
* day of the current month at midnight.
*/
private static TemporalAdjuster lastDayOfMonth() {
TemporalAdjuster adjuster = TemporalAdjusters.lastDayOfMonth();
return temporal -> {
Temporal result = adjuster.adjustInto(temporal);
return rollbackToMidnight(temporal, result);
};
}
/**
* Returns an adjuster that returns the last weekday of the month.
*/
private static TemporalAdjuster lastWeekdayOfMonth() {
TemporalAdjuster adjuster = TemporalAdjusters.lastDayOfMonth();
return temporal -> {
Temporal lastDom = adjuster.adjustInto(temporal);
Temporal result;
int dow = lastDom.get(ChronoField.DAY_OF_WEEK);
if (dow == 6) { // Saturday
result = lastDom.minus(1, ChronoUnit.DAYS);
}
else if (dow == 7) { // Sunday
result = lastDom.minus(2, ChronoUnit.DAYS);
}
else {
result = lastDom;
}
return rollbackToMidnight(temporal, result);
};
}
/**
* Return a temporal adjuster that finds the nth-to-last day of the month.
* @param offset the negative offset, i.e. -3 means third-to-last
@@ -233,10 +187,9 @@ final class QuartzCronField extends CronField {
*/
private static TemporalAdjuster lastDayWithOffset(int offset) {
Assert.isTrue(offset < 0, "Offset should be < 0");
TemporalAdjuster adjuster = TemporalAdjusters.lastDayOfMonth();
return temporal -> {
Temporal result = adjuster.adjustInto(temporal).plus(offset, ChronoUnit.DAYS);
return rollbackToMidnight(temporal, result);
Temporal lastDayOfMonth = TemporalAdjusters.lastDayOfMonth().adjustInto(temporal);
return lastDayOfMonth.plus(offset, ChronoUnit.DAYS);
};
}
@@ -262,7 +215,6 @@ final class QuartzCronField extends CronField {
int count = 0;
while (count++ < CronExpression.MAX_ATTEMPTS) {
temporal = Type.DAY_OF_MONTH.elapseUntil(cast(temporal), dayOfMonth);
temporal = atMidnight().adjustInto(temporal);
current = Type.DAY_OF_MONTH.get(temporal);
if (current == dayOfMonth) {
dayOfWeek = temporal.get(ChronoField.DAY_OF_WEEK);
@@ -288,44 +240,6 @@ final class QuartzCronField extends CronField {
};
}
/**
* Return a temporal adjuster that finds the last of the given doy-of-week
* in a month.
*/
private static TemporalAdjuster lastInMonth(DayOfWeek dayOfWeek) {
TemporalAdjuster adjuster = TemporalAdjusters.lastInMonth(dayOfWeek);
return temporal -> {
Temporal result = adjuster.adjustInto(temporal);
return rollbackToMidnight(temporal, result);
};
}
/**
* Returns a temporal adjuster that finds {@code ordinal}-th occurrence of
* the given day-of-week in a month.
*/
private static TemporalAdjuster dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) {
TemporalAdjuster adjuster = TemporalAdjusters.dayOfWeekInMonth(ordinal, dayOfWeek);
return temporal -> {
Temporal result = adjuster.adjustInto(temporal);
return rollbackToMidnight(temporal, result);
};
}
/**
* Rolls back the given {@code result} to midnight. When
* {@code current} has the same day of month as {@code result}, the former
* is returned, to make sure that we don't end up before where we started.
*/
private static Temporal rollbackToMidnight(Temporal current, Temporal result) {
if (result.get(ChronoField.DAY_OF_MONTH) == current.get(ChronoField.DAY_OF_MONTH)) {
return current;
}
else {
return atMidnight().adjustInto(result);
}
}
@SuppressWarnings("unchecked")
private static <T extends Temporal & Comparable<? super T>> T cast(Temporal temporal) {
return (T) temporal;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -17,10 +17,8 @@
package org.springframework.validation.beanvalidation;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -293,17 +291,12 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
configureParameterNameProvider(this.parameterNameDiscoverer, configuration);
}
List<InputStream> mappingStreams = null;
if (this.mappingLocations != null) {
mappingStreams = new ArrayList<>(this.mappingLocations.length);
for (Resource location : this.mappingLocations) {
try {
InputStream stream = location.getInputStream();
mappingStreams.add(stream);
configuration.addMapping(stream);
configuration.addMapping(location.getInputStream());
}
catch (IOException ex) {
closeMappingStreams(mappingStreams);
throw new IllegalStateException("Cannot read mapping resource: " + location);
}
}
@@ -314,13 +307,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
// Allow for custom post-processing before we actually build the ValidatorFactory.
postProcessConfiguration(configuration);
try {
this.validatorFactory = configuration.buildValidatorFactory();
setTargetValidator(this.validatorFactory.getValidator());
}
finally {
closeMappingStreams(mappingStreams);
}
this.validatorFactory = configuration.buildValidatorFactory();
setTargetValidator(this.validatorFactory.getValidator());
}
private void configureParameterNameProvider(ParameterNameDiscoverer discoverer, Configuration<?> configuration) {
@@ -341,18 +329,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
});
}
private void closeMappingStreams(@Nullable List<InputStream> mappingStreams){
if (!CollectionUtils.isEmpty(mappingStreams)) {
for (InputStream stream : mappingStreams) {
try {
stream.close();
}
catch (IOException ignored) {
}
}
}
}
/**
* Post-process the given Bean Validation configuration,
* adding to or overriding any of its settings.
@@ -421,7 +397,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
return super.unwrap(type);
}
catch (ValidationException ex) {
// Ignore - we'll try ValidatorFactory unwrapping next
// ignore - we'll try ValidatorFactory unwrapping next
}
}
if (this.validatorFactory != null) {
@@ -429,7 +405,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
return this.validatorFactory.unwrap(type);
}
catch (ValidationException ex) {
// Ignore if just being asked for ValidatorFactory
// ignore if just being asked for ValidatorFactory
if (ValidatorFactory.class == type) {
return (T) this.validatorFactory;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -179,7 +179,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
}
}
else {
// Got no BindingResult - can only do standard rejectValue call
// got no BindingResult - can only do standard rejectValue call
// with automatic extraction of the current field value
errors.rejectValue(field, errorCode, errorArgs, violation.getMessage());
}
@@ -386,7 +386,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator);
}
catch (ValidationException ex) {
// Ignore if just being asked for plain JSR-303 Validator
// ignore if just being asked for plain Validator
if (javax.validation.Validator.class == type) {
return (T) this.targetValidator;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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,26 +36,24 @@ import static org.assertj.core.api.Assertions.assertThat;
public class AtAspectJAfterThrowingTests {
@Test
public void testAccessThrowable() {
public void testAccessThrowable() throws Exception {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
ITestBean bean = (ITestBean) ctx.getBean("testBean");
ExceptionHandlingAspect aspect = (ExceptionHandlingAspect) ctx.getBean("aspect");
assertThat(AopUtils.isAopProxy(bean)).isTrue();
IOException exceptionThrown = null;
try {
bean.unreliableFileOperation();
}
catch (IOException ex) {
exceptionThrown = ex;
catch (IOException e) {
//
}
assertThat(aspect.handled).isEqualTo(1);
assertThat(aspect.lastException).isSameAs(exceptionThrown);
assertThat(aspect.lastException).isNotNull();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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,6 @@ import static org.assertj.core.api.Assertions.assertThat;
public class AtAspectJAnnotationBindingTests {
private AnnotatedTestBean testBean;
private ClassPathXmlApplicationContext ctx;
@@ -71,7 +70,8 @@ public class AtAspectJAnnotationBindingTests {
class AtAspectJAnnotationBindingTestAspect {
@Around("execution(* *(..)) && @annotation(testAnn)")
public Object doWithAnnotation(ProceedingJoinPoint pjp, TestAnnotation testAnn) throws Throwable {
public Object doWithAnnotation(ProceedingJoinPoint pjp, TestAnnotation testAnn)
throws Throwable {
String annValue = testAnn.value();
Object result = pjp.proceed();
return (result instanceof String ? annValue + " " + result : result);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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,23 +16,14 @@
package org.springframework.context.annotation;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* @author Andy Wilkinson
* @author Liu Dongmiao
*/
public class AggressiveFactoryBeanInstantiationTests {
@@ -58,66 +49,17 @@ public class AggressiveFactoryBeanInstantiationTests {
}
}
@Test
public void checkLinkageError() {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.register(BeanMethodConfigurationWithExceptionInInitializer.class);
context.refresh();
fail("Should have thrown BeanCreationException");
}
catch (BeanCreationException ex) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
ex.printStackTrace(pw);
pw.flush();
String stackTrace = baos.toString();
assertThat(stackTrace.contains(".<clinit>")).isTrue();
assertThat(stackTrace.contains("java.lang.NoClassDefFoundError")).isFalse();
}
}
@Configuration
static class BeanMethodConfiguration {
@Bean
public String foo() {
return "foo";
}
@Bean
public AutowiredBean autowiredBean() {
return new AutowiredBean();
}
@Bean
@DependsOn("autowiredBean")
public SimpleFactoryBean simpleFactoryBean(ApplicationContext applicationContext) {
return new SimpleFactoryBean(applicationContext);
}
}
@Configuration
static class BeanMethodConfigurationWithExceptionInInitializer extends BeanMethodConfiguration {
@Bean
@DependsOn("autowiredBean")
@Override
public SimpleFactoryBean simpleFactoryBean(ApplicationContext applicationContext) {
new ExceptionInInitializer();
return new SimpleFactoryBean(applicationContext);
}
}
static class AutowiredBean {
@Autowired
String foo;
}
static class SimpleFactoryBean implements FactoryBean<Object> {
public SimpleFactoryBean(ApplicationContext applicationContext) {
@@ -134,14 +76,4 @@ public class AggressiveFactoryBeanInstantiationTests {
}
}
static class ExceptionInInitializer {
private static final int ERROR = callInClinit();
private static int callInClinit() {
throw new UnsupportedOperationException();
}
}
}
@@ -271,15 +271,9 @@ class AnnotationConfigApplicationContextTests {
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanA.class), "a")).isTrue();
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanB.class), "b")).isTrue();
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanC.class), "c")).isTrue();
assertThat(context.getBeansOfType(BeanA.class)).isEmpty();
assertThat(context.getBeansOfType(BeanB.class).values().iterator().next()).isSameAs(context.getBean(BeanB.class));
assertThat(context.getBeansOfType(BeanC.class).values().iterator().next()).isSameAs(context.getBean(BeanC.class));
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() ->
context.getBeanFactory().resolveNamedBean(BeanA.class));
assertThat(context.getBeanFactory().resolveNamedBean(BeanB.class).getBeanInstance()).isSameAs(context.getBean(BeanB.class));
assertThat(context.getBeanFactory().resolveNamedBean(BeanC.class).getBeanInstance()).isSameAs(context.getBean(BeanC.class));
}
@Test
@@ -20,6 +20,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -65,6 +66,7 @@ import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -75,13 +77,13 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
* @author Juergen Hoeller
* @author Sam Brannen
*/
class ConfigurationClassPostProcessorTests {
public class ConfigurationClassPostProcessorTests {
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
@BeforeEach
void setup() {
public void setup() {
QualifierAnnotationAutowireCandidateResolver acr = new QualifierAnnotationAutowireCandidateResolver();
acr.setBeanFactory(this.beanFactory);
this.beanFactory.setAutowireCandidateResolver(acr);
@@ -97,7 +99,7 @@ class ConfigurationClassPostProcessorTests {
* We test for such a case below, and in doing so prove that enhancement is working.
*/
@Test
void enhancementIsPresentBecauseSingletonSemanticsAreRespected() {
public void enhancementIsPresentBecauseSingletonSemanticsAreRespected() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -105,13 +107,11 @@ class ConfigurationClassPostProcessorTests {
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertThat(bar.foo).isSameAs(foo);
assertThat(beanFactory.getDependentBeans("foo")).contains("bar");
assertThat(beanFactory.getDependentBeans("config")).contains("foo");
assertThat(beanFactory.getDependentBeans("config")).contains("bar");
assertThat(Arrays.asList(beanFactory.getDependentBeans("foo")).contains("bar")).isTrue();
}
@Test
void enhancementIsPresentBecauseSingletonSemanticsAreRespectedUsingAsm() {
public void enhancementIsPresentBecauseSingletonSemanticsAreRespectedUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -119,13 +119,11 @@ class ConfigurationClassPostProcessorTests {
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertThat(bar.foo).isSameAs(foo);
assertThat(beanFactory.getDependentBeans("foo")).contains("bar");
assertThat(beanFactory.getDependentBeans("config")).contains("foo");
assertThat(beanFactory.getDependentBeans("config")).contains("bar");
assertThat(Arrays.asList(beanFactory.getDependentBeans("foo")).contains("bar")).isTrue();
}
@Test
void enhancementIsNotPresentForProxyBeanMethodsFlagSetToFalse() {
public void enhancementIsNotPresentForProxyBeanMethodsFlagSetToFalse() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(NonEnhancedSingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -136,7 +134,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void enhancementIsNotPresentForProxyBeanMethodsFlagSetToFalseUsingAsm() {
public void enhancementIsNotPresentForProxyBeanMethodsFlagSetToFalseUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(NonEnhancedSingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -147,7 +145,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void enhancementIsNotPresentForStaticMethods() {
public void enhancementIsNotPresentForStaticMethods() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(StaticSingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -160,7 +158,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void enhancementIsNotPresentForStaticMethodsUsingAsm() {
public void enhancementIsNotPresentForStaticMethodsUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(StaticSingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -173,7 +171,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void configurationIntrospectionOfInnerClassesWorksWithDotNameSyntax() {
public void configurationIntrospectionOfInnerClassesWorksWithDotNameSyntax() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(getClass().getName() + ".SingletonBeanConfig"));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -187,7 +185,7 @@ class ConfigurationClassPostProcessorTests {
* if a bean class is already loaded.
*/
@Test
void alreadyLoadedConfigurationClasses() {
public void alreadyLoadedConfigurationClasses() {
beanFactory.registerBeanDefinition("unloadedConfig", new RootBeanDefinition(UnloadedConfig.class.getName()));
beanFactory.registerBeanDefinition("loadedConfig", new RootBeanDefinition(LoadedConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
@@ -200,7 +198,7 @@ class ConfigurationClassPostProcessorTests {
* Tests whether a bean definition without a specified bean class is handled correctly.
*/
@Test
void postProcessorIntrospectsInheritedDefinitionsCorrectly() {
public void postProcessorIntrospectsInheritedDefinitionsCorrectly() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
beanFactory.registerBeanDefinition("parent", new RootBeanDefinition(TestBean.class));
beanFactory.registerBeanDefinition("child", new ChildBeanDefinition("parent"));
@@ -212,96 +210,96 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void postProcessorWorksWithComposedConfigurationUsingReflection() {
public void postProcessorWorksWithComposedConfigurationUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(ComposedConfigurationClass.class);
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithComposedConfigurationUsingAsm() {
public void postProcessorWorksWithComposedConfigurationUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(ComposedConfigurationClass.class.getName());
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForBasePackageUsingReflection() {
public void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForBasePackageUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedConfigurationWithAttributeOverrideForBasePackage.class);
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForBasePackageUsingAsm() {
public void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForBasePackageUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedConfigurationWithAttributeOverrideForBasePackage.class.getName());
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForExcludeFilterUsingReflection() {
public void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForExcludeFilterUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedConfigurationWithAttributeOverrideForExcludeFilter.class);
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForExcludeFilterUsingAsm() {
public void postProcessorWorksWithComposedConfigurationWithAttributeOverrideForExcludeFilterUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedConfigurationWithAttributeOverrideForExcludeFilter.class.getName());
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingReflection() {
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class);
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingAsm() {
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class.getName());
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingReflection() {
public void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedComposedConfigurationWithAttributeOverridesClass.class);
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingAsm() {
public void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ComposedComposedConfigurationWithAttributeOverridesClass.class.getName());
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesUsingReflection() {
public void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
MetaComponentScanConfigurationWithAttributeOverridesClass.class);
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesUsingAsm() {
public void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
MetaComponentScanConfigurationWithAttributeOverridesClass.class.getName());
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesSubclassUsingReflection() {
public void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesSubclassUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
SubMetaComponentScanConfigurationWithAttributeOverridesClass.class);
assertSupportForComposedAnnotation(beanDefinition);
}
@Test
void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesSubclassUsingAsm() {
public void postProcessorWorksWithMetaComponentScanConfigurationWithAttributeOverridesSubclassUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
SubMetaComponentScanConfigurationWithAttributeOverridesClass.class.getName());
assertSupportForComposedAnnotation(beanDefinition);
@@ -326,7 +324,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void postProcessorOverridesNonApplicationBeanDefinitions() {
public void postProcessorOverridesNonApplicationBeanDefinitions() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setRole(RootBeanDefinition.ROLE_SUPPORT);
beanFactory.registerBeanDefinition("bar", rbd);
@@ -339,7 +337,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void postProcessorDoesNotOverrideRegularBeanDefinitions() {
public void postProcessorDoesNotOverrideRegularBeanDefinitions() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setResource(new DescriptiveResource("XML or something"));
beanFactory.registerBeanDefinition("bar", rbd);
@@ -351,7 +349,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void postProcessorDoesNotOverrideRegularBeanDefinitionsEvenWithScopedProxy() {
public void postProcessorDoesNotOverrideRegularBeanDefinitionsEvenWithScopedProxy() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setResource(new DescriptiveResource("XML or something"));
BeanDefinitionHolder proxied = ScopedProxyUtils.createScopedProxy(
@@ -365,7 +363,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void postProcessorFailsOnImplicitOverrideIfOverridingIsNotAllowed() {
public void postProcessorFailsOnImplicitOverrideIfOverridingIsNotAllowed() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setResource(new DescriptiveResource("XML or something"));
beanFactory.registerBeanDefinition("bar", rbd);
@@ -380,7 +378,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test // gh-25430
void detectAliasOverride() {
public void detectAliasOverride() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
beanFactory.setAllowBeanDefinitionOverriding(false);
@@ -392,7 +390,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void configurationClassesProcessedInCorrectOrder() {
public void configurationClassesProcessedInCorrectOrder() {
beanFactory.registerBeanDefinition("config1", new RootBeanDefinition(OverridingSingletonBeanConfig.class));
beanFactory.registerBeanDefinition("config2", new RootBeanDefinition(SingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
@@ -406,7 +404,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void configurationClassesWithValidOverridingForProgrammaticCall() {
public void configurationClassesWithValidOverridingForProgrammaticCall() {
beanFactory.registerBeanDefinition("config1", new RootBeanDefinition(OverridingAgainSingletonBeanConfig.class));
beanFactory.registerBeanDefinition("config2", new RootBeanDefinition(OverridingSingletonBeanConfig.class));
beanFactory.registerBeanDefinition("config3", new RootBeanDefinition(SingletonBeanConfig.class));
@@ -421,7 +419,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void configurationClassesWithInvalidOverridingForProgrammaticCall() {
public void configurationClassesWithInvalidOverridingForProgrammaticCall() {
beanFactory.registerBeanDefinition("config1", new RootBeanDefinition(InvalidOverridingSingletonBeanConfig.class));
beanFactory.registerBeanDefinition("config2", new RootBeanDefinition(OverridingSingletonBeanConfig.class));
beanFactory.registerBeanDefinition("config3", new RootBeanDefinition(SingletonBeanConfig.class));
@@ -437,7 +435,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test // SPR-15384
void nestedConfigurationClassesProcessedInCorrectOrder() {
public void nestedConfigurationClassesProcessedInCorrectOrder() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(ConfigWithOrderedNestedClasses.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -450,7 +448,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test // SPR-16734
void innerConfigurationClassesProcessedInCorrectOrder() {
public void innerConfigurationClassesProcessedInCorrectOrder() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(ConfigWithOrderedInnerClasses.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -464,7 +462,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void scopedProxyTargetMarkedAsNonAutowireCandidate() {
public void scopedProxyTargetMarkedAsNonAutowireCandidate() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -481,7 +479,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void processingAllowedOnlyOncePerProcessorRegistryPair() {
public void processingAllowedOnlyOncePerProcessorRegistryPair() {
DefaultListableBeanFactory bf1 = new DefaultListableBeanFactory();
DefaultListableBeanFactory bf2 = new DefaultListableBeanFactory();
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
@@ -494,7 +492,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjection() {
public void genericsBasedInjection() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -511,7 +509,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithScoped() {
public void genericsBasedInjectionWithScoped() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -528,7 +526,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithScopedProxy() {
public void genericsBasedInjectionWithScopedProxy() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -548,7 +546,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithScopedProxyUsingAsm() {
public void genericsBasedInjectionWithScopedProxyUsingAsm() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -568,7 +566,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithImplTypeAtInjectionPoint() {
public void genericsBasedInjectionWithImplTypeAtInjectionPoint() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -585,7 +583,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithFactoryBean() {
public void genericsBasedInjectionWithFactoryBean() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -604,7 +602,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithRawMatch() {
public void genericsBasedInjectionWithRawMatch() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawMatchingConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -613,7 +611,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithWildcardMatch() {
public void genericsBasedInjectionWithWildcardMatch() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(WildcardMatchingConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -622,7 +620,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithWildcardWithExtendsMatch() {
public void genericsBasedInjectionWithWildcardWithExtendsMatch() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(WildcardWithExtendsConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
@@ -630,7 +628,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithWildcardWithGenericExtendsMatch() {
public void genericsBasedInjectionWithWildcardWithGenericExtendsMatch() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(WildcardWithGenericExtendsConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
@@ -638,12 +636,12 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithEarlyGenericsMatching() {
public void genericsBasedInjectionWithEarlyGenericsMatching() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -655,13 +653,13 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatching() {
public void genericsBasedInjectionWithLateGenericsMatching() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -673,12 +671,12 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithEarlyGenericsMatchingAndRawFactoryMethod() {
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(0);
@@ -688,13 +686,13 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingAndRawFactoryMethod() {
public void genericsBasedInjectionWithLateGenericsMatchingAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -706,12 +704,12 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithEarlyGenericsMatchingAndRawInstance() {
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -723,13 +721,13 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingAndRawInstance() {
public void genericsBasedInjectionWithLateGenericsMatchingAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -741,7 +739,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithEarlyGenericsMatchingOnCglibProxy() {
public void genericsBasedInjectionWithEarlyGenericsMatchingOnCglibProxy() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -751,7 +749,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -765,7 +763,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxy() {
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxy() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -776,7 +774,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -790,7 +788,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawFactoryMethod() {
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -801,7 +799,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -815,7 +813,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawInstance() {
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -826,7 +824,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -840,7 +838,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithEarlyGenericsMatchingOnJdkProxy() {
public void genericsBasedInjectionWithEarlyGenericsMatchingOnJdkProxy() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -849,7 +847,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -863,7 +861,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxy() {
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxy() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -873,7 +871,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -887,7 +885,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawFactoryMethod() {
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -897,7 +895,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -911,7 +909,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawInstance() {
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
@@ -921,7 +919,7 @@ class ConfigurationClassPostProcessorTests {
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
assertThat(beanNames).contains("stringRepo");
assertThat(ObjectUtils.containsElement(beanNames, "stringRepo")).isTrue();
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertThat(beanNames.length).isEqualTo(1);
@@ -935,7 +933,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testSelfReferenceExclusionForFactoryMethodOnSameBean() {
public void testSelfReferenceExclusionForFactoryMethodOnSameBean() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -949,7 +947,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testConfigWithDefaultMethods() {
public void testConfigWithDefaultMethods() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -963,7 +961,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testConfigWithDefaultMethodsUsingAsm() {
public void testConfigWithDefaultMethodsUsingAsm() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -977,7 +975,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testCircularDependency() {
public void testCircularDependency() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
@@ -990,38 +988,38 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testCircularDependencyWithApplicationContext() {
public void testCircularDependencyWithApplicationContext() {
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
new AnnotationConfigApplicationContext(A.class, AStrich.class))
.withMessageContaining("Circular reference");
}
@Test
void testPrototypeArgumentThroughBeanMethodCall() {
public void testPrototypeArgumentThroughBeanMethodCall() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithPrototype.class);
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
}
@Test
void testSingletonArgumentThroughBeanMethodCall() {
public void testSingletonArgumentThroughBeanMethodCall() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithSingleton.class);
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
}
@Test
void testNullArgumentThroughBeanMethodCall() {
public void testNullArgumentThroughBeanMethodCall() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithNull.class);
ctx.getBean("aFoo");
}
@Test
void testInjectionPointMatchForNarrowTargetReturnType() {
public void testInjectionPointMatchForNarrowTargetReturnType() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(FooBarConfiguration.class);
assertThat(ctx.getBean(FooImpl.class).bar).isSameAs(ctx.getBean(BarImpl.class));
}
@Test
void testVarargOnBeanMethod() {
public void testVarargOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class, TestBean.class);
VarargConfiguration bean = ctx.getBean(VarargConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1030,7 +1028,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testEmptyVarargOnBeanMethod() {
public void testEmptyVarargOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(VarargConfiguration.class);
VarargConfiguration bean = ctx.getBean(VarargConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1038,7 +1036,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testCollectionArgumentOnBeanMethod() {
public void testCollectionArgumentOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class, TestBean.class);
CollectionArgumentConfiguration bean = ctx.getBean(CollectionArgumentConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1047,7 +1045,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testEmptyCollectionArgumentOnBeanMethod() {
public void testEmptyCollectionArgumentOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionArgumentConfiguration.class);
CollectionArgumentConfiguration bean = ctx.getBean(CollectionArgumentConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1055,7 +1053,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testMapArgumentOnBeanMethod() {
public void testMapArgumentOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class, DummyRunnable.class);
MapArgumentConfiguration bean = ctx.getBean(MapArgumentConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1064,7 +1062,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testEmptyMapArgumentOnBeanMethod() {
public void testEmptyMapArgumentOnBeanMethod() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapArgumentConfiguration.class);
MapArgumentConfiguration bean = ctx.getBean(MapArgumentConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1072,7 +1070,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testCollectionInjectionFromSameConfigurationClass() {
public void testCollectionInjectionFromSameConfigurationClass() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(CollectionInjectionConfiguration.class);
CollectionInjectionConfiguration bean = ctx.getBean(CollectionInjectionConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1081,7 +1079,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testMapInjectionFromSameConfigurationClass() {
public void testMapInjectionFromSameConfigurationClass() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MapInjectionConfiguration.class);
MapInjectionConfiguration bean = ctx.getBean(MapInjectionConfiguration.class);
assertThat(bean.testBeans).isNotNull();
@@ -1090,7 +1088,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testBeanLookupFromSameConfigurationClass() {
public void testBeanLookupFromSameConfigurationClass() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanLookupConfiguration.class);
BeanLookupConfiguration bean = ctx.getBean(BeanLookupConfiguration.class);
assertThat(bean.getTestBean()).isNotNull();
@@ -1098,7 +1096,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testNameClashBetweenConfigurationClassAndBean() {
public void testNameClashBetweenConfigurationClassAndBean() {
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() -> {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyTestBean.class);
ctx.getBean("myTestBean", TestBean.class);
@@ -1106,7 +1104,7 @@ class ConfigurationClassPostProcessorTests {
}
@Test
void testBeanDefinitionRegistryPostProcessorConfig() {
public void testBeanDefinitionRegistryPostProcessorConfig() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanDefinitionRegistryPostProcessorConfig.class);
boolean condition = ctx.getBean("myTestBean") instanceof TestBean;
assertThat(condition).isTrue();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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 @@ public class EnableLoadTimeWeavingTests {
@Test
public void control() {
GenericXmlApplicationContext ctx =
new GenericXmlApplicationContext(getClass(), "EnableLoadTimeWeavingTests-context.xml");
new GenericXmlApplicationContext(getClass(), "EnableLoadTimeWeavingTests-context.xml");
ctx.getBean("loadTimeWeaver", LoadTimeWeaver.class);
}
@@ -73,11 +73,9 @@ public class EnableLoadTimeWeavingTests {
verify(loadTimeWeaver).addTransformer(isA(ClassFileTransformer.class));
}
@Configuration
@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.DISABLED)
static class EnableLTWConfig_withAjWeavingDisabled implements LoadTimeWeavingConfigurer {
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return mock(LoadTimeWeaver.class);
@@ -87,7 +85,6 @@ public class EnableLoadTimeWeavingTests {
@Configuration
@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.AUTODETECT)
static class EnableLTWConfig_withAjWeavingAutodetect implements LoadTimeWeavingConfigurer {
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return mock(LoadTimeWeaver.class);
@@ -97,11 +94,9 @@ public class EnableLoadTimeWeavingTests {
@Configuration
@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
static class EnableLTWConfig_withAjWeavingEnabled implements LoadTimeWeavingConfigurer {
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return mock(LoadTimeWeaver.class);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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,10 +18,8 @@ package org.springframework.context.annotation;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collections;
import java.util.Iterator;
import java.util.Properties;
@@ -33,7 +31,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
@@ -50,13 +47,13 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*
* @author Chris Beams
* @author Phillip Webb
* @author Sam Brannen
* @since 3.1
*/
class PropertySourceAnnotationTests {
public class PropertySourceAnnotationTests {
@Test
void withExplicitName() {
public void withExplicitName() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithExplicitName.class);
ctx.refresh();
@@ -76,25 +73,29 @@ class PropertySourceAnnotationTests {
}
@Test
void withImplicitName() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithImplicitName.class);
public void withImplicitName() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithImplicitName.class);
ctx.refresh();
assertThat(ctx.getEnvironment().getPropertySources().contains("class path resource [org/springframework/context/annotation/p1.properties]")).as("property source p1 was not added").isTrue();
assertThat(ctx.getBean(TestBean.class).getName()).isEqualTo("p1TestBean");
}
@Test
void withTestProfileBeans() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithTestProfileBeans.class);
public void withTestProfileBeans() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithTestProfileBeans.class);
ctx.refresh();
assertThat(ctx.containsBean("testBean")).isTrue();
assertThat(ctx.containsBean("testProfileBean")).isTrue();
}
/**
* Tests the LIFO behavior of @PropertySource annotations.
* <p>The last one registered should 'win'.
* Tests the LIFO behavior of @PropertySource annotaitons.
* The last one registered should 'win'.
*/
@Test
void orderingIsLifo() {
public void orderingIsLifo() {
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithImplicitName.class, P2Config.class);
@@ -113,7 +114,7 @@ class PropertySourceAnnotationTests {
}
@Test
void withCustomFactory() {
public void withCustomFactory() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithImplicitName.class, WithCustomFactory.class);
ctx.refresh();
@@ -121,7 +122,7 @@ class PropertySourceAnnotationTests {
}
@Test
void withCustomFactoryAsMeta() {
public void withCustomFactoryAsMeta() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithImplicitName.class, WithCustomFactoryAsMeta.class);
ctx.refresh();
@@ -129,43 +130,59 @@ class PropertySourceAnnotationTests {
}
@Test
void withUnresolvablePlaceholder() {
assertThatExceptionOfType(BeanDefinitionStoreException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(ConfigWithUnresolvablePlaceholder.class))
.withCauseInstanceOf(IllegalArgumentException.class);
public void withUnresolvablePlaceholder() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithUnresolvablePlaceholder.class);
try {
ctx.refresh();
}
catch (BeanDefinitionStoreException ex) {
assertThat(ex.getCause() instanceof IllegalArgumentException).isTrue();
}
}
@Test
void withUnresolvablePlaceholderAndDefault() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithUnresolvablePlaceholderAndDefault.class);
public void withUnresolvablePlaceholderAndDefault() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithUnresolvablePlaceholderAndDefault.class);
ctx.refresh();
assertThat(ctx.getBean(TestBean.class).getName()).isEqualTo("p1TestBean");
}
@Test
void withResolvablePlaceholder() {
public void withResolvablePlaceholder() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithResolvablePlaceholder.class);
System.setProperty("path.to.properties", "org/springframework/context/annotation");
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithResolvablePlaceholder.class);
ctx.refresh();
assertThat(ctx.getBean(TestBean.class).getName()).isEqualTo("p1TestBean");
System.clearProperty("path.to.properties");
}
@Test
void withResolvablePlaceholderAndFactoryBean() {
public void withResolvablePlaceholderAndFactoryBean() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithResolvablePlaceholderAndFactoryBean.class);
System.setProperty("path.to.properties", "org/springframework/context/annotation");
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithResolvablePlaceholderAndFactoryBean.class);
ctx.refresh();
assertThat(ctx.getBean(TestBean.class).getName()).isEqualTo("p1TestBean");
System.clearProperty("path.to.properties");
}
@Test
void withEmptyResourceLocations() {
assertThatExceptionOfType(BeanDefinitionStoreException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(ConfigWithEmptyResourceLocations.class))
.withCauseInstanceOf(IllegalArgumentException.class);
public void withEmptyResourceLocations() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithEmptyResourceLocations.class);
try {
ctx.refresh();
}
catch (BeanDefinitionStoreException ex) {
assertThat(ex.getCause() instanceof IllegalArgumentException).isTrue();
}
}
@Test
void withNameAndMultipleResourceLocations() {
public void withNameAndMultipleResourceLocations() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithNameAndMultipleResourceLocations.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
@@ -174,7 +191,7 @@ class PropertySourceAnnotationTests {
}
@Test
void withMultipleResourceLocations() {
public void withMultipleResourceLocations() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithMultipleResourceLocations.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
@@ -183,7 +200,7 @@ class PropertySourceAnnotationTests {
}
@Test
void withRepeatedPropertySourcesInContainerAnnotation() {
public void withPropertySources() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithPropertySources.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
@@ -192,43 +209,7 @@ class PropertySourceAnnotationTests {
}
@Test
void withRepeatedPropertySources() {
try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithRepeatedPropertySourceAnnotations.class)) {
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
// p2 should 'win' as it was registered last
assertThat(ctx.getEnvironment().getProperty("testbean.name")).isEqualTo("p2TestBean");
}
}
@Test
void withRepeatedPropertySourcesOnComposedAnnotation() {
Class<?> configClass = ConfigWithRepeatedPropertySourceAnnotationsOnComposedAnnotation.class;
String key = "custom.config.package";
System.clearProperty(key);
try (ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(configClass)) {
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
// p2 should 'win' as it was registered last
assertThat(ctx.getEnvironment().getProperty("testbean.name")).isEqualTo("p2TestBean");
}
System.setProperty(key, "org/springframework/context/annotation");
try (ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(configClass)) {
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p3")).isTrue();
// p3 should 'win' as it was registered last
assertThat(ctx.getEnvironment().getProperty("testbean.name")).isEqualTo("p3TestBean");
}
finally {
System.clearProperty(key);
}
}
@Test
void withNamedPropertySources() {
public void withNamedPropertySources() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithNamedPropertySources.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
@@ -237,21 +218,21 @@ class PropertySourceAnnotationTests {
}
@Test
void withMissingPropertySource() {
assertThatExceptionOfType(BeanDefinitionStoreException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(ConfigWithMissingPropertySource.class))
public void withMissingPropertySource() {
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
new AnnotationConfigApplicationContext(ConfigWithMissingPropertySource.class))
.withCauseInstanceOf(FileNotFoundException.class);
}
@Test
void withIgnoredPropertySource() {
public void withIgnoredPropertySource() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithIgnoredPropertySource.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
}
@Test
void withSameSourceImportedInDifferentOrder() {
public void withSameSourceImportedInDifferentOrder() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithSameSourceImportedInDifferentOrder.class);
assertThat(ctx.getEnvironment().containsProperty("from.p1")).isTrue();
assertThat(ctx.getEnvironment().containsProperty("from.p2")).isTrue();
@@ -259,7 +240,7 @@ class PropertySourceAnnotationTests {
}
@Test
void orderingWithAndWithoutNameAndMultipleResourceLocations() {
public void orderingWithAndWithoutNameAndMultipleResourceLocations() {
// SPR-10820: p2 should 'win' as it was registered last
AnnotationConfigApplicationContext ctxWithName = new AnnotationConfigApplicationContext(ConfigWithNameAndMultipleResourceLocations.class);
AnnotationConfigApplicationContext ctxWithoutName = new AnnotationConfigApplicationContext(ConfigWithMultipleResourceLocations.class);
@@ -268,14 +249,14 @@ class PropertySourceAnnotationTests {
}
@Test
void orderingWithAndWithoutNameAndFourResourceLocations() {
public void orderingWithAndWithoutNameAndFourResourceLocations() {
// SPR-12198: p4 should 'win' as it was registered last
AnnotationConfigApplicationContext ctxWithoutName = new AnnotationConfigApplicationContext(ConfigWithFourResourceLocations.class);
assertThat(ctxWithoutName.getEnvironment().getProperty("testbean.name")).isEqualTo("p4TestBean");
}
@Test
void orderingDoesntReplaceExisting() throws Exception {
public void orderingDoesntReplaceExisting() throws Exception {
// SPR-12198: mySource should 'win' as it was registered manually
AnnotationConfigApplicationContext ctxWithoutName = new AnnotationConfigApplicationContext();
MapPropertySource mySource = new MapPropertySource("mine", Collections.singletonMap("testbean.name", "myTestBean"));
@@ -286,51 +267,51 @@ class PropertySourceAnnotationTests {
}
@Configuration
@PropertySource("classpath:${unresolvable}/p1.properties")
@PropertySource(value="classpath:${unresolvable}/p1.properties")
static class ConfigWithUnresolvablePlaceholder {
}
@Configuration
@PropertySource("classpath:${unresolvable:org/springframework/context/annotation}/p1.properties")
@PropertySource(value="classpath:${unresolvable:org/springframework/context/annotation}/p1.properties")
static class ConfigWithUnresolvablePlaceholderAndDefault {
@Inject Environment env;
@Bean
TestBean testBean() {
public TestBean testBean() {
return new TestBean(env.getProperty("testbean.name"));
}
}
@Configuration
@PropertySource("classpath:${path.to.properties}/p1.properties")
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
static class ConfigWithResolvablePlaceholder {
@Inject Environment env;
@Bean
TestBean testBean() {
public TestBean testBean() {
return new TestBean(env.getProperty("testbean.name"));
}
}
@Configuration
@PropertySource("classpath:${path.to.properties}/p1.properties")
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
static class ConfigWithResolvablePlaceholderAndFactoryBean {
@Inject Environment env;
@SuppressWarnings("rawtypes")
@Bean
FactoryBean<TestBean> testBean() {
public FactoryBean testBean() {
final String name = env.getProperty("testbean.name");
return new FactoryBean<TestBean>() {
return new FactoryBean() {
@Override
public TestBean getObject() {
public Object getObject() {
return new TestBean(name);
}
@Override
@@ -353,7 +334,7 @@ class PropertySourceAnnotationTests {
@Inject Environment env;
@Bean
TestBean testBean() {
public TestBean testBean() {
return new TestBean(env.getProperty("testbean.name"));
}
}
@@ -366,7 +347,7 @@ class PropertySourceAnnotationTests {
@Inject Environment env;
@Bean
TestBean testBean() {
public TestBean testBean() {
return new TestBean(env.getProperty("testbean.name"));
}
}
@@ -380,7 +361,7 @@ class PropertySourceAnnotationTests {
@Inject Environment env;
@Bean @Profile("test")
TestBean testBean() {
public TestBean testBean() {
return new TestBean(env.getProperty("testbean.name"));
}
}
@@ -399,21 +380,21 @@ class PropertySourceAnnotationTests {
@Configuration
@MyPropertySource("classpath:org/springframework/context/annotation/p2.properties")
@MyPropertySource(value = "classpath:org/springframework/context/annotation/p2.properties")
static class WithCustomFactoryAsMeta {
}
@Retention(RetentionPolicy.RUNTIME)
@PropertySource(value = {}, factory = MyCustomFactory.class)
@interface MyPropertySource {
public @interface MyPropertySource {
@AliasFor(annotation = PropertySource.class)
String value();
}
static class MyCustomFactory implements PropertySourceFactory {
public static class MyCustomFactory implements PropertySourceFactory {
@Override
public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
@@ -441,10 +422,11 @@ class PropertySourceAnnotationTests {
@Configuration
@PropertySource({
"classpath:org/springframework/context/annotation/p1.properties",
"classpath:org/springframework/context/annotation/p2.properties"
})
@PropertySource(
value = {
"classpath:org/springframework/context/annotation/p1.properties",
"classpath:org/springframework/context/annotation/p2.properties"
})
static class ConfigWithMultipleResourceLocations {
}
@@ -452,33 +434,12 @@ class PropertySourceAnnotationTests {
@Configuration
@PropertySources({
@PropertySource("classpath:org/springframework/context/annotation/p1.properties"),
@PropertySource("classpath:${base.package}/p2.properties")
@PropertySource("classpath:${base.package}/p2.properties"),
})
static class ConfigWithPropertySources {
}
@Configuration
@PropertySource("classpath:org/springframework/context/annotation/p1.properties")
@PropertySource(value = "classpath:${base.package}/p2.properties", ignoreResourceNotFound = true)
static class ConfigWithRepeatedPropertySourceAnnotations {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@PropertySource("classpath:org/springframework/context/annotation/p1.properties")
@PropertySource(value = "classpath:${base.package}/p2.properties", ignoreResourceNotFound = true)
@PropertySource(value = "classpath:${custom.config.package:bogus/config}/p3.properties", ignoreResourceNotFound = true)
@interface ComposedConfiguration {
}
@ComposedConfiguration
static class ConfigWithRepeatedPropertySourceAnnotationsOnComposedAnnotation {
}
@Configuration
@PropertySources({
@PropertySource(name = "psName", value = "classpath:org/springframework/context/annotation/p1.properties"),
@@ -510,7 +471,7 @@ class PropertySourceAnnotationTests {
@Configuration
@PropertySource({})
@PropertySource(value = {})
static class ConfigWithEmptyResourceLocations {
}
@@ -521,7 +482,7 @@ class PropertySourceAnnotationTests {
@PropertySource("classpath:org/springframework/context/annotation/p2.properties")
})
@Configuration
static class ConfigWithSameSourceImportedInDifferentOrder {
public static class ConfigWithSameSourceImportedInDifferentOrder {
}
@@ -531,17 +492,18 @@ class PropertySourceAnnotationTests {
@PropertySource("classpath:org/springframework/context/annotation/p2.properties"),
@PropertySource("classpath:org/springframework/context/annotation/p1.properties")
})
static class ConfigImportedWithSameSourceImportedInDifferentOrder {
public static class ConfigImportedWithSameSourceImportedInDifferentOrder {
}
@Configuration
@PropertySource({
"classpath:org/springframework/context/annotation/p1.properties",
"classpath:org/springframework/context/annotation/p2.properties",
"classpath:org/springframework/context/annotation/p3.properties",
"classpath:org/springframework/context/annotation/p4.properties"
})
@PropertySource(
value = {
"classpath:org/springframework/context/annotation/p1.properties",
"classpath:org/springframework/context/annotation/p2.properties",
"classpath:org/springframework/context/annotation/p3.properties",
"classpath:org/springframework/context/annotation/p4.properties"
})
static class ConfigWithFourResourceLocations {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -49,11 +49,9 @@ public class PayloadApplicationEventTests {
public void testProgrammaticEventListener() {
List<Auditable> events = new ArrayList<>();
ApplicationListener<AuditablePayloadEvent<String>> listener = events::add;
ApplicationListener<AuditablePayloadEvent<Integer>> mismatch = (event -> event.getPayload().intValue());
ConfigurableApplicationContext ac = new GenericApplicationContext();
ac.addApplicationListener(listener);
ac.addApplicationListener(mismatch);
ac.refresh();
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
@@ -65,11 +63,9 @@ public class PayloadApplicationEventTests {
public void testProgrammaticPayloadListener() {
List<String> events = new ArrayList<>();
ApplicationListener<PayloadApplicationEvent<String>> listener = ApplicationListener.forPayload(events::add);
ApplicationListener<PayloadApplicationEvent<Integer>> mismatch = ApplicationListener.forPayload(payload -> payload.intValue());
ConfigurableApplicationContext ac = new GenericApplicationContext();
ac.addApplicationListener(listener);
ac.addApplicationListener(mismatch);
ac.refresh();
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
@@ -25,47 +25,18 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Unit tests for {@link BitsCronField}.
*
* @author Arjen Poutsma
* @author Sam Brannen
*/
class BitsCronFieldTests {
public class BitsCronFieldTests {
@Test
void parse() {
assertThat(BitsCronField.parseSeconds("42")).has(clearRange(0, 41)).has(set(42)).has(clearRange(43, 59));
assertThat(BitsCronField.parseMinutes("1,2,5,9")).has(clear(0)).has(set(1, 2)).has(clearRange(3,4)).has(set(5)).has(clearRange(6,8)).has(set(9)).has(clearRange(10,59));
assertThat(BitsCronField.parseSeconds("0-4,8-12")).has(setRange(0, 4)).has(clearRange(5,7)).has(setRange(8, 12)).has(clearRange(13,59));
assertThat(BitsCronField.parseSeconds("57/2")).has(clearRange(0, 56)).has(set(57)).has(clear(58)).has(set(59));
assertThat(BitsCronField.parseMinutes("30")).has(set(30)).has(clearRange(1, 29)).has(clearRange(31, 59));
assertThat(BitsCronField.parseHours("23")).has(set(23)).has(clearRange(0, 23));
assertThat(BitsCronField.parseHours("0-23/2")).has(set(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22)).has(clear(1,3,5,7,9,11,13,15,17,19,21,23));
assertThat(BitsCronField.parseDaysOfMonth("1")).has(set(1)).has(clearRange(2, 31));
assertThat(BitsCronField.parseMonth("1")).has(set(1)).has(clearRange(2, 12));
assertThat(BitsCronField.parseDaysOfWeek("0")).has(set(7, 7)).has(clearRange(0, 6));
}
@Test
void parseLists() {
assertThat(BitsCronField.parseSeconds("15,30")).has(set(15, 30)).has(clearRange(1, 15)).has(clearRange(31, 59));
assertThat(BitsCronField.parseMinutes("1,2,5,9")).has(set(1, 2, 5, 9)).has(clear(0)).has(clearRange(3, 4)).has(clearRange(6, 8)).has(clearRange(10, 59));
assertThat(BitsCronField.parseHours("1,2,3")).has(set(1, 2, 3)).has(clearRange(4, 23));
assertThat(BitsCronField.parseDaysOfMonth("1,2,3")).has(set(1, 2, 3)).has(clearRange(4, 31));
assertThat(BitsCronField.parseMonth("1,2,3")).has(set(1, 2, 3)).has(clearRange(4, 12));
assertThat(BitsCronField.parseDaysOfWeek("1,2,3")).has(set(1, 2, 3)).has(clearRange(4, 7));
assertThat(BitsCronField.parseMinutes("5,10-30/2"))
.has(clearRange(0, 5))
.has(set(5))
.has(clearRange(6,10))
.has(set(10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30))
.has(clear(11, 13, 15, 17, 19, 21, 23, 25, 27, 29))
.has(clearRange(31, 60));
assertThat(BitsCronField.parseDaysOfWeek("0")).has(clearRange(0, 6)).has(set(7, 7));
assertThat(BitsCronField.parseSeconds("57/2")).has(clearRange(0, 56)).has(set(57)).has(clear(58)).has(set(59));
}
@Test
@@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test;
import static java.time.DayOfWeek.FRIDAY;
import static java.time.DayOfWeek.MONDAY;
import static java.time.DayOfWeek.SUNDAY;
import static java.time.DayOfWeek.THURSDAY;
import static java.time.DayOfWeek.TUESDAY;
import static java.time.DayOfWeek.WEDNESDAY;
import static java.time.temporal.TemporalAdjusters.next;
@@ -117,7 +116,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMinute(10);
LocalDateTime expected = last.plusMinutes(1).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -151,7 +149,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.of(year, 10, 30, 11, 1);
LocalDateTime expected = last.withHour(12).withMinute(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -176,7 +173,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withDayOfMonth(1);
LocalDateTime expected = last.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -211,7 +207,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMonth(9).withDayOfMonth(30);
LocalDateTime expected = LocalDateTime.of(last.getYear(), 10, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -227,7 +222,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMonth(8).withDayOfMonth(30);
LocalDateTime expected = last.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -243,7 +237,6 @@ class CronExpressionTests {
ZonedDateTime last = ZonedDateTime.now(ZoneId.of("CET")).withMonth(10).withDayOfMonth(30);
ZonedDateTime expected = last.withDayOfMonth(31).withHour(0).withMinute(0).withSecond(0).withNano(0);
ZonedDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -258,7 +251,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMonth(10).withDayOfMonth(30);
LocalDateTime expected = LocalDateTime.of(last.getYear(), 11, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -273,7 +265,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withYear(2010).withMonth(12).withDayOfMonth(31);
LocalDateTime expected = LocalDateTime.of(2011, 1, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -306,7 +297,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().with(next(MONDAY));
LocalDateTime expected = last.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(TUESDAY);
}
@@ -318,7 +308,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().with(next(WEDNESDAY));
LocalDateTime expected = last.plusDays(6).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(TUESDAY);
}
@@ -330,7 +319,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMinute(4).withSecond(54);
LocalDateTime expected = last.plusMinutes(1).withSecond(55).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -345,7 +333,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withHour(9).withSecond(54);
LocalDateTime expected = last.plusHours(1).withMinute(0).withSecond(55).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -360,7 +347,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withHour(9).withMinute(4);
LocalDateTime expected = last.plusHours(1).plusMinutes(1).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -376,7 +362,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withDayOfMonth(2).withSecond(54);
LocalDateTime expected = last.plusDays(1).withHour(0).withMinute(0).withSecond(55).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -391,7 +376,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withMonth(10).withDayOfMonth(2);
LocalDateTime expected = LocalDateTime.of(last.getYear(), 11, 3, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -414,7 +398,6 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.now().withYear(2007).withMonth(2).withDayOfMonth(10);
LocalDateTime expected = LocalDateTime.of(2008, 2, 29, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -430,14 +413,12 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.of(LocalDate.of(2009, 9, 26), LocalTime.now());
LocalDateTime expected = last.plusDays(2).withHour(7).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
// Next day is a week day so add one
last = actual;
expected = expected.plusDays(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -452,14 +433,12 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.of(LocalDate.of(2010, 12, 30), LocalTime.now());
LocalDateTime expected = last.plusMonths(1).withHour(23).withMinute(30).withSecond(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
// Next trigger is 3 months later
last = actual;
expected = expected.plusMonths(3);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -506,13 +485,11 @@ class CronExpressionTests {
LocalDateTime expected = LocalDateTime.of(last.getYear() + 1, 1, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = expected.plusYears(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -536,13 +513,11 @@ class CronExpressionTests {
LocalDateTime expected = LocalDateTime.of(last.getYear(), 11, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = expected.plusMonths(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -559,13 +534,11 @@ class CronExpressionTests {
LocalDateTime expected = last.with(next(SUNDAY)).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = expected.plusWeeks(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -582,13 +555,11 @@ class CronExpressionTests {
LocalDateTime expected = last.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = expected.plusDays(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -612,13 +583,11 @@ class CronExpressionTests {
LocalDateTime expected = last.plusHours(1).withMinute(0).withSecond(0).withNano(0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = expected.plusHours(1);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -634,19 +603,16 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.of(LocalDate.of(2008, 1, 4), LocalTime.now());
LocalDateTime expected = LocalDateTime.of(2008, 1, 31, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.of(2008, 2, 29, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.of(2008, 3, 31, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -662,19 +628,16 @@ class CronExpressionTests {
LocalDateTime last = LocalDateTime.of(LocalDate.of(2008, 1, 4), LocalTime.now());
LocalDateTime expected = LocalDateTime.of(2008, 1, 28, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.of(2008, 2, 26, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.of(2008, 3, 28, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
@@ -1079,168 +1042,4 @@ class CronExpressionTests {
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(WEDNESDAY);
}
@Test
void dayOfMonthListWithQuartz() {
CronExpression expression = CronExpression.parse("0 0 0 1W,15,LW * ?");
LocalDateTime last = LocalDateTime.of(2019, 12, 30, 0, 0);
LocalDateTime expected = LocalDateTime.of(2019, 12, 31, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual).is(weekday);
last = actual;
expected = LocalDateTime.of(2020, 1, 1, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual).is(weekday);
last = actual;
expected = LocalDateTime.of(2020, 1, 15, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.of(2020, 1, 31, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual).is(weekday);
}
@Test
void dayOfWeekListWithQuartz() {
CronExpression expression = CronExpression.parse("0 0 0 ? * THU#1,THU#3,THU#5");
LocalDateTime last = LocalDateTime.of(2019, 12, 31, 0, 0);
LocalDateTime expected = LocalDateTime.of(2020, 1, 2, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(THURSDAY);
last = actual;
expected = LocalDateTime.of(2020, 1, 16, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(THURSDAY);
last = actual;
expected = LocalDateTime.of(2020, 1, 30, 0, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(THURSDAY);
}
@Test
void quartzLastDayOfMonthEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * L * *");
LocalDateTime last = LocalDateTime.of(2021, 1, 30, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 1, 31, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = LocalDateTime.of(2021, 1, 31, 1, 0);
expected = LocalDateTime.of(2021, 1, 31, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void quartzLastDayOfMonthOffsetEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * L-1 * *");
LocalDateTime last = LocalDateTime.of(2021, 1, 29, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 1, 30, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = LocalDateTime.of(2021, 1, 30, 1, 0);
expected = LocalDateTime.of(2021, 1, 30, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void quartzFirstWeekdayOfMonthEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * 1W * *");
LocalDateTime last = LocalDateTime.of(2021, 1, 31, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 2, 1, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = LocalDateTime.of(2021, 2, 1, 1, 0);
expected = LocalDateTime.of(2021, 2, 1, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void quartzLastWeekdayOfMonthEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * LW * *");
LocalDateTime last = LocalDateTime.of(2021, 1, 28, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 1, 29, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = LocalDateTime.of(2021, 1, 29, 1, 0);
expected = LocalDateTime.of(2021, 1, 29, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void quartz5thFridayOfTheMonthEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * ? * FRI#5");
LocalDateTime last = LocalDateTime.of(2021, 1, 28, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 1, 29, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(FRIDAY);
last = LocalDateTime.of(2021, 1, 29, 1, 0);
expected = LocalDateTime.of(2021, 1, 29, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void quartzLastFridayOfTheMonthEveryHour() {
CronExpression expression = CronExpression.parse("0 0 * ? * FRIL");
LocalDateTime last = LocalDateTime.of(2021, 1, 28, 0, 1);
LocalDateTime expected = LocalDateTime.of(2021, 1, 29, 0, 0);
LocalDateTime actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
assertThat(actual.getDayOfWeek()).isEqualTo(FRIDAY);
last = LocalDateTime.of(2021, 1, 29, 1, 0);
expected = LocalDateTime.of(2021, 1, 29, 2, 0);
actual = expression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
}
@@ -25,8 +25,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Unit tests for {@link QuartzCronField}.
*
* @author Arjen Poutsma
*/
class QuartzCronFieldTests {
@@ -97,8 +95,6 @@ class QuartzCronFieldTests {
assertThatIllegalArgumentException().isThrownBy(() -> QuartzCronField.parseDaysOfWeek("1#L"));
assertThatIllegalArgumentException().isThrownBy(() -> QuartzCronField.parseDaysOfWeek("L#1"));
assertThatIllegalArgumentException().isThrownBy(() -> QuartzCronField.parseDaysOfWeek("8#1"));
assertThatIllegalArgumentException().isThrownBy(() -> QuartzCronField.parseDaysOfWeek("2#1,2#3,2#5"));
assertThatIllegalArgumentException().isThrownBy(() -> QuartzCronField.parseDaysOfWeek("FRI#-1"));
}
}
@@ -1,2 +1 @@
testbean.name=p3TestBean
from.p3=p3Value
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -58,10 +58,10 @@ internal fun <T: Any> monoToDeferred(source: Mono<T>) =
* @since 5.2
*/
@Suppress("UNCHECKED_CAST")
fun invokeSuspendingFunction(method: Method, target: Any, vararg args: Any?): Publisher<*> {
fun invokeSuspendingFunction(method: Method, bean: Any, vararg args: Any?): Publisher<*> {
val function = method.kotlinFunction!!
val mono = mono(Dispatchers.Unconfined) {
function.callSuspend(target, *args.sliceArray(0..(args.size-2))).let { if (it == Unit) null else it }
function.callSuspend(bean, *args.sliceArray(0..(args.size-2))).let { if (it == Unit) null else it }
}.onErrorMap(InvocationTargetException::class.java) { it.targetException }
return if (function.returnType.classifier == Flow::class) {
mono.flatMapMany { (it as Flow<Any>).asFlux() }
+5 -1
View File
@@ -1,11 +1,15 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
id "com.github.johnrengelman.shadow" version "5.2.0"
}
description = "Spring Core"
apply plugin: "kotlin"
// spring-core includes asm and repackages cglib, inlining both into the spring-core jar.
// cglib itself depends on asm and is therefore further transformed by the ShadowJar task to
// cglib itself depends on asm and is therefore further transformed by the JarJar task to
// depend on org.springframework.asm; this avoids including two different copies of asm.
def cglibVersion = "3.3.0"
def objenesisVersion = "3.1"
@@ -77,7 +77,7 @@ public abstract class AnnotationVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.av = annotationVisitor;
}
@@ -129,9 +129,9 @@ public abstract class AnnotationVisitor {
}
/**
* Visits an array value of the annotation. Note that arrays of primitive values (such as byte,
* Visits an array value of the annotation. Note that arrays of primitive types (such as byte,
* boolean, short, char, int, long, float or double) can be passed as value to {@link #visit
* visit}. This is what {@link ClassReader} does for non empty arrays of primitive values.
* visit}. This is what {@link ClassReader} does.
*
* @param name the value name.
* @return a visitor to visit the actual array value elements, or {@literal null} if this visitor
@@ -100,10 +100,8 @@ public class ClassReader {
@Deprecated
// DontCheck(MemberName): can't be renamed (for backward binary compatibility).
public final byte[] b;
/** The offset in bytes of the ClassFile's access_flags field. */
public final int header;
/**
* A byte array containing the JVMS ClassFile structure to be parsed. <i>The content of this array
* must not be modified. This field is intended for {@link Attribute} sub classes, and is normally
@@ -114,7 +112,6 @@ public class ClassReader {
* ClassFile element offsets within this byte array.
*/
final byte[] classFileBuffer;
/**
* The offset in bytes, in {@link #classFileBuffer}, of each cp_info entry of the ClassFile's
* constant_pool array, <i>plus one</i>. In other words, the offset of constant pool entry i is
@@ -122,19 +119,16 @@ public class ClassReader {
* 1].
*/
private final int[] cpInfoOffsets;
/**
* The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
* multiple parsing of a given CONSTANT_Utf8 constant pool item.
*/
private final String[] constantUtf8Values;
/**
* The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
* cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
*/
private final ConstantDynamic[] constantDynamicValues;
/**
* The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array
* (in the BootstrapMethods attribute).
@@ -143,7 +137,6 @@ public class ClassReader {
* 4.7.23</a>
*/
private final int[] bootstrapMethodOffsets;
/**
* A conservative estimate of the maximum length of the strings contained in the constant pool of
* the class.
@@ -191,7 +184,7 @@ public class ClassReader {
this.b = classFileBuffer;
// Check the class' major_version. This field is after the magic and minor_version fields, which
// use 4 and 2 bytes respectively.
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V17) {
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V16) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
@@ -506,9 +499,6 @@ public class ClassReader {
} else if (Constants.SYNTHETIC.equals(attributeName)) {
accessFlags |= Opcodes.ACC_SYNTHETIC;
} else if (Constants.SOURCE_DEBUG_EXTENSION.equals(attributeName)) {
if (attributeLength > classFileBuffer.length - currentAttributeOffset) {
throw new IllegalArgumentException();
}
sourceDebugExtension =
readUtf(currentAttributeOffset, attributeLength, new char[attributeLength]);
} else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
@@ -1519,9 +1509,6 @@ public class ClassReader {
final int maxLocals = readUnsignedShort(currentOffset + 2);
final int codeLength = readInt(currentOffset + 4);
currentOffset += 8;
if (codeLength > classFileBuffer.length - currentOffset) {
throw new IllegalArgumentException();
}
// Read the bytecode 'code' array to create a label for each referenced instruction.
final int bytecodeStartOffset = currentOffset;
@@ -2978,7 +2965,7 @@ public class ClassReader {
// Parse the array_value array.
while (numElementValuePairs-- > 0) {
currentOffset =
readElementValue(annotationVisitor, currentOffset, /* elementName= */ null, charBuffer);
readElementValue(annotationVisitor, currentOffset, /* elementName = */ null, charBuffer);
}
}
if (annotationVisitor != null) {
@@ -77,7 +77,7 @@ public abstract class ClassVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.cv = classVisitor;
}
@@ -76,7 +76,7 @@ public abstract class FieldVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.fv = fieldVisitor;
}
@@ -89,7 +89,7 @@ public abstract class MethodVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.mv = methodVisitor;
}
@@ -75,7 +75,7 @@ public abstract class ModuleVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.mv = moduleVisitor;
}
@@ -132,7 +132,7 @@ public interface Opcodes {
* <pre>
* public class StuffVisitor {
* &#64;Deprecated public void visitOldStuff(int arg, ...) {
* visitNewStuff(arg | SOURCE_DEPRECATED, ...);
* visitNewStuf(arg | SOURCE_DEPRECATED, ...);
* }
* public void visitNewStuff(int argAndSource...) {
* if ((argAndSource & SOURCE_DEPRECATED) == 0) {
@@ -154,7 +154,7 @@ public interface Opcodes {
* <p>and there are two cases:
*
* <ul>
* <li>call visitOldStuff: in the call to super.visitOldStuff, the source is set to
* <li>call visitOldSuff: in the call to super.visitOldStuff, the source is set to
* SOURCE_DEPRECATED and visitNewStuff is called. Here 'do stuff' is run because the source
* was previously set to SOURCE_DEPRECATED, and execution eventually returns to
* UserStuffVisitor.visitOldStuff, where 'do user stuff' is run.
@@ -281,7 +281,6 @@ public interface Opcodes {
int V14 = 0 << 16 | 58;
int V15 = 0 << 16 | 59;
int V16 = 0 << 16 | 60;
int V17 = 0 << 16 | 61;
/**
* Version flag indicating that the class is using 'preview' features.
@@ -75,7 +75,7 @@ public abstract class RecordComponentVisitor {
&& api != Opcodes.ASM10_EXPERIMENTAL) {
throw new IllegalArgumentException("Unsupported api " + api);
}
// SPRING PATCH: no preview mode check for ASM experimental
// SPRING PATCH: no preview mode check for ASM 9 experimental
this.api = api;
this.delegate = recordComponentVisitor;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -18,7 +18,7 @@ package org.springframework.asm;
/**
* Utility class exposing constants related to Spring's internal repackaging
* of the ASM bytecode library: currently based on ASM 9.x plus minor patches.
* of the ASM bytecode library: currently based on ASM 9.0 plus minor patches.
*
* <p>See <a href="package-summary.html">package-level javadocs</a> for more
* information on {@code org.springframework.asm}.
@@ -1,6 +1,6 @@
/**
* Spring's repackaging of
* <a href="https://gitlab.ow2.org/asm/asm">ASM 9.x</a>
* <a href="https://gitlab.ow2.org/asm/asm">ASM 9.0</a>
* (with Spring-specific patches; for internal use only).
*
* <p>This repackaging technique avoids any potential conflicts with
@@ -522,46 +522,26 @@ public class ReflectUtils {
}
}
// Direct defineClass attempt on the target Classloader
if (c == null) {
// Classic option: protected ClassLoader.defineClass method
if (c == null && classLoaderDefineClassMethod != null) {
if (protectionDomain == null) {
protectionDomain = PROTECTION_DOMAIN;
}
// Look for publicDefineClass(String name, byte[] b, ProtectionDomain protectionDomain)
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
try {
Method publicDefineClass = loader.getClass().getMethod(
"publicDefineClass", String.class, byte[].class, ProtectionDomain.class);
c = (Class) publicDefineClass.invoke(loader, className, b, protectionDomain);
if (!classLoaderDefineClassMethod.isAccessible()) {
classLoaderDefineClassMethod.setAccessible(true);
}
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
}
catch (InvocationTargetException ex) {
if (!(ex.getTargetException() instanceof UnsupportedOperationException)) {
throw new CodeGenerationException(ex.getTargetException());
}
// in case of UnsupportedOperationException, fall through
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
// publicDefineClass method not available -> fall through
}
// Classic option: protected ClassLoader.defineClass method
if (c == null && classLoaderDefineClassMethod != null) {
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
try {
if (!classLoaderDefineClassMethod.isAccessible()) {
classLoaderDefineClassMethod.setAccessible(true);
}
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
}
catch (InvocationTargetException ex) {
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
// Fall through if setAccessible fails with InaccessibleObjectException on JDK 9+
// (on the module path and/or with a JVM bootstrapped with --illegal-access=deny)
if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) {
throw new CodeGenerationException(ex);
}
// Fall through if setAccessible fails with InaccessibleObjectException on JDK 9+
// (on the module path and/or with a JVM bootstrapped with --illegal-access=deny)
if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) {
throw new CodeGenerationException(ex);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -16,24 +16,20 @@
package org.springframework.core;
import java.util.function.Function;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Interface defining a generic contract for attaching and accessing metadata
* to/from arbitrary objects.
*
* @author Rob Harrop
* @author Sam Brannen
* @since 2.0
*/
public interface AttributeAccessor {
/**
* Set the attribute defined by {@code name} to the supplied {@code value}.
* <p>If {@code value} is {@code null}, the attribute is {@link #removeAttribute removed}.
* If {@code value} is {@code null}, the attribute is {@link #removeAttribute removed}.
* <p>In general, users should take care to prevent overlaps with other
* metadata attributes by using fully-qualified names, perhaps using
* class or package names as prefix.
@@ -44,48 +40,16 @@ public interface AttributeAccessor {
/**
* Get the value of the attribute identified by {@code name}.
* <p>Return {@code null} if the attribute doesn't exist.
* Return {@code null} if the attribute doesn't exist.
* @param name the unique attribute key
* @return the current value of the attribute, if any
*/
@Nullable
Object getAttribute(String name);
/**
* Compute a new value for the attribute identified by {@code name} if
* necessary and {@linkplain #setAttribute set} the new value in this
* {@code AttributeAccessor}.
* <p>If a value for the attribute identified by {@code name} already exists
* in this {@code AttributeAccessor}, the existing value will be returned
* without applying the supplied compute function.
* <p>The default implementation of this method is not thread safe but can
* overridden by concrete implementations of this interface.
* @param <T> the type of the attribute value
* @param name the unique attribute key
* @param computeFunction a function that computes a new value for the attribute
* name; the function must not return a {@code null} value
* @return the existing value or newly computed value for the named attribute
* @see #getAttribute(String)
* @see #setAttribute(String, Object)
* @since 5.3.3
*/
@SuppressWarnings("unchecked")
default <T> T computeAttribute(String name, Function<String, T> computeFunction) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(computeFunction, "Compute function must not be null");
Object value = getAttribute(name);
if (value == null) {
value = computeFunction.apply(name);
Assert.state(value != null,
() -> String.format("Compute function must not return null for attribute named '%s'", name));
setAttribute(name, value);
}
return (T) value;
}
/**
* Remove the attribute identified by {@code name} and return its value.
* <p>Return {@code null} if no attribute under {@code name} is found.
* Return {@code null} if no attribute under {@code name} is found.
* @param name the unique attribute key
* @return the last value of the attribute, if any
*/
@@ -94,7 +58,7 @@ public interface AttributeAccessor {
/**
* Return {@code true} if the attribute identified by {@code name} exists.
* <p>Otherwise return {@code false}.
* Otherwise return {@code false}.
* @param name the unique attribute key
*/
boolean hasAttribute(String name);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -19,7 +19,6 @@ package org.springframework.core;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -33,7 +32,6 @@ import org.springframework.util.StringUtils;
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.0
*/
@SuppressWarnings("serial")
@@ -61,17 +59,6 @@ public abstract class AttributeAccessorSupport implements AttributeAccessor, Ser
return this.attributes.get(name);
}
@Override
@SuppressWarnings("unchecked")
public <T> T computeAttribute(String name, Function<String, T> computeFunction) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(computeFunction, "Compute function must not be null");
Object value = this.attributes.computeIfAbsent(name, computeFunction);
Assert.state(value != null,
() -> String.format("Compute function must not return null for attribute named '%s'", name));
return (T) value;
}
@Override
@Nullable
public Object removeAttribute(String name) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -225,11 +225,11 @@ public final class Conventions {
if (!attributeName.contains("-")) {
return attributeName;
}
char[] result = new char[attributeName.length() -1]; // not completely accurate but good guess
char[] chars = attributeName.toCharArray();
char[] result = new char[chars.length -1]; // not completely accurate but good guess
int currPos = 0;
boolean upperCaseNext = false;
for (int i = 0; i < attributeName.length(); i++ ) {
char c = attributeName.charAt(i);
for (char c : chars) {
if (c == '-') {
upperCaseNext = true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -39,9 +39,15 @@ package org.springframework.core;
*/
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
public DefaultParameterNameDiscoverer() {
// TODO Remove this conditional inclusion when upgrading to Kotlin 1.5, see https://youtrack.jetbrains.com/issue/KT-44594
if (KotlinDetector.isKotlinReflectPresent() && !NativeDetector.inNativeImage()) {
if (KotlinDetector.isKotlinReflectPresent() && !IN_NATIVE_IMAGE) {
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
}
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
@@ -1,39 +0,0 @@
/*
* 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.
* 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.core;
/**
* A common delegate for detecting a GraalVM native image environment.
*
* <p>Requires using the {@code -H:+InlineBeforeAnalysis} native image compiler flag in order to allow code removal at
* build time.
*
* @author Sebastien Deleuze
* @since 5.3.4
*/
public abstract class NativeDetector {
// See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
/**
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
*/
public static boolean inNativeImage() {
return imageCode;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -60,28 +60,7 @@ public class ReactiveAdapterRegistry {
@Nullable
private static volatile ReactiveAdapterRegistry sharedInstance;
private static final boolean reactorPresent;
private static final boolean rxjava1Present;
private static final boolean rxjava2Present;
private static final boolean rxjava3Present;
private static final boolean flowPublisherPresent;
private static final boolean kotlinCoroutinesPresent;
static {
ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader();
reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader);
rxjava1Present = ClassUtils.isPresent("rx.Observable", classLoader) &&
ClassUtils.isPresent("rx.RxReactiveStreams", classLoader);
rxjava2Present = ClassUtils.isPresent("io.reactivex.Flowable", classLoader);
rxjava3Present = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader);
flowPublisherPresent = ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader);
kotlinCoroutinesPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader);
}
private final boolean reactorPresent;
private final List<ReactiveAdapter> adapters = new ArrayList<>();
@@ -91,34 +70,41 @@ public class ReactiveAdapterRegistry {
* @see #getSharedInstance()
*/
public ReactiveAdapterRegistry() {
ClassLoader classLoader = ReactiveAdapterRegistry.class.getClassLoader();
// Reactor
if (reactorPresent) {
boolean reactorRegistered = false;
if (ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader)) {
new ReactorRegistrar().registerAdapters(this);
reactorRegistered = true;
}
this.reactorPresent = reactorRegistered;
// RxJava1 (deprecated)
if (rxjava1Present) {
if (ClassUtils.isPresent("rx.Observable", classLoader) &&
ClassUtils.isPresent("rx.RxReactiveStreams", classLoader)) {
new RxJava1Registrar().registerAdapters(this);
}
// RxJava2
if (rxjava2Present) {
if (ClassUtils.isPresent("io.reactivex.Flowable", classLoader)) {
new RxJava2Registrar().registerAdapters(this);
}
// RxJava3
if (rxjava3Present) {
if (ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable", classLoader)) {
new RxJava3Registrar().registerAdapters(this);
}
// Java 9+ Flow.Publisher
if (flowPublisherPresent) {
if (ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader)) {
new ReactorJdkFlowAdapterRegistrar().registerAdapter(this);
}
// If not present, do nothing for the time being...
// We can fall back on "reactive-streams-flow-bridge" (once released)
// Kotlin Coroutines
if (reactorPresent && kotlinCoroutinesPresent) {
// Coroutines
if (this.reactorPresent && ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader)) {
new CoroutinesRegistrar().registerAdapters(this);
}
}
@@ -139,7 +125,7 @@ public class ReactiveAdapterRegistry {
public void registerReactiveType(ReactiveTypeDescriptor descriptor,
Function<Object, Publisher<?>> toAdapter, Function<Publisher<?>, Object> fromAdapter) {
if (reactorPresent) {
if (this.reactorPresent) {
this.adapters.add(new ReactorAdapter(descriptor, toAdapter, fromAdapter));
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -59,6 +59,13 @@ final class SerializableTypeWrapper {
private static final Class<?>[] SUPPORTED_SERIALIZABLE_TYPES = {
GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class};
/**
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
*/
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
static final ConcurrentReferenceHashMap<Type, Type> cache = new ConcurrentReferenceHashMap<>(256);
@@ -109,7 +116,7 @@ final class SerializableTypeWrapper {
// No serializable type wrapping necessary (e.g. for java.lang.Class)
return providedType;
}
if (NativeDetector.inNativeImage() || !Serializable.class.isAssignableFrom(Class.class)) {
if (IN_NATIVE_IMAGE || !Serializable.class.isAssignableFrom(Class.class)) {
// Let's skip any wrapping attempts if types are generally not serializable in
// the current runtime environment (even java.lang.Class itself, e.g. on GraalVM native images)
return providedType;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -16,10 +16,6 @@
package org.springframework.core;
import java.security.ProtectionDomain;
import org.springframework.lang.Nullable;
/**
* Interface to be implemented by a reloading-aware ClassLoader
* (e.g. a Groovy-based ClassLoader). Detected for example by
@@ -38,41 +34,10 @@ public interface SmartClassLoader {
* Determine whether the given class is reloadable (in this ClassLoader).
* <p>Typically used to check whether the result may be cached (for this
* ClassLoader) or whether it should be reobtained every time.
* The default implementation always returns {@code false}.
* @param clazz the class to check (usually loaded from this ClassLoader)
* @return whether the class should be expected to appear in a reloaded
* version (with a different {@code Class} object) later on
*/
default boolean isClassReloadable(Class<?> clazz) {
return false;
}
/**
* Define a custom class (typically a CGLIB proxy class) in this class loader.
* <p>This is a public equivalent of the protected
* {@code defineClass(String, byte[], int, int, ProtectionDomain)} method
* in {@link ClassLoader} which is traditionally invoked via reflection.
* A concrete implementation in a custom class loader should simply delegate
* to that protected method in order to make classloader-specific definitions
* publicly available without "illegal access" warnings on JDK 9+:
* {@code return defineClass(name, b, 0, b.length, protectionDomain)}.
* Note that the JDK 9+ {@code Lookup#defineClass} method does not support
* a custom target class loader for the new definition; it rather always
* defines the class in the same class loader as the lookup's context class.
* @param name the name of the class
* @param b the bytes defining the class
* @param protectionDomain the protection domain for the class, if any
* @return the newly created class
* @throws LinkageError in case of a bad class definition
* @throws SecurityException in case of an invalid definition attempt
* @throws UnsupportedOperationException in case of a custom definition attempt
* not being possible (thrown by the default implementation in this interface)
* @since 5.3.4
* @see ClassLoader#defineClass(String, byte[], int, int, ProtectionDomain)
* @see java.lang.invoke.MethodHandles.Lookup#defineClass(byte[])
*/
default Class<?> publicDefineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) {
throw new UnsupportedOperationException();
}
boolean isClassReloadable(Class<?> clazz);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -21,6 +21,9 @@ import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
/**
@@ -38,21 +41,17 @@ import org.springframework.lang.Nullable;
*
* @author Juergen Hoeller
* @since 3.2.7
* @see org.springframework.beans.CachedIntrospectionResults#IGNORE_BEANINFO_PROPERTY_NAME
* @see org.springframework.context.index.CandidateComponentsIndexLoader#IGNORE_INDEX
* @see org.springframework.core.env.AbstractEnvironment#IGNORE_GETENV_PROPERTY_NAME
* @see org.springframework.expression.spel.SpelParserConfiguration#SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME
* @see org.springframework.beans.CachedIntrospectionResults#IGNORE_BEANINFO_PROPERTY_NAME
* @see org.springframework.jdbc.core.StatementCreatorUtils#IGNORE_GETPARAMETERTYPE_PROPERTY_NAME
* @see org.springframework.jndi.JndiLocatorDelegate#IGNORE_JNDI_PROPERTY_NAME
* @see org.springframework.objenesis.SpringObjenesis#IGNORE_OBJENESIS_PROPERTY_NAME
* @see org.springframework.test.context.NestedTestConfiguration#ENCLOSING_CONFIGURATION_PROPERTY_NAME
* @see org.springframework.test.context.TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME
* @see org.springframework.test.context.cache.ContextCache#MAX_CONTEXT_CACHE_SIZE_PROPERTY_NAME
*/
public final class SpringProperties {
private static final String PROPERTIES_RESOURCE_LOCATION = "spring.properties";
private static final Log logger = LogFactory.getLog(SpringProperties.class);
private static final Properties localProperties = new Properties();
@@ -62,13 +61,16 @@ public final class SpringProperties {
URL url = (cl != null ? cl.getResource(PROPERTIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResource(PROPERTIES_RESOURCE_LOCATION));
if (url != null) {
logger.debug("Found 'spring.properties' file in local classpath");
try (InputStream is = url.openStream()) {
localProperties.load(is);
}
}
}
catch (IOException ex) {
System.err.println("Could not load 'spring.properties' file from local classpath: " + ex);
if (logger.isInfoEnabled()) {
logger.info("Could not load 'spring.properties' file from local classpath: " + ex);
}
}
}
@@ -106,7 +108,9 @@ public final class SpringProperties {
value = System.getProperty(key);
}
catch (Throwable ex) {
System.err.println("Could not retrieve system property '" + key + "': " + ex);
if (logger.isDebugEnabled()) {
logger.debug("Could not retrieve system property '" + key + "': " + ex);
}
}
}
return value;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -16,7 +16,6 @@
package org.springframework.core.codec;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -60,7 +59,7 @@ public interface Decoder<T> {
* this type must have been previously passed to the {@link #canDecode}
* method and it must have returned {@code true}.
* @param mimeType the MIME type associated with the input stream (optional)
* @param hints additional information about how to do decode
* @param hints additional information about how to do encode
* @return the output stream with decoded elements
*/
Flux<T> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
@@ -73,7 +72,7 @@ public interface Decoder<T> {
* this type must have been previously passed to the {@link #canDecode}
* method and it must have returned {@code true}.
* @param mimeType the MIME type associated with the input stream (optional)
* @param hints additional information about how to do decode
* @param hints additional information about how to do encode
* @return the output stream with the decoded element
*/
Mono<T> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType,
@@ -86,7 +85,7 @@ public interface Decoder<T> {
* @param buffer the {@code DataBuffer} to decode
* @param targetType the expected output type
* @param mimeType the MIME type associated with the data
* @param hints additional information about how to do decode
* @param hints additional information about how to do encode
* @return the decoded value, possibly {@code null}
* @since 5.2
*/
@@ -112,27 +111,8 @@ public interface Decoder<T> {
}
/**
* Return the list of MIME types supported by this Decoder. The list may not
* apply to every possible target element type and calls to this method
* should typically be guarded via {@link #canDecode(ResolvableType, MimeType)
* canDecode(elementType, null)}. The list may also exclude MIME types
* supported only for a specific element type. Alternatively, use
* {@link #getDecodableMimeTypes(ResolvableType)} for a more precise list.
* @return the list of supported MIME types
* Return the list of MIME types this decoder supports.
*/
List<MimeType> getDecodableMimeTypes();
/**
* Return the list of MIME types supported by this Decoder for the given type
* of element. This list may differ from {@link #getDecodableMimeTypes()}
* if the Decoder doesn't support the given element type or if it supports
* it only for a subset of MIME types.
* @param targetType the type of element to check for decoding
* @return the list of MIME types supported for the given target type
* @since 5.3.4
*/
default List<MimeType> getDecodableMimeTypes(ResolvableType targetType) {
return (canDecode(targetType, null) ? getDecodableMimeTypes() : Collections.emptyList());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -16,7 +16,6 @@
package org.springframework.core.codec;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -91,27 +90,8 @@ public interface Encoder<T> {
}
/**
* Return the list of MIME types supported by this Encoder. The list may not
* apply to every possible target element type and calls to this method should
* typically be guarded via {@link #canEncode(ResolvableType, MimeType)
* canEncode(elementType, null)}. The list may also exclude MIME types
* supported only for a specific element type. Alternatively, use
* {@link #getEncodableMimeTypes(ResolvableType)} for a more precise list.
* @return the list of supported MIME types
* Return the list of mime types this encoder supports.
*/
List<MimeType> getEncodableMimeTypes();
/**
* Return the list of MIME types supported by this Encoder for the given type
* of element. This list may differ from the {@link #getEncodableMimeTypes()}
* if the Encoder doesn't support the element type or if it supports it only
* for a subset of MIME types.
* @param elementType the type of element to check for encoding
* @return the list of MIME types supported for the given element type
* @since 5.3.4
*/
default List<MimeType> getEncodableMimeTypes(ResolvableType elementType) {
return (canEncode(elementType, null) ? getEncodableMimeTypes() : Collections.emptyList());
}
}
@@ -21,8 +21,6 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
@@ -150,22 +148,4 @@ public abstract class Hints {
}
}
/**
* If the hints contain a {@link #LOG_PREFIX_HINT} and the given logger has
* DEBUG level enabled, apply the log prefix as a hint to the given buffer
* via {@link DataBufferUtils#touch(DataBuffer, Object)}.
* @param buffer the buffer to touch
* @param hints the hints map to check for a log prefix
* @param logger the logger whose level to check
* @since 5.3.2
*/
public static void touchDataBuffer(DataBuffer buffer, @Nullable Map<String, Object> hints, Log logger) {
if (logger.isDebugEnabled() && hints != null) {
Object logPrefix = hints.get(LOG_PREFIX_HINT);
if (logPrefix != null) {
DataBufferUtils.touch(buffer, logPrefix);
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -130,9 +130,6 @@ public class ResourceRegionEncoder extends AbstractEncoder<ResourceRegion> {
}
Flux<DataBuffer> in = DataBufferUtils.read(resource, position, bufferFactory, this.bufferSize);
if (logger.isDebugEnabled()) {
in = in.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
}
return DataBufferUtils.takeUntilByteCount(in, count);
}
@@ -157,20 +157,16 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
int startIndex = buffer.readPosition();
int length = (endIndex - startIndex + 1);
DataBuffer slice = buffer.retainedSlice(startIndex, length);
if (this.stripDelimiter) {
slice.writePosition(slice.writePosition() - matcher.delimiter().length);
}
result = (result != null ? result : new ArrayList<>());
if (chunks.isEmpty()) {
if (this.stripDelimiter) {
slice.writePosition(slice.writePosition() - matcher.delimiter().length);
}
result.add(slice);
}
else {
chunks.add(slice);
DataBuffer joined = buffer.factory().join(chunks);
if (this.stripDelimiter) {
joined.writePosition(joined.writePosition() - matcher.delimiter().length);
}
result.add(joined);
result.add(buffer.factory().join(chunks));
chunks.clear();
}
buffer.readPosition(endIndex + 1);
@@ -17,17 +17,17 @@
package org.springframework.core.convert.support;
import java.lang.reflect.Array;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.CopyOnWriteArraySet;
import org.springframework.core.DecoratingProxy;
import org.springframework.core.ResolvableType;
@@ -500,9 +500,9 @@ public class GenericConversionService implements ConfigurableConversionService {
*/
private static class Converters {
private final Set<GenericConverter> globalConverters = new CopyOnWriteArraySet<>();
private final Set<GenericConverter> globalConverters = new LinkedHashSet<>();
private final Map<ConvertiblePair, ConvertersForPair> converters = new ConcurrentHashMap<>(256);
private final Map<ConvertiblePair, ConvertersForPair> converters = new LinkedHashMap<>(36);
public void add(GenericConverter converter) {
Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
@@ -513,7 +513,8 @@ public class GenericConversionService implements ConfigurableConversionService {
}
else {
for (ConvertiblePair convertiblePair : convertibleTypes) {
getMatchableConverters(convertiblePair).add(converter);
ConvertersForPair convertersForPair = getMatchableConverters(convertiblePair);
convertersForPair.add(converter);
}
}
}
@@ -651,7 +652,7 @@ public class GenericConversionService implements ConfigurableConversionService {
*/
private static class ConvertersForPair {
private final Deque<GenericConverter> converters = new ConcurrentLinkedDeque<>();
private final Deque<GenericConverter> converters = new ArrayDeque<>(1);
public void add(GenericConverter converter) {
this.converters.addFirst(converter);

Some files were not shown because too many files have changed in this diff Show More