Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Buildmaster 967637d763 Release v5.3.1 2020-11-10 08:59:43 +00:00
321 changed files with 3032 additions and 8370 deletions
+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".
+32 -32
View File
@@ -1,7 +1,7 @@
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.21' 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'
@@ -9,7 +9,7 @@ plugins {
id "io.freefair.aspectj" version '5.1.1' apply false
id "com.github.ben-manes.versions" version '0.28.0'
id "me.champeau.gradle.jmh" version "0.5.0" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.21" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.10" apply false
}
ext {
@@ -25,18 +25,18 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.0"
mavenBom "io.netty:netty-bom:4.1.56.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.3"
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.35.v20201120"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.21"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.2"
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'
@@ -53,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
@@ -63,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.20"
dependency "io.reactivex.rxjava3:rxjava:3.0.9"
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"
@@ -73,9 +73,9 @@ 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.14") {
dependency("com.thoughtworks.xstream:xstream:1.4.13") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
@@ -95,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.24"
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"
@@ -123,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.27.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.41') {
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.41') {
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.3.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"
@@ -154,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"
@@ -190,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.18.1"
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.0') {
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.46.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.44.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.46.0") {
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") {
@@ -236,7 +236,7 @@ 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.9"
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"
@@ -339,7 +339,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.39"
toolVersion = "8.36.2"
configDirectory.set(rootProject.file("src/checkstyle"))
}
+6 -3
View File
@@ -3,13 +3,16 @@ set -e
case "$1" in
java8)
echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u275-b01/OpenJDK8U-jdk_x64_linux_hotspot_8u275b01.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.9.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.9.1_1.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.1%2B9/OpenJDK15U-jdk_x64_linux_hotspot_15.0.1_9.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-20201106
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-20201106
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-20201106
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.3
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 -18
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,23 +56,6 @@ eclipse.classpath.file.whenMerged { classpath ->
}
}
// Ensure that test fixture dependencies are handled properly in Gradle 6.7.
// Bug fixed in Gradle 6.8: https://github.com/gradle/gradle/issues/14932
eclipse.classpath.file.whenMerged {
entries.findAll { it instanceof ProjectDependency }.each {
it.entryAttributes.remove('without_test_code')
}
}
// 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"
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -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-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")
@@ -543,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 {
@@ -560,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;
}
/**
@@ -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) {
@@ -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,
@@ -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-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 {
@@ -427,11 +427,15 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty() || IN_NATIVE_IMAGE) {
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 {
@@ -815,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 " +
@@ -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++) {
@@ -78,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.
@@ -131,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.
@@ -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);
@@ -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.
@@ -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,62 +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);
}
}
@@ -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,7 +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"));
}
}
@@ -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() }
@@ -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) {
@@ -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.
@@ -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.
@@ -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 {
@@ -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;
/**
@@ -47,6 +50,8 @@ 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();
@@ -56,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);
}
}
}
@@ -100,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;
@@ -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);
}
@@ -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);
@@ -487,24 +487,6 @@ public abstract class DataBufferUtils {
}
}
/**
* Associate the given hint with the data buffer if it is a pooled buffer
* and supports leak tracking.
* @param dataBuffer the data buffer to attach the hint to
* @param hint the hint to attach
* @return the input buffer
* @since 5.3.2
*/
@SuppressWarnings("unchecked")
public static <T extends DataBuffer> T touch(T dataBuffer, Object hint) {
if (dataBuffer instanceof PooledDataBuffer) {
return (T) ((PooledDataBuffer) dataBuffer).touch(hint);
}
else {
return dataBuffer;
}
}
/**
* Release the given data buffer, if it is a {@link PooledDataBuffer} and
* has been {@linkplain PooledDataBuffer#isAllocated() allocated}.
@@ -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.
@@ -54,8 +54,11 @@ public class LimitedDataBufferList extends ArrayList<DataBuffer> {
@Override
public boolean add(DataBuffer buffer) {
updateCount(buffer.readableByteCount());
return super.add(buffer);
boolean result = super.add(buffer);
if (result) {
updateCount(buffer.readableByteCount());
}
return result;
}
@Override
@@ -315,12 +315,6 @@ public class NettyDataBuffer implements PooledDataBuffer {
return new NettyDataBuffer(this.byteBuf.retain(), this.dataBufferFactory);
}
@Override
public PooledDataBuffer touch(Object hint) {
this.byteBuf.touch(hint);
return this;
}
@Override
public boolean release() {
return this.byteBuf.release();
@@ -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.
@@ -38,13 +38,6 @@ public interface PooledDataBuffer extends DataBuffer {
*/
PooledDataBuffer retain();
/**
* Associate the given hint with the data buffer for debugging purposes.
* @return this buffer
* @since 5.3.2
*/
PooledDataBuffer touch(Object hint);
/**
* Decrease the reference count for this buffer by one,
* and deallocate it once the count reaches zero.
@@ -432,9 +432,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
// Possibly "c:" drive prefix on Windows, to be upper-cased for proper duplicate detection
filePath = StringUtils.capitalize(filePath);
}
// # can appear in directories/filenames, java.net.URL should not treat it as a fragment
filePath = StringUtils.replace(filePath, "#", "%23");
// Build URL that points to the root of the jar file
UrlResource jarResource = new UrlResource(ResourceUtils.JAR_URL_PREFIX +
ResourceUtils.FILE_URL_PREFIX + filePath + ResourceUtils.JAR_URL_SEPARATOR);
// Potentially overlapping with URLClassLoader.getURLs() result above!
@@ -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.
@@ -18,11 +18,10 @@ package org.springframework.core.io.support;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -130,7 +129,7 @@ public class ResourceArrayPropertyEditor extends PropertyEditorSupport {
public void setValue(Object value) throws IllegalArgumentException {
if (value instanceof Collection || (value instanceof Object[] && !(value instanceof Resource[]))) {
Collection<?> input = (value instanceof Collection ? (Collection<?>) value : Arrays.asList((Object[]) value));
Set<Resource> merged = new LinkedHashSet<>();
List<Resource> merged = new ArrayList<>();
for (Object element : input) {
if (element instanceof String) {
// A location pattern: resolve it into a Resource array.
@@ -138,7 +137,11 @@ public class ResourceArrayPropertyEditor extends PropertyEditorSupport {
String pattern = resolvePath((String) element).trim();
try {
Resource[] resources = this.resourcePatternResolver.getResources(pattern);
Collections.addAll(merged, resources);
for (Resource resource : resources) {
if (!merged.contains(resource)) {
merged.add(resource);
}
}
}
catch (IOException ex) {
// ignore - might be an unresolved placeholder or non-existing base directory
@@ -149,7 +152,10 @@ public class ResourceArrayPropertyEditor extends PropertyEditorSupport {
}
else if (element instanceof Resource) {
// A Resource object: add it to the result.
merged.add((Resource) element);
Resource resource = (Resource) element;
if (!merged.contains(resource)) {
merged.add(resource);
}
}
else {
throw new IllegalArgumentException("Cannot convert element [" + element + "] to [" +
@@ -644,7 +644,7 @@ public class AntPathMatcher implements PathMatcher {
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?}|[^/{}]|\\\\[{}])+?)}");
private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
private final String rawPattern;
@@ -16,8 +16,6 @@
package org.springframework.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.BitSet;
@@ -106,7 +104,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
private final Map<String, String> parameters;
@Nullable
private transient Charset resolvedCharset;
private Charset resolvedCharset;
@Nullable
private volatile String toStringValue;
@@ -186,9 +184,9 @@ public class MimeType implements Comparable<MimeType>, Serializable {
this.subtype = subtype.toLowerCase(Locale.ENGLISH);
if (!CollectionUtils.isEmpty(parameters)) {
Map<String, String> map = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ENGLISH);
parameters.forEach((parameter, value) -> {
checkParameters(parameter, value);
map.put(parameter, value);
parameters.forEach((attribute, value) -> {
checkParameters(attribute, value);
map.put(attribute, value);
});
this.parameters = Collections.unmodifiableMap(map);
}
@@ -226,11 +224,11 @@ public class MimeType implements Comparable<MimeType>, Serializable {
}
}
protected void checkParameters(String parameter, String value) {
Assert.hasLength(parameter, "'parameter' must not be empty");
protected void checkParameters(String attribute, String value) {
Assert.hasLength(attribute, "'attribute' must not be empty");
Assert.hasLength(value, "'value' must not be empty");
checkToken(parameter);
if (PARAM_CHARSET.equals(parameter)) {
checkToken(attribute);
if (PARAM_CHARSET.equals(attribute)) {
if (this.resolvedCharset == null) {
this.resolvedCharset = Charset.forName(unquote(value));
}
@@ -593,17 +591,6 @@ public class MimeType implements Comparable<MimeType>, Serializable {
return 0;
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// Rely on default serialization, just initialize state after deserialization.
ois.defaultReadObject();
// Initialize transient fields.
String charsetName = getParameter(PARAM_CHARSET);
if (charsetName != null) {
this.resolvedCharset = Charset.forName(unquote(charsetName));
}
}
/**
* Parse the given String value into a {@code MimeType} object,
@@ -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.
@@ -824,19 +824,6 @@ public abstract class ReflectionUtils {
* @param method the method to check
*/
boolean matches(Method method);
/**
* Create a composite filter based on this filter <em>and</em> the provided filter.
* <p>If this filter does not match, the next filter will not be applied.
* @param next the next {@code MethodFilter}
* @return a composite {@code MethodFilter}
* @throws IllegalArgumentException if the MethodFilter argument is {@code null}
* @since 5.3.2
*/
default MethodFilter and(MethodFilter next) {
Assert.notNull(next, "Next MethodFilter must not be null");
return method -> matches(method) && next.matches(method);
}
}
@@ -865,19 +852,6 @@ public abstract class ReflectionUtils {
* @param field the field to check
*/
boolean matches(Field field);
/**
* Create a composite filter based on this filter <em>and</em> the provided filter.
* <p>If this filter does not match, the next filter will not be applied.
* @param next the next {@code FieldFilter}
* @return a composite {@code FieldFilter}
* @throws IllegalArgumentException if the FieldFilter argument is {@code null}
* @since 5.3.2
*/
default FieldFilter and(FieldFilter next) {
Assert.notNull(next, "Next FieldFilter must not be null");
return field -> matches(field) && next.matches(field);
}
}
}
@@ -161,8 +161,9 @@ class XMLEventStreamWriter implements XMLStreamWriter {
public void writeEndElement() throws XMLStreamException {
closeEmptyElementIfNecessary();
int last = this.endElements.size() - 1;
EndElement lastEndElement = this.endElements.remove(last);
EndElement lastEndElement = this.endElements.get(last);
this.eventWriter.add(lastEndElement);
this.endElements.remove(last);
}
@Override
@@ -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.
@@ -17,61 +17,39 @@
package org.springframework.core;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link AttributeAccessorSupport}.
*
* @author Rob Harrop
* @author Sam Brannen
* @since 2.0
*/
class AttributeAccessorSupportTests {
private static final String NAME = "name";
private static final String NAME = "foo";
private static final String VALUE = "value";
private final AttributeAccessor attributeAccessor = new SimpleAttributeAccessorSupport();
private static final String VALUE = "bar";
private AttributeAccessor attributeAccessor = new SimpleAttributeAccessorSupport();
@Test
void setAndGet() {
void setAndGet() throws Exception {
this.attributeAccessor.setAttribute(NAME, VALUE);
assertThat(this.attributeAccessor.getAttribute(NAME)).isEqualTo(VALUE);
}
@Test
void setAndHas() {
void setAndHas() throws Exception {
assertThat(this.attributeAccessor.hasAttribute(NAME)).isFalse();
this.attributeAccessor.setAttribute(NAME, VALUE);
assertThat(this.attributeAccessor.hasAttribute(NAME)).isTrue();
}
@Test
void computeAttribute() {
AtomicInteger atomicInteger = new AtomicInteger();
Function<String, String> computeFunction = name -> "computed-" + atomicInteger.incrementAndGet();
assertThat(this.attributeAccessor.hasAttribute(NAME)).isFalse();
this.attributeAccessor.computeAttribute(NAME, computeFunction);
assertThat(this.attributeAccessor.getAttribute(NAME)).isEqualTo("computed-1");
this.attributeAccessor.computeAttribute(NAME, computeFunction);
assertThat(this.attributeAccessor.getAttribute(NAME)).isEqualTo("computed-1");
this.attributeAccessor.removeAttribute(NAME);
assertThat(this.attributeAccessor.hasAttribute(NAME)).isFalse();
this.attributeAccessor.computeAttribute(NAME, computeFunction);
assertThat(this.attributeAccessor.getAttribute(NAME)).isEqualTo("computed-2");
}
@Test
void remove() {
void remove() throws Exception {
assertThat(this.attributeAccessor.hasAttribute(NAME)).isFalse();
this.attributeAccessor.setAttribute(NAME, VALUE);
assertThat(this.attributeAccessor.removeAttribute(NAME)).isEqualTo(VALUE);
@@ -79,13 +57,13 @@ class AttributeAccessorSupportTests {
}
@Test
void attributeNames() {
void attributeNames() throws Exception {
this.attributeAccessor.setAttribute(NAME, VALUE);
this.attributeAccessor.setAttribute("abc", "123");
String[] attributeNames = this.attributeAccessor.attributeNames();
Arrays.sort(attributeNames);
assertThat(Arrays.binarySearch(attributeNames, "abc")).isEqualTo(0);
assertThat(Arrays.binarySearch(attributeNames, NAME)).isEqualTo(1);
assertThat(Arrays.binarySearch(attributeNames, NAME) > -1).isTrue();
assertThat(Arrays.binarySearch(attributeNames, "abc") > -1).isTrue();
}
@SuppressWarnings("serial")
@@ -367,9 +367,8 @@ class ReactiveAdapterRegistryTests {
private static class ExtendedFlux<T> extends Flux<T> {
@Override
public void subscribe(CoreSubscriber<? super T> actual) {
public void subscribe(CoreSubscriber actual) {
throw new UnsupportedOperationException();
}
}
}
@@ -35,8 +35,6 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.Answer;
import org.reactivestreams.Subscription;
import reactor.core.publisher.BaseSubscriber;
@@ -836,22 +834,6 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
.verifyError(DataBufferLimitException.class);
}
@Test // gh-26060
void joinWithLimitDoesNotOverRelease() {
NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(PooledByteBufAllocator.DEFAULT);
byte[] bytes = "foo-bar-baz".getBytes(StandardCharsets.UTF_8);
NettyDataBuffer buffer = bufferFactory.allocateBuffer(bytes.length);
buffer.getNativeBuffer().retain(); // should be at 2 now
buffer.write(bytes);
Mono<DataBuffer> result = DataBufferUtils.join(Flux.just(buffer), 8);
StepVerifier.create(result).verifyError(DataBufferLimitException.class);
assertThat(buffer.getNativeBuffer().refCnt()).isEqualTo(1);
buffer.release();
}
@ParameterizedDataBufferAllocatingTest
void joinErrors(String displayName, DataBufferFactory bufferFactory) {
super.bufferFactory = bufferFactory;
@@ -17,11 +17,9 @@ package org.springframework.core.io.buffer;
import java.nio.charset.StandardCharsets;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* Unit tests for {@link LimitedDataBufferList}.
* @author Rossen Stoyanchev
@@ -31,10 +29,8 @@ public class LimitedDataBufferListTests {
@Test
void limitEnforced() {
LimitedDataBufferList list = new LimitedDataBufferList(5);
assertThatThrownBy(() -> list.add(toDataBuffer("123456"))).isInstanceOf(DataBufferLimitException.class);
assertThat(list).isEmpty();
Assertions.assertThatThrownBy(() -> new LimitedDataBufferList(5).add(toDataBuffer("123456")))
.isInstanceOf(DataBufferLimitException.class);
}
@Test
@@ -130,7 +130,6 @@ class AntPathMatcherTests {
assertThat(pathMatcher.match("", "")).isTrue();
assertThat(pathMatcher.match("/{bla}.*", "/testing.html")).isTrue();
assertThat(pathMatcher.match("/{bla}", "//x\ny")).isTrue();
}
@Test
@@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.testfixture.io.SerializationTestUtils;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
@@ -268,13 +267,13 @@ class MimeTypeTests {
assertThat(mimeType.getParameter("attr")).isEqualTo("'v>alue'");
}
@Test // SPR-16630
@Test // SPR-16630
void parseMimeTypeWithSpacesAroundEquals() {
MimeType mimeType = MimeTypeUtils.parseMimeType("multipart/x-mixed-replace;boundary = --myboundary");
assertThat(mimeType.getParameter("boundary")).isEqualTo("--myboundary");
}
@Test // SPR-16630
@Test // SPR-16630
void parseMimeTypeWithSpacesAroundEqualsAndQuotedValue() {
MimeType mimeType = MimeTypeUtils.parseMimeType("text/plain; foo = \" bar \" ");
assertThat(mimeType.getParameter("foo")).isEqualTo("\" bar \"");
@@ -304,14 +303,14 @@ class MimeTypeTests {
assertThat(mimeTypes.size()).as("Invalid amount of mime types").isEqualTo(0);
}
@Test // gh-23241
@Test // gh-23241
void parseMimeTypesWithTrailingComma() {
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes("text/plain, text/html,");
assertThat(mimeTypes).as("No mime types returned").isNotNull();
assertThat(mimeTypes.size()).as("Incorrect number of mime types").isEqualTo(2);
}
@Test // SPR-17459
@Test // SPR-17459
void parseMimeTypesWithQuotedParameters() {
testWithQuotedParameters("foo/bar;param=\",\"");
testWithQuotedParameters("foo/bar;param=\"s,a,\"");
@@ -333,7 +332,7 @@ class MimeTypeTests {
assertThat(type.getSubtypeSuffix()).isEqualTo("json");
}
@Test // gh-25350
@Test // gh-25350
void wildcardSubtypeCompatibleWithSuffix() {
MimeType applicationStar = new MimeType("application", "*");
MimeType applicationVndJson = new MimeType("application", "vnd.something+json");
@@ -343,9 +342,8 @@ class MimeTypeTests {
private void testWithQuotedParameters(String... mimeTypes) {
String s = String.join(",", mimeTypes);
List<MimeType> actual = MimeTypeUtils.parseMimeTypes(s);
assertThat(actual.size()).isEqualTo(mimeTypes.length);
for (int i = 0; i < mimeTypes.length; i++) {
for (int i=0; i < mimeTypes.length; i++) {
assertThat(actual.get(i).toString()).isEqualTo(mimeTypes[i]);
}
}
@@ -372,7 +370,6 @@ class MimeTypeTests {
List<MimeType> result = new ArrayList<>(expected);
Random rnd = new Random();
// shuffle & sort 10 times
for (int i = 0; i < 10; i++) {
Collections.shuffle(result, rnd);
@@ -402,7 +399,11 @@ class MimeTypeTests {
assertThat(m2.compareTo(m1) != 0).as("Invalid comparison result").isTrue();
}
@Test // SPR-13157
/**
* SPR-13157
* @since 4.2
*/
@Test
void equalsIsCaseInsensitiveForCharsets() {
MimeType m1 = new MimeType("text", "plain", singletonMap("charset", "UTF-8"));
MimeType m2 = new MimeType("text", "plain", singletonMap("charset", "utf-8"));
@@ -412,12 +413,4 @@ class MimeTypeTests {
assertThat(m2.compareTo(m1)).isEqualTo(0);
}
@Test // gh-26127
void serialize() throws Exception {
MimeType original = new MimeType("text", "plain", StandardCharsets.UTF_8);
MimeType deserialized = SerializationTestUtils.serializeAndDeserialize(original);
assertThat(deserialized).isEqualTo(original);
assertThat(original).isEqualTo(deserialized);
}
}
@@ -186,7 +186,12 @@ class ReflectionUtilsTests {
@Test
void doWithProtectedMethods() {
ListSavingMethodCallback mc = new ListSavingMethodCallback();
ReflectionUtils.doWithMethods(TestObject.class, mc, method -> Modifier.isProtected(method.getModifiers()));
ReflectionUtils.doWithMethods(TestObject.class, mc, new ReflectionUtils.MethodFilter() {
@Override
public boolean matches(Method m) {
return Modifier.isProtected(m.getModifiers());
}
});
assertThat(mc.getMethodNames().isEmpty()).isFalse();
assertThat(mc.getMethodNames().contains("clone")).as("Must find protected method on Object").isTrue();
assertThat(mc.getMethodNames().contains("finalize")).as("Must find protected method on Object").isTrue();
@@ -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.
@@ -17,7 +17,6 @@
package org.springframework.core.testfixture.io.buffer;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DataBufferWrapper;
import org.springframework.core.io.buffer.PooledDataBuffer;
import org.springframework.util.Assert;
@@ -68,19 +67,19 @@ class LeakAwareDataBuffer extends DataBufferWrapper implements PooledDataBuffer
@Override
public PooledDataBuffer retain() {
DataBufferUtils.retain(dataBuffer());
return this;
}
@Override
public PooledDataBuffer touch(Object hint) {
DataBufferUtils.touch(dataBuffer(), hint);
DataBuffer delegate = dataBuffer();
if (delegate instanceof PooledDataBuffer) {
((PooledDataBuffer) delegate).retain();
}
return this;
}
@Override
public boolean release() {
DataBufferUtils.release(dataBuffer());
DataBuffer delegate = dataBuffer();
if (delegate instanceof PooledDataBuffer) {
((PooledDataBuffer) delegate).release();
}
return isAllocated();
}
@@ -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.
@@ -54,9 +54,10 @@ public abstract class AstUtils {
}
else {
if (targetType != null) {
int pos = 0;
for (Class<?> clazz : targets) {
if (clazz == targetType) { // put exact matches on the front to be tried first?
specificAccessors.add(resolver);
specificAccessors.add(pos++, resolver);
}
else if (clazz.isAssignableFrom(targetType)) { // put supertype matches at the end of the
// specificAccessor list
@@ -47,7 +47,7 @@ import org.springframework.util.StringUtils;
/**
* A powerful {@link PropertyAccessor} that uses reflection to access properties
* for reading and possibly also for writing on a target instance.
* for reading and possibly also for writing.
*
* <p>A property can be referenced through a public getter method (when being read)
* or a public setter method (when being written), and also as a public field.
@@ -98,8 +98,8 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
}
/**
* Create a new property accessor for reading and possibly also writing.
* @param allowWrite whether to allow write operations on a target instance
* Create a new property accessor for reading and possibly writing.
* @param allowWrite whether to also allow for write operations
* @since 4.3.15
* @see #canWrite
*/
@@ -628,8 +628,8 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
@Override
public String toString() {
return "PropertyCacheKey [clazz=" + this.clazz.getName() + ", property=" + this.property +
", targetIsClass=" + this.targetIsClass + "]";
return "CacheKey [clazz=" + this.clazz.getName() + ", property=" + this.property + ", " +
this.property + ", targetIsClass=" + this.targetIsClass + "]";
}
@Override
@@ -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,10 +36,10 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* @author Andy Clement
* @author Juergen Hoeller
*/
class SpelParserTests {
public class SpelParserTests {
@Test
void theMostBasic() {
public void theMostBasic() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2");
assertThat(expr).isNotNull();
@@ -50,7 +50,7 @@ class SpelParserTests {
}
@Test
void valueType() {
public void valueType() {
SpelExpressionParser parser = new SpelExpressionParser();
EvaluationContext ctx = new StandardEvaluationContext();
Class<?> c = parser.parseRaw("2").getValueType();
@@ -66,7 +66,7 @@ class SpelParserTests {
}
@Test
void whitespace() {
public void whitespace() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2 + 3");
assertThat(expr.getValue()).isEqualTo(5);
@@ -79,7 +79,7 @@ class SpelParserTests {
}
@Test
void arithmeticPlus1() {
public void arithmeticPlus1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+2");
assertThat(expr).isNotNull();
@@ -88,65 +88,66 @@ class SpelParserTests {
}
@Test
void arithmeticPlus2() {
public void arithmeticPlus2() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("37+41");
assertThat(expr.getValue()).isEqualTo(78);
}
@Test
void arithmeticMultiply1() {
public void arithmeticMultiply1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3");
assertThat(expr).isNotNull();
assertThat(expr.getAST()).isNotNull();
// printAst(expr.getAST(),0);
assertThat(expr.getValue()).isEqualTo(6);
}
@Test
void arithmeticPrecedence1() {
public void arithmeticPrecedence1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3+5");
assertThat(expr.getValue()).isEqualTo(11);
}
@Test
void generalExpressions() {
public void generalExpressions() {
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String");
})
.satisfies(parseExceptionRequirements(SpelMessage.MISSING_CONSTRUCTOR_ARGS, 10));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.MISSING_CONSTRUCTOR_ARGS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3,");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("\"abc");
})
.satisfies(parseExceptionRequirements(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING, 0));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING, 0));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("'abc");
})
.satisfies(parseExceptionRequirements(SpelMessage.NON_TERMINATING_QUOTED_STRING, 0));
.satisfies(ex -> parseExceptionRequirements(SpelMessage.NON_TERMINATING_QUOTED_STRING, 0));
}
@@ -160,38 +161,38 @@ class SpelParserTests {
}
@Test
void arithmeticPrecedence2() {
public void arithmeticPrecedence2() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+3*5");
assertThat(expr.getValue()).isEqualTo(17);
}
@Test
void arithmeticPrecedence3() {
public void arithmeticPrecedence3() {
SpelExpression expr = new SpelExpressionParser().parseRaw("3+10/2");
assertThat(expr.getValue()).isEqualTo(8);
}
@Test
void arithmeticPrecedence4() {
public void arithmeticPrecedence4() {
SpelExpression expr = new SpelExpressionParser().parseRaw("10/2+3");
assertThat(expr.getValue()).isEqualTo(8);
}
@Test
void arithmeticPrecedence5() {
public void arithmeticPrecedence5() {
SpelExpression expr = new SpelExpressionParser().parseRaw("(4+10)/2");
assertThat(expr.getValue()).isEqualTo(7);
}
@Test
void arithmeticPrecedence6() {
public void arithmeticPrecedence6() {
SpelExpression expr = new SpelExpressionParser().parseRaw("(3+2)*2");
assertThat(expr.getValue()).isEqualTo(10);
}
@Test
void booleanOperators() {
public void booleanOperators() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("false");
@@ -209,7 +210,7 @@ class SpelParserTests {
}
@Test
void booleanOperators_symbolic_spr9614() {
public void booleanOperators_symbolic_spr9614() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("false");
@@ -227,7 +228,7 @@ class SpelParserTests {
}
@Test
void stringLiterals() {
public void stringLiterals() {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'");
assertThat(expr.getValue()).isEqualTo("howdy");
expr = new SpelExpressionParser().parseRaw("'hello '' world'");
@@ -235,13 +236,13 @@ class SpelParserTests {
}
@Test
void stringLiterals2() {
public void stringLiterals2() {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'.substring(0,2)");
assertThat(expr.getValue()).isEqualTo("ho");
}
@Test
void testStringLiterals_DoubleQuotes_spr9620() {
public void testStringLiterals_DoubleQuotes_spr9620() {
SpelExpression expr = new SpelExpressionParser().parseRaw("\"double quote: \"\".\"");
assertThat(expr.getValue()).isEqualTo("double quote: \".");
expr = new SpelExpressionParser().parseRaw("\"hello \"\" world\"");
@@ -249,7 +250,7 @@ class SpelParserTests {
}
@Test
void testStringLiterals_DoubleQuotes_spr9620_2() {
public void testStringLiterals_DoubleQuotes_spr9620_2() {
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() ->
new SpelExpressionParser().parseRaw("\"double quote: \\\"\\\".\""))
.satisfies(ex -> {
@@ -259,7 +260,7 @@ class SpelParserTests {
}
@Test
void positionalInformation() {
public void positionalInformation() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false");
SpelNode rootAst = expr.getAST();
OpOr operatorOr = (OpOr) rootAst;
@@ -288,7 +289,7 @@ class SpelParserTests {
}
@Test
void tokenKind() {
public void tokenKind() {
TokenKind tk = TokenKind.NOT;
assertThat(tk.hasPayload()).isFalse();
assertThat(tk.toString()).isEqualTo("NOT(!)");
@@ -303,7 +304,7 @@ class SpelParserTests {
}
@Test
void token() {
public void token() {
Token token = new Token(TokenKind.NOT, 0, 3);
assertThat(token.kind).isEqualTo(TokenKind.NOT);
assertThat(token.startPos).isEqualTo(0);
@@ -318,7 +319,7 @@ class SpelParserTests {
}
@Test
void exceptions() {
public void exceptions() {
ExpressionException exprEx = new ExpressionException("test");
assertThat(exprEx.getSimpleMessage()).isEqualTo("test");
assertThat(exprEx.toDetailedString()).isEqualTo("test");
@@ -336,13 +337,13 @@ class SpelParserTests {
}
@Test
void parseMethodsOnNumbers() {
public void parseMethodsOnNumbers() {
checkNumber("3.14.toString()", "3.14", String.class);
checkNumber("3.toString()", "3", String.class);
}
@Test
void numerics() {
public void numerics() {
checkNumber("2", 2, Integer.class);
checkNumber("22", 22, Integer.class);
checkNumber("+22", 22, Integer.class);
@@ -384,7 +385,8 @@ class SpelParserTests {
private void checkNumberError(String expression, SpelMessage expectedMessage) {
SpelExpressionParser parser = new SpelExpressionParser();
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> parser.parseRaw(expression))
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() ->
parser.parseRaw(expression))
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(expectedMessage));
}
@@ -30,6 +30,7 @@ import java.util.Set;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Helper class that efficiently creates multiple {@link PreparedStatementCreator}
@@ -199,8 +200,9 @@ public class PreparedStatementCreatorFactory {
public PreparedStatementCreatorImpl(String actualSql, List<?> parameters) {
this.actualSql = actualSql;
Assert.notNull(parameters, "Parameters List must not be null");
this.parameters = parameters;
if (parameters.size() != declaredParameters.size()) {
if (this.parameters.size() != declaredParameters.size()) {
// Account for named parameters being used multiple times
Set<String> names = new HashSet<>();
for (int i = 0; i < parameters.size(); i++) {
@@ -345,9 +345,9 @@ public abstract class NamedParameterUtils {
for (int i = 0; i < paramNames.size(); i++) {
String paramName = paramNames.get(i);
try {
Object value = paramSource.getValue(paramName);
SqlParameter param = findParameter(declaredParams, paramName, i);
paramArray[i] = (param != null ? new SqlParameterValue(param, paramSource.getValue(paramName)) :
SqlParameterSourceUtils.getTypedValue(paramSource, paramName));
paramArray[i] = (param != null ? new SqlParameterValue(param, value) : value);
}
catch (IllegalArgumentException ex) {
throw new InvalidDataAccessApiUsageException(
@@ -92,13 +92,17 @@ public abstract class SqlParameterSourceUtils {
* @param source the source of parameter values and type information
* @param parameterName the name of the parameter
* @return the value object
* @see SqlParameterValue
*/
@Nullable
public static Object getTypedValue(SqlParameterSource source, String parameterName) {
int sqlType = source.getSqlType(parameterName);
if (sqlType != SqlParameterSource.TYPE_UNKNOWN) {
return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
if (source.getTypeName(parameterName) != null) {
return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
}
else {
return new SqlParameterValue(sqlType, source.getValue(parameterName));
}
}
else {
return source.getValue(parameterName);
@@ -433,7 +433,7 @@ public abstract class AbstractJdbcCall {
/**
* Match the provided in parameter values with registered parameters and
* parameters defined via meta-data processing.
* @param parameterSource the parameter values provided as a {@link SqlParameterSource}
* @param parameterSource the parameter vakues provided as a {@link SqlParameterSource}
* @return a Map with parameter names and values
*/
protected Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
@@ -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.
@@ -54,10 +54,8 @@ inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<ou
* @author Mario Arias
* @since 5.0
*/
@Suppress("DEPRECATION")
// TODO Replace by the vararg variant in Spring Framework 6
inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<out Any>): T? =
queryForObject(sql, args, T::class.java) as T
queryForObject(sql, T::class.java, args) as T
/**
* Extension for [JdbcOperations.queryForList] providing a `queryForList<Foo>("...")` variant.
@@ -88,11 +86,8 @@ inline fun <reified T> JdbcOperations.queryForList(sql: String, args: Array<out
* @author Mario Arias
* @since 5.0
*/
@Suppress("DEPRECATION")
// TODO Replace by the vararg variant in Spring Framework 6
inline fun <reified T> JdbcOperations.queryForList(sql: String, args: Array<out Any>): List<T> =
queryForList(sql, args, T::class.java)
queryForList(sql, T::class.java, args)
/**
* Extension for [JdbcOperations.query] providing a ResultSetExtractor-like function
@@ -247,7 +247,7 @@
<value>03000,42000,42601,42602,42622,42804,42P01</value>
</property>
<property name="duplicateKeyCodes">
<value>21000,23505</value>
<value>23505</value>
</property>
<property name="dataIntegrityViolationCodes">
<value>23000,23502,23503,23514</value>
@@ -561,11 +561,10 @@ public class NamedParameterJdbcTemplateTests {
@Test
public void testBatchUpdateWithSqlParameterSourcePlusTypeInfo() throws Exception {
SqlParameterSource[] ids = new SqlParameterSource[3];
ids[0] = new MapSqlParameterSource().addValue("id", null, Types.NULL);
ids[1] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC);
ids[2] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC);
final int[] rowsAffected = new int[] {1, 2, 3};
SqlParameterSource[] ids = new SqlParameterSource[2];
ids[0] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC);
ids[1] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC);
final int[] rowsAffected = new int[] {1, 2};
given(preparedStatement.executeBatch()).willReturn(rowsAffected);
given(connection.getMetaData()).willReturn(databaseMetaData);
@@ -573,15 +572,13 @@ public class NamedParameterJdbcTemplateTests {
int[] actualRowsAffected = namedParameterTemplate.batchUpdate(
"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id", ids);
assertThat(actualRowsAffected.length == 3).as("executed 3 updates").isTrue();
assertThat(actualRowsAffected.length == 2).as("executed 2 updates").isTrue();
assertThat(actualRowsAffected[0]).isEqualTo(rowsAffected[0]);
assertThat(actualRowsAffected[1]).isEqualTo(rowsAffected[1]);
assertThat(actualRowsAffected[2]).isEqualTo(rowsAffected[2]);
verify(connection).prepareStatement("UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?");
verify(preparedStatement).setNull(1, Types.NULL);
verify(preparedStatement).setObject(1, 100, Types.NUMERIC);
verify(preparedStatement).setObject(1, 200, Types.NUMERIC);
verify(preparedStatement, times(3)).addBatch();
verify(preparedStatement, times(2)).addBatch();
verify(preparedStatement, atLeastOnce()).close();
verify(connection, atLeastOnce()).close();
}
@@ -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.
@@ -67,12 +67,11 @@ class JdbcOperationsExtensionsTests {
}
@Test
@Suppress("DEPRECATION")
fun `queryForObject with reified type parameters and args`() {
val args = arrayOf(3, 4)
every { template.queryForObject(sql, args, any<Class<Int>>()) } returns 2
val args = arrayOf(3)
every { template.queryForObject(sql, any<Class<Int>>(), args) } returns 2
assertThat(template.queryForObject<Int>(sql, args)).isEqualTo(2)
verify { template.queryForObject(sql, args, any<Class<Int>>()) }
verify { template.queryForObject(sql, any<Class<Int>>(), args) }
}
@Test
@@ -94,13 +93,12 @@ class JdbcOperationsExtensionsTests {
}
@Test
@Suppress("DEPRECATION")
fun `queryForList with reified type parameters and args`() {
val list = listOf(1, 2, 3)
val args = arrayOf(3, 4)
every { template.queryForList(sql, args, any<Class<Int>>()) } returns list
val args = arrayOf(3)
every { template.queryForList(sql, any<Class<Int>>(), args) } returns list
template.queryForList<Int>(sql, args)
verify { template.queryForList(sql, args, any<Class<Int>>()) }
verify { template.queryForList(sql, any<Class<Int>>(), args) }
}
@Test
@@ -94,7 +94,6 @@ public class KotlinSerializationJsonMessageConverter extends AbstractJsonMessage
* Tries to find a serializer that can marshall or unmarshall instances of the given type
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
* <p>Resolved serializers are cached and cached results are returned on successive calls.
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
* @param type the type to find a serializer for
* @return a resolved serializer for the given type
* @throws RuntimeException if no serializer supporting the given type can be found
@@ -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.
@@ -38,7 +38,6 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.DecodingException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@@ -233,7 +232,6 @@ public class PayloadMethodArgumentResolver implements HandlerMethodArgumentResol
if (decoder.canDecode(elementType, mimeType)) {
if (adapter != null && adapter.isMultiValue()) {
Flux<?> flux = content
.filter(this::nonEmptyDataBuffer)
.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
.onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
@@ -247,7 +245,6 @@ public class PayloadMethodArgumentResolver implements HandlerMethodArgumentResol
else {
// Single-value (with or without reactive type wrapper)
Mono<?> mono = content.next()
.filter(this::nonEmptyDataBuffer)
.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
.onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
@@ -265,14 +262,6 @@ public class PayloadMethodArgumentResolver implements HandlerMethodArgumentResol
message, parameter, "Cannot decode to [" + targetType + "]" + message));
}
private boolean nonEmptyDataBuffer(DataBuffer buffer) {
if (buffer.readableByteCount() > 0) {
return true;
}
DataBufferUtils.release(buffer);
return false;
}
private Throwable handleReadError(MethodParameter parameter, Message<?> message, Throwable ex) {
return ex instanceof DecodingException ?
new MethodArgumentResolutionException(message, parameter, "Failed to read HTTP message", ex) : ex;
@@ -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.
@@ -34,24 +34,10 @@ import org.springframework.util.ConcurrentReferenceHashMap;
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @since 4.0
*/
public abstract class AbstractExceptionHandlerMethodResolver {
private static final Method NO_MATCHING_EXCEPTION_HANDLER_METHOD;
static {
try {
NO_MATCHING_EXCEPTION_HANDLER_METHOD =
AbstractExceptionHandlerMethodResolver.class.getDeclaredMethod("noMatchingExceptionHandler");
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("Expected method not found: " + ex);
}
}
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentReferenceHashMap<>(16);
@@ -66,9 +52,9 @@ public abstract class AbstractExceptionHandlerMethodResolver {
}
/**
* Extract the exceptions this method handles. This implementation looks for
* Extract the exceptions this method handles.This implementation looks for
* sub-classes of Throwable in the method signature.
* <p>The method is static to ensure safe use from sub-class constructors.
* The method is static to ensure safe use from sub-class constructors.
*/
@SuppressWarnings("unchecked")
protected static List<Class<? extends Throwable>> getExceptionsFromMethodSignature(Method method) {
@@ -94,7 +80,7 @@ public abstract class AbstractExceptionHandlerMethodResolver {
/**
* Find a {@link Method} to handle the given exception.
* <p>Uses {@link ExceptionDepthComparator} if more than one match is found.
* Use {@link ExceptionDepthComparator} if more than one match is found.
* @param exception the exception
* @return a Method to handle the exception, or {@code null} if none found
*/
@@ -113,7 +99,6 @@ public abstract class AbstractExceptionHandlerMethodResolver {
/**
* Find a {@link Method} to handle the given exception type. This can be
* useful if an {@link Exception} instance is not available (e.g. for tools).
* <p>Uses {@link ExceptionDepthComparator} if more than one match is found.
* @param exceptionType the exception type
* @return a Method to handle the exception, or {@code null} if none found
* @since 4.3.1
@@ -125,12 +110,11 @@ public abstract class AbstractExceptionHandlerMethodResolver {
method = getMappedMethod(exceptionType);
this.exceptionLookupCache.put(exceptionType, method);
}
return (method != NO_MATCHING_EXCEPTION_HANDLER_METHOD ? method : null);
return method;
}
/**
* Return the {@link Method} mapped to the given exception type, or
* {@link #NO_MATCHING_EXCEPTION_HANDLER_METHOD} if none.
* Return the {@link Method} mapped to the given exception type, or {@code null} if none.
*/
@Nullable
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
@@ -141,21 +125,12 @@ public abstract class AbstractExceptionHandlerMethodResolver {
}
}
if (!matches.isEmpty()) {
if (matches.size() > 1) {
matches.sort(new ExceptionDepthComparator(exceptionType));
}
matches.sort(new ExceptionDepthComparator(exceptionType));
return this.mappedMethods.get(matches.get(0));
}
else {
return NO_MATCHING_EXCEPTION_HANDLER_METHOD;
return null;
}
}
/**
* For the {@link #NO_MATCHING_EXCEPTION_HANDLER_METHOD} constant.
*/
@SuppressWarnings("unused")
private void noMatchingExceptionHandler() {
}
}
@@ -31,8 +31,6 @@ import io.rsocket.Payload;
import io.rsocket.metadata.CompositeMetadata;
import io.rsocket.metadata.RoutingMetadata;
import io.rsocket.metadata.WellKnownMimeType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ResolvableType;
@@ -54,9 +52,6 @@ import org.springframework.util.MimeType;
*/
public class DefaultMetadataExtractor implements MetadataExtractor, MetadataExtractorRegistry {
private static final Log logger = LogFactory.getLog(DefaultMetadataExtractor.class);
private final List<Decoder<?>> decoders;
private final Map<String, EntryExtractor<?>> registrations = new HashMap<>();
@@ -124,10 +119,6 @@ public class DefaultMetadataExtractor implements MetadataExtractor, MetadataExtr
else {
extractEntry(payload.metadata().slice(), metadataMimeType.toString(), result);
}
if (logger.isDebugEnabled()) {
logger.debug("Values extracted from metadata: " + result +
" with registrations for " + this.registrations.keySet() + ".");
}
return result;
}
@@ -184,7 +175,7 @@ public class DefaultMetadataExtractor implements MetadataExtractor, MetadataExtr
@Override
public String toString() {
return "\"" + this.mimeType + "\" => " + this.targetType;
return "mimeType=" + this.mimeType + ", targetType=" + this.targetType;
}
}
@@ -71,18 +71,18 @@ import org.springframework.validation.Validator;
* Provides essential configuration for handling messages with simple messaging
* protocols such as STOMP.
*
* <p>{@link #clientInboundChannel(TaskExecutor)} and {@link #clientOutboundChannel(TaskExecutor)} deliver
* <p>{@link #clientInboundChannel()} and {@link #clientOutboundChannel()} deliver
* messages to and from remote clients to several message handlers such as the
* following.
* <ul>
* <li>{@link #simpAnnotationMethodMessageHandler(AbstractSubscribableChannel, AbstractSubscribableChannel, SimpMessagingTemplate, CompositeMessageConverter)}</li>
* <li>{@link #simpleBrokerMessageHandler(AbstractSubscribableChannel, AbstractSubscribableChannel, AbstractSubscribableChannel, UserDestinationResolver)}</li>
* <li>{@link #stompBrokerRelayMessageHandler(AbstractSubscribableChannel, AbstractSubscribableChannel, AbstractSubscribableChannel, UserDestinationMessageHandler, MessageHandler, UserDestinationResolver)}</li>
* <li>{@link #userDestinationMessageHandler(AbstractSubscribableChannel, AbstractSubscribableChannel, AbstractSubscribableChannel, UserDestinationResolver)}</li>
* <li>{@link #simpAnnotationMethodMessageHandler()}</li>
* <li>{@link #simpleBrokerMessageHandler()}</li>
* <li>{@link #stompBrokerRelayMessageHandler()}</li>
* <li>{@link #userDestinationMessageHandler()}</li>
* </ul>
*
* <p>{@link #brokerChannel(AbstractSubscribableChannel, AbstractSubscribableChannel, TaskExecutor)} delivers messages from within the application to the
* the respective message handlers. {@link #brokerMessagingTemplate(AbstractSubscribableChannel, AbstractSubscribableChannel, AbstractSubscribableChannel, CompositeMessageConverter)} can be injected
* <p>{@link #brokerChannel()} delivers messages from within the application to the
* the respective message handlers. {@link #brokerMessagingTemplate()} can be injected
* into any application component to send messages.
*
* <p>Subclasses are responsible for the parts of the configuration that feed messages
@@ -90,7 +90,6 @@ import org.springframework.validation.Validator;
*
* @author Rossen Stoyanchev
* @author Brian Clozel
* @author Sebastien Deleuze
* @since 4.0
*/
public abstract class AbstractMessageBrokerConfiguration implements ApplicationContextAware {
@@ -148,8 +147,8 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
@Bean
public AbstractSubscribableChannel clientInboundChannel(TaskExecutor clientInboundChannelExecutor) {
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(clientInboundChannelExecutor);
public AbstractSubscribableChannel clientInboundChannel() {
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(clientInboundChannelExecutor());
channel.setLogger(SimpLogging.forLog(channel.getLogger()));
ChannelRegistration reg = getClientInboundChannelRegistration();
if (reg.hasInterceptors()) {
@@ -184,8 +183,8 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
}
@Bean
public AbstractSubscribableChannel clientOutboundChannel(TaskExecutor clientOutboundChannelExecutor) {
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(clientOutboundChannelExecutor);
public AbstractSubscribableChannel clientOutboundChannel() {
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(clientOutboundChannelExecutor());
channel.setLogger(SimpLogging.forLog(channel.getLogger()));
ChannelRegistration reg = getClientOutboundChannelRegistration();
if (reg.hasInterceptors()) {
@@ -220,11 +219,10 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
}
@Bean
public AbstractSubscribableChannel brokerChannel(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, TaskExecutor brokerChannelExecutor) {
ChannelRegistration reg = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getBrokerChannelRegistration();
public AbstractSubscribableChannel brokerChannel() {
ChannelRegistration reg = getBrokerRegistry().getBrokerChannelRegistration();
ExecutorSubscribableChannel channel = (reg.hasTaskExecutor() ?
new ExecutorSubscribableChannel(brokerChannelExecutor) : new ExecutorSubscribableChannel());
new ExecutorSubscribableChannel(brokerChannelExecutor()) : new ExecutorSubscribableChannel());
reg.interceptors(new ImmutableMessageChannelInterceptor());
channel.setLogger(SimpLogging.forLog(channel.getLogger()));
channel.setInterceptors(reg.getInterceptors());
@@ -232,9 +230,8 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
}
@Bean
public TaskExecutor brokerChannelExecutor(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel) {
ChannelRegistration reg = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getBrokerChannelRegistration();
public TaskExecutor brokerChannelExecutor() {
ChannelRegistration reg = getBrokerRegistry().getBrokerChannelRegistration();
ThreadPoolTaskExecutor executor;
if (reg.hasTaskExecutor()) {
executor = reg.taskExecutor().getTaskExecutor();
@@ -254,10 +251,9 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
* An accessor for the {@link MessageBrokerRegistry} that ensures its one-time creation
* and initialization through {@link #configureMessageBroker(MessageBrokerRegistry)}.
*/
protected final MessageBrokerRegistry getBrokerRegistry(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel) {
protected final MessageBrokerRegistry getBrokerRegistry() {
if (this.brokerRegistry == null) {
MessageBrokerRegistry registry = new MessageBrokerRegistry(clientInboundChannel, clientOutboundChannel);
MessageBrokerRegistry registry = new MessageBrokerRegistry(clientInboundChannel(), clientOutboundChannel());
configureMessageBroker(registry);
this.brokerRegistry = registry;
}
@@ -276,20 +272,15 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
* configuration classes.
*/
@Nullable
public final PathMatcher getPathMatcher(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel) {
return getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getPathMatcher();
public final PathMatcher getPathMatcher() {
return getBrokerRegistry().getPathMatcher();
}
@Bean
public SimpAnnotationMethodMessageHandler simpAnnotationMethodMessageHandler(
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel,
SimpMessagingTemplate brokerMessagingTemplate, CompositeMessageConverter brokerMessageConverter) {
SimpAnnotationMethodMessageHandler handler = createAnnotationMethodMessageHandler(clientInboundChannel,
clientOutboundChannel, brokerMessagingTemplate);
MessageBrokerRegistry brokerRegistry = getBrokerRegistry(clientInboundChannel, clientOutboundChannel);
handler.setDestinationPrefixes(brokerRegistry.getApplicationDestinationPrefixes());
handler.setMessageConverter(brokerMessageConverter);
public SimpAnnotationMethodMessageHandler simpAnnotationMethodMessageHandler() {
SimpAnnotationMethodMessageHandler handler = createAnnotationMethodMessageHandler();
handler.setDestinationPrefixes(getBrokerRegistry().getApplicationDestinationPrefixes());
handler.setMessageConverter(brokerMessageConverter());
handler.setValidator(simpValidator());
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>();
@@ -300,7 +291,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
addReturnValueHandlers(returnValueHandlers);
handler.setCustomReturnValueHandlers(returnValueHandlers);
PathMatcher pathMatcher = brokerRegistry.getPathMatcher();
PathMatcher pathMatcher = getBrokerRegistry().getPathMatcher();
if (pathMatcher != null) {
handler.setPathMatcher(pathMatcher);
}
@@ -311,12 +302,11 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
* Protected method for plugging in a custom subclass of
* {@link org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler
* SimpAnnotationMethodMessageHandler}.
* @since 5.3.2
* @since 4.2
*/
protected SimpAnnotationMethodMessageHandler createAnnotationMethodMessageHandler(
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel,
SimpMessagingTemplate brokerMessagingTemplate) {
return new SimpAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate);
protected SimpAnnotationMethodMessageHandler createAnnotationMethodMessageHandler() {
return new SimpAnnotationMethodMessageHandler(clientInboundChannel(),
clientOutboundChannel(), brokerMessagingTemplate());
}
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
@@ -327,56 +317,48 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
@Bean
@Nullable
public AbstractBrokerMessageHandler simpleBrokerMessageHandler(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, AbstractSubscribableChannel brokerChannel,
UserDestinationResolver userDestinationResolver) {
SimpleBrokerMessageHandler handler = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getSimpleBroker(brokerChannel);
public AbstractBrokerMessageHandler simpleBrokerMessageHandler() {
SimpleBrokerMessageHandler handler = getBrokerRegistry().getSimpleBroker(brokerChannel());
if (handler == null) {
return null;
}
updateUserDestinationResolver(handler, userDestinationResolver);
updateUserDestinationResolver(handler);
return handler;
}
private void updateUserDestinationResolver(AbstractBrokerMessageHandler handler, UserDestinationResolver userDestinationResolver) {
private void updateUserDestinationResolver(AbstractBrokerMessageHandler handler) {
Collection<String> prefixes = handler.getDestinationPrefixes();
if (!prefixes.isEmpty() && !prefixes.iterator().next().startsWith("/")) {
((DefaultUserDestinationResolver) userDestinationResolver).setRemoveLeadingSlash(true);
((DefaultUserDestinationResolver) userDestinationResolver()).setRemoveLeadingSlash(true);
}
}
@Bean
@Nullable
public AbstractBrokerMessageHandler stompBrokerRelayMessageHandler(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, AbstractSubscribableChannel brokerChannel,
UserDestinationMessageHandler userDestinationMessageHandler, @Nullable MessageHandler userRegistryMessageHandler,
UserDestinationResolver userDestinationResolver) {
MessageBrokerRegistry brokerRegistry = getBrokerRegistry(clientInboundChannel, clientOutboundChannel);
StompBrokerRelayMessageHandler handler = brokerRegistry.getStompBrokerRelay(brokerChannel);
public AbstractBrokerMessageHandler stompBrokerRelayMessageHandler() {
StompBrokerRelayMessageHandler handler = getBrokerRegistry().getStompBrokerRelay(brokerChannel());
if (handler == null) {
return null;
}
Map<String, MessageHandler> subscriptions = new HashMap<>(4);
String destination = brokerRegistry.getUserDestinationBroadcast();
String destination = getBrokerRegistry().getUserDestinationBroadcast();
if (destination != null) {
subscriptions.put(destination, userDestinationMessageHandler);
subscriptions.put(destination, userDestinationMessageHandler());
}
destination = brokerRegistry.getUserRegistryBroadcast();
destination = getBrokerRegistry().getUserRegistryBroadcast();
if (destination != null) {
subscriptions.put(destination, userRegistryMessageHandler);
subscriptions.put(destination, userRegistryMessageHandler());
}
handler.setSystemSubscriptions(subscriptions);
updateUserDestinationResolver(handler, userDestinationResolver);
updateUserDestinationResolver(handler);
return handler;
}
@Bean
public UserDestinationMessageHandler userDestinationMessageHandler(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, AbstractSubscribableChannel brokerChannel,
UserDestinationResolver userDestinationResolver) {
UserDestinationMessageHandler handler = new UserDestinationMessageHandler(clientInboundChannel,
brokerChannel, userDestinationResolver);
String destination = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getUserDestinationBroadcast();
public UserDestinationMessageHandler userDestinationMessageHandler() {
UserDestinationMessageHandler handler = new UserDestinationMessageHandler(clientInboundChannel(),
brokerChannel(), userDestinationResolver());
String destination = getBrokerRegistry().getUserDestinationBroadcast();
if (destination != null) {
handler.setBroadcastDestination(destination);
}
@@ -385,17 +367,15 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
@Bean
@Nullable
public MessageHandler userRegistryMessageHandler(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, SimpUserRegistry userRegistry,
SimpMessagingTemplate brokerMessagingTemplate, TaskScheduler messageBrokerTaskScheduler) {
MessageBrokerRegistry brokerRegistry = getBrokerRegistry(clientInboundChannel, clientOutboundChannel);
if (brokerRegistry.getUserRegistryBroadcast() == null) {
public MessageHandler userRegistryMessageHandler() {
if (getBrokerRegistry().getUserRegistryBroadcast() == null) {
return null;
}
SimpUserRegistry userRegistry = userRegistry();
Assert.isInstanceOf(MultiServerUserRegistry.class, userRegistry, "MultiServerUserRegistry required");
return new UserRegistryMessageHandler((MultiServerUserRegistry) userRegistry,
brokerMessagingTemplate, brokerRegistry.getUserRegistryBroadcast(),
messageBrokerTaskScheduler);
brokerMessagingTemplate(), getBrokerRegistry().getUserRegistryBroadcast(),
messageBrokerTaskScheduler());
}
// Expose alias for 4.1 compatibility
@@ -409,15 +389,13 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
}
@Bean
public SimpMessagingTemplate brokerMessagingTemplate(AbstractSubscribableChannel brokerChannel,
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel,
CompositeMessageConverter brokerMessageConverter) {
SimpMessagingTemplate template = new SimpMessagingTemplate(brokerChannel);
String prefix = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getUserDestinationPrefix();
public SimpMessagingTemplate brokerMessagingTemplate() {
SimpMessagingTemplate template = new SimpMessagingTemplate(brokerChannel());
String prefix = getBrokerRegistry().getUserDestinationPrefix();
if (prefix != null) {
template.setUserDestinationPrefix(prefix);
}
template.setMessageConverter(brokerMessageConverter);
template.setMessageConverter(brokerMessageConverter());
return template;
}
@@ -463,10 +441,9 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
}
@Bean
public UserDestinationResolver userDestinationResolver(SimpUserRegistry userRegistry,
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel) {
DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry);
String prefix = getBrokerRegistry(clientInboundChannel, clientOutboundChannel).getUserDestinationPrefix();
public UserDestinationResolver userDestinationResolver() {
DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry());
String prefix = getBrokerRegistry().getUserDestinationPrefix();
if (prefix != null) {
resolver.setUserDestinationPrefix(prefix);
}
@@ -475,14 +452,12 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
@Bean
@SuppressWarnings("deprecation")
public SimpUserRegistry userRegistry(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel) {
public SimpUserRegistry userRegistry() {
SimpUserRegistry registry = createLocalUserRegistry();
MessageBrokerRegistry brokerRegistry = getBrokerRegistry(clientInboundChannel, clientOutboundChannel);
if (registry == null) {
registry = createLocalUserRegistry(brokerRegistry.getUserRegistryOrder());
registry = createLocalUserRegistry(getBrokerRegistry().getUserRegistryOrder());
}
boolean broadcast = brokerRegistry.getUserRegistryBroadcast() != null;
boolean broadcast = getBrokerRegistry().getUserRegistryBroadcast() != null;
return (broadcast ? new MultiServerUserRegistry(registry) : registry);
}
@@ -378,14 +378,13 @@ public class MessageHeaderAccessor {
* {@link #copyHeadersIfAbsent(Map)} to avoid overwriting values.
*/
public void copyHeaders(@Nullable Map<String, ?> headersToCopy) {
if (headersToCopy == null || this.headers == headersToCopy) {
return;
if (headersToCopy != null) {
headersToCopy.forEach((key, value) -> {
if (!isReadOnly(key)) {
setHeader(key, value);
}
});
}
headersToCopy.forEach((key, value) -> {
if (!isReadOnly(key)) {
setHeader(key, value);
}
});
}
/**
@@ -393,14 +392,13 @@ public class MessageHeaderAccessor {
* <p>This operation will <em>not</em> overwrite any existing values.
*/
public void copyHeadersIfAbsent(@Nullable Map<String, ?> headersToCopy) {
if (headersToCopy == null || this.headers == headersToCopy) {
return;
if (headersToCopy != null) {
headersToCopy.forEach((key, value) -> {
if (!isReadOnly(key)) {
setHeaderIfAbsent(key, value);
}
});
}
headersToCopy.forEach((key, value) -> {
if (!isReadOnly(key)) {
setHeaderIfAbsent(key, value);
}
});
}
protected boolean isReadOnly(String headerName) {
@@ -75,8 +75,6 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
@SuppressWarnings("unchecked")
Map<String, List<String>> map = (Map<String, List<String>>) getHeader(NATIVE_HEADERS);
if (map != null) {
// setHeader checks for equality but we need copy of native headers
setHeader(NATIVE_HEADERS, null);
setHeader(NATIVE_HEADERS, new LinkedMultiValueMap<>(map));
}
}
@@ -105,8 +103,6 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
if (isMutable()) {
Map<String, List<String>> map = getNativeHeaders();
if (map != null) {
// setHeader checks for equality but we need immutable wrapper
setHeader(NATIVE_HEADERS, null);
setHeader(NATIVE_HEADERS, Collections.unmodifiableMap(map));
}
super.setImmutable();
@@ -114,34 +110,31 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
}
@Override
public void copyHeaders(@Nullable Map<String, ?> headersToCopy) {
if (headersToCopy == null) {
return;
public void setHeader(String name, @Nullable Object value) {
if (name.equalsIgnoreCase(NATIVE_HEADERS)) {
// Force removal since setHeader checks for equality
super.setHeader(NATIVE_HEADERS, null);
}
@SuppressWarnings("unchecked")
Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS);
if (map != null && map != getNativeHeaders()) {
map.forEach(this::setNativeHeaderValues);
}
// setHeader checks for equality, native headers should be equal by now
super.copyHeaders(headersToCopy);
super.setHeader(name, value);
}
@Override
public void copyHeadersIfAbsent(@Nullable Map<String, ?> headersToCopy) {
if (headersToCopy == null) {
return;
@SuppressWarnings("unchecked")
public void copyHeaders(@Nullable Map<String, ?> headersToCopy) {
if (headersToCopy != null) {
Map<String, List<String>> nativeHeaders = getNativeHeaders();
Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS);
if (map != null) {
if (nativeHeaders != null) {
nativeHeaders.putAll(map);
}
else {
nativeHeaders = new LinkedMultiValueMap<>(map);
}
}
super.copyHeaders(headersToCopy);
setHeader(NATIVE_HEADERS, nativeHeaders);
}
@SuppressWarnings("unchecked")
Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS);
if (map != null && getNativeHeaders() == null) {
map.forEach(this::setNativeHeaderValues);
}
super.copyHeadersIfAbsent(headersToCopy);
}
/**
@@ -208,30 +201,6 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
}
}
/**
* Variant of {@link #addNativeHeader(String, String)} for all values.
* @since 5.2.12
*/
public void setNativeHeaderValues(String name, @Nullable List<String> values) {
Assert.state(isMutable(), "Already immutable");
Map<String, List<String>> map = getNativeHeaders();
if (values == null) {
if (map != null && map.get(name) != null) {
setModified(true);
map.remove(name);
}
return;
}
if (map == null) {
map = new LinkedMultiValueMap<>(3);
setHeader(NATIVE_HEADERS, map);
}
if (!ObjectUtils.nullSafeEquals(values, getHeader(name))) {
setModified(true);
map.put(name, new ArrayList<>(values));
}
}
/**
* Add the specified native header value to existing values.
* <p>In order for this to work, the accessor must be {@link #isMutable()
@@ -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,6 +19,7 @@ package org.springframework.messaging.rsocket;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
import io.rsocket.Payload;
import io.rsocket.RSocket;
import io.rsocket.SocketAcceptor;
import io.rsocket.core.RSocketServer;
@@ -42,7 +43,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.rsocket.annotation.ConnectMapping;
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
import org.springframework.stereotype.Controller;
@@ -164,12 +164,6 @@ public class RSocketClientToServerIntegrationTests {
.verify(Duration.ofSeconds(5));
}
@Test // gh-26344
public void echoChannelWithEmptyInput() {
Flux<String> result = requester.route("echo-channel-empty").data(Flux.empty()).retrieveFlux(String.class);
StepVerifier.create(result).verifyComplete();
}
@Test
public void metadataPush() {
Flux.just("bar", "baz")
@@ -260,11 +254,6 @@ public class RSocketClientToServerIntegrationTests {
return payloads.delayElements(Duration.ofMillis(10)).map(payload -> payload + " async");
}
@MessageMapping("echo-channel-empty")
Flux<String> echoChannelEmpty(@Payload(required = false) Flux<String> payloads) {
return payloads.map(payload -> payload + " echoed");
}
@MessageMapping("thrown-exception")
Mono<String> handleAndThrow(String payload) {
throw new IllegalArgumentException("Invalid input error");
@@ -349,29 +338,29 @@ public class RSocketClientToServerIntegrationTests {
}
@Override
public Mono<Void> fireAndForget(io.rsocket.Payload payload) {
public Mono<Void> fireAndForget(Payload payload) {
return this.delegate.fireAndForget(payload)
.doOnSuccess(aVoid -> this.fireAndForgetCount.incrementAndGet());
}
@Override
public Mono<Void> metadataPush(io.rsocket.Payload payload) {
public Mono<Void> metadataPush(Payload payload) {
return this.delegate.metadataPush(payload)
.doOnSuccess(aVoid -> this.metadataPushCount.incrementAndGet());
}
@Override
public Mono<io.rsocket.Payload> requestResponse(io.rsocket.Payload payload) {
public Mono<Payload> requestResponse(Payload payload) {
return this.delegate.requestResponse(payload);
}
@Override
public Flux<io.rsocket.Payload> requestStream(io.rsocket.Payload payload) {
public Flux<Payload> requestStream(Payload payload) {
return this.delegate.requestStream(payload);
}
@Override
public Flux<io.rsocket.Payload> requestChannel(Publisher<io.rsocket.Payload> payloads) {
public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
return this.delegate.requestChannel(payloads);
}
}
@@ -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.
@@ -30,7 +30,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.task.TaskExecutor;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@@ -595,20 +594,19 @@ public class MessageBrokerConfigurationTests {
@Override
@Bean
public AbstractSubscribableChannel clientInboundChannel(TaskExecutor clientInboundChannelExecutor) {
public AbstractSubscribableChannel clientInboundChannel() {
return new TestChannel();
}
@Override
@Bean
public AbstractSubscribableChannel clientOutboundChannel(TaskExecutor clientOutboundChannelExecutor) {
public AbstractSubscribableChannel clientOutboundChannel() {
return new TestChannel();
}
@Override
@Bean
public AbstractSubscribableChannel brokerChannel(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, TaskExecutor brokerChannelExecutor) {
public AbstractSubscribableChannel brokerChannel() {
return new TestChannel();
}
}
@@ -682,21 +680,20 @@ public class MessageBrokerConfigurationTests {
@Override
@Bean
public AbstractSubscribableChannel clientInboundChannel(TaskExecutor clientInboundChannelExecutor) {
public AbstractSubscribableChannel clientInboundChannel() {
// synchronous
return new ExecutorSubscribableChannel(null);
}
@Override
@Bean
public AbstractSubscribableChannel clientOutboundChannel(TaskExecutor clientOutboundChannelExecutor) {
public AbstractSubscribableChannel clientOutboundChannel() {
return new TestChannel();
}
@Override
@Bean
public AbstractSubscribableChannel brokerChannel(AbstractSubscribableChannel clientInboundChannel,
AbstractSubscribableChannel clientOutboundChannel, TaskExecutor brokerChannelExecutor) {
public AbstractSubscribableChannel brokerChannel() {
// synchronous
return new ExecutorSubscribableChannel(null);
}
@@ -226,46 +226,19 @@ public class NativeMessageHeaderAccessorTests {
@Test // gh-25821
void copyImmutableToMutable() {
NativeMessageHeaderAccessor sourceAccessor = new NativeMessageHeaderAccessor();
sourceAccessor.addNativeHeader("foo", "bar");
Message<String> source = MessageBuilder.createMessage("payload", sourceAccessor.getMessageHeaders());
NativeMessageHeaderAccessor source = new NativeMessageHeaderAccessor();
source.addNativeHeader("foo", "bar");
Message<String> message = MessageBuilder.createMessage("payload", source.getMessageHeaders());
NativeMessageHeaderAccessor targetAccessor = new NativeMessageHeaderAccessor();
targetAccessor.copyHeaders(source.getHeaders());
targetAccessor.setLeaveMutable(true);
Message<?> target = MessageBuilder.createMessage(source.getPayload(), targetAccessor.getMessageHeaders());
NativeMessageHeaderAccessor target = new NativeMessageHeaderAccessor();
target.copyHeaders(message.getHeaders());
target.setLeaveMutable(true);
message = MessageBuilder.createMessage(message.getPayload(), target.getMessageHeaders());
MessageHeaderAccessor accessor = MessageHeaderAccessor.getMutableAccessor(target);
MessageHeaderAccessor accessor = MessageHeaderAccessor.getMutableAccessor(message);
assertThat(accessor.isMutable());
((NativeMessageHeaderAccessor) accessor).addNativeHeader("foo", "baz");
assertThat(((NativeMessageHeaderAccessor) accessor).getNativeHeader("foo")).containsExactly("bar", "baz");
}
@Test // gh-25821
void copyIfAbsentImmutableToMutable() {
NativeMessageHeaderAccessor sourceAccessor = new NativeMessageHeaderAccessor();
sourceAccessor.addNativeHeader("foo", "bar");
Message<String> source = MessageBuilder.createMessage("payload", sourceAccessor.getMessageHeaders());
MessageHeaderAccessor targetAccessor = new NativeMessageHeaderAccessor();
targetAccessor.copyHeadersIfAbsent(source.getHeaders());
targetAccessor.setLeaveMutable(true);
Message<?> target = MessageBuilder.createMessage(source.getPayload(), targetAccessor.getMessageHeaders());
MessageHeaderAccessor accessor = MessageHeaderAccessor.getMutableAccessor(target);
assertThat(accessor.isMutable());
((NativeMessageHeaderAccessor) accessor).addNativeHeader("foo", "baz");
assertThat(((NativeMessageHeaderAccessor) accessor).getNativeHeader("foo")).containsExactly("bar", "baz");
}
@Test // gh-26155
void copySelf() {
NativeMessageHeaderAccessor accessor = new NativeMessageHeaderAccessor();
accessor.addNativeHeader("foo", "bar");
accessor.setHeader("otherHeader", "otherHeaderValue");
accessor.setLeaveMutable(true);
// Does not fail with ConcurrentModificationException
accessor.copyHeaders(accessor.getMessageHeaders());
}
}
@@ -418,13 +418,10 @@ public abstract class AbstractEntityManagerFactoryBean implements
String message = ex.getMessage();
String causeString = cause.toString();
if (!message.endsWith(causeString)) {
ex = new PersistenceException(message + "; nested exception is " + causeString, cause);
throw new PersistenceException(message + "; nested exception is " + causeString, cause);
}
}
}
if (logger.isErrorEnabled()) {
logger.error("Failed to initialize JPA EntityManagerFactory: " + ex.getMessage());
}
throw ex;
}
@@ -48,9 +48,9 @@ import org.springframework.lang.Nullable;
* EntityManager. Developed and tested against Hibernate 5.3 and 5.4;
* backwards-compatible with Hibernate 5.2 at runtime on a best-effort basis.
*
* <p>Exposes Hibernate's persistence provider and Hibernate's Session as extended
* EntityManager interface, and adapts {@link AbstractJpaVendorAdapter}'s common
* configuration settings. Also supports the detection of annotated packages (through
* <p>Exposes Hibernate's persistence provider and EntityManager extension interface,
* and adapts {@link AbstractJpaVendorAdapter}'s common configuration settings.
* Also supports the detection of annotated packages (through
* {@link org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo#getManagedPackages()}),
* e.g. containing Hibernate {@link org.hibernate.annotations.FilterDef} annotations,
* along with Spring-driven entity scanning which requires no {@code persistence.xml}
@@ -82,8 +82,8 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
public HibernateJpaVendorAdapter() {
this.persistenceProvider = new SpringHibernateJpaPersistenceProvider();
this.entityManagerFactoryInterface = SessionFactory.class; // as of Spring 5.3
this.entityManagerInterface = Session.class; // as of Spring 5.3
this.entityManagerFactoryInterface = SessionFactory.class;
this.entityManagerInterface = Session.class;
}
@@ -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.
@@ -21,7 +21,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
@@ -43,10 +42,10 @@ public class MockMultipartFile implements MultipartFile {
private final String name;
private final String originalFilename;
private String originalFilename;
@Nullable
private final String contentType;
private String contentType;
private final byte[] content;
@@ -80,7 +79,7 @@ public class MockMultipartFile implements MultipartFile {
public MockMultipartFile(
String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
Assert.hasLength(name, "Name must not be empty");
Assert.hasLength(name, "Name must not be null");
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
this.contentType = contentType;
@@ -109,7 +108,6 @@ public class MockMultipartFile implements MultipartFile {
}
@Override
@NonNull
public String getOriginalFilename() {
return this.originalFilename;
}

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