Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Builds 23bb745ea4 Release v5.3.13 2021-11-11 07:31:25 +00:00
560 changed files with 5785 additions and 9449 deletions
-3
View File
@@ -1,3 +0,0 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.322-librca
+58 -63
View File
@@ -2,9 +2,9 @@ plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.10'
id "io.freefair.aspectj" version '6.2.0' apply false
id 'org.jetbrains.dokka' version '1.6.10' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.32' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.32" apply false
id 'org.jetbrains.dokka' version '1.5.0' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.31' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.31" apply false
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id "org.unbroken-dome.xjc" version '2.0.0' apply false
@@ -27,25 +27,25 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
mavenBom "io.netty:netty-bom:4.1.75.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5"
mavenBom "io.netty:netty-bom:4.1.70.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.13"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.31"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
mavenBom "org.junit:junit-bom:5.8.2"
mavenBom "org.junit:junit-bom:5.8.1"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
entry 'log4j-slf4j-impl'
}
dependency "org.slf4j:slf4j-api:1.7.36"
dependency "org.slf4j:slf4j-api:1.7.32"
dependency("com.google.code.findbugs:findbugs:3.0.1") {
exclude group: "dom4j", name: "dom4j"
}
@@ -67,23 +67,23 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
dependency "io.smallrye.reactive:mutiny:1.4.0"
dependency "io.reactivex.rxjava3:rxjava:3.1.1"
dependency "io.smallrye.reactive:mutiny:1.1.1"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.1"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.8") {
dependency "com.fasterxml:aalto-xml:1.3.0"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") {
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.9"
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
dependency "com.google.code.gson:gson:2.8.8"
dependency "com.google.protobuf:protobuf-java-util:3.18.0"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.14"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -92,12 +92,12 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.30"
dependency "org.yaml:snakeyaml:1.29"
dependency "com.h2database:h2:2.1.210"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.2"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.rometools:rome:1.18.0"
dependency "com.rometools:rome:1.16.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.4"
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
@@ -123,48 +123,48 @@ 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.33.Final"
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
dependency "org.hibernate:hibernate-core:5.4.32.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.54') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
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.60') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.54') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
dependencySet(group: 'io.undertow', version: '2.2.12.Final') {
entry 'undertow-core'
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
}
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.5") {
exclude group: "commons-logging", name: "commons-logging"
}
dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') {
entry 'okhttp'
entry 'mockwebserver'
}
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
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.1'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.9"
dependency "org.jruby:jruby:9.2.20.1"
dependency "org.jruby:jruby:9.2.19.0"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
@@ -191,25 +191,25 @@ configure(allprojects) { project ->
dependency "org.junit.support:testng-engine:1.0.1"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.22.0"
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
dependency "org.assertj:assertj-core:3.21.0"
dependencySet(group: 'org.xmlunit', version: '2.8.3') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '4.4.0') {
dependencySet(group: 'org.mockito', version: '4.0.0') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.12.1"
dependency "io.mockk:mockk:1.12.0"
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.54.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.54.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -237,8 +237,8 @@ configure(allprojects) { project ->
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.13"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10"
dependency "joda-time:joda-time:2.10.10"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "9.3"
toolVersion = "9.0"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -353,16 +353,16 @@ configure([rootProject] + javaProjects) { project ->
testImplementation("io.mockk:mockk")
testImplementation("org.assertj:assertj-core")
// Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs.
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
// JSR-305 only used for non-required meta-annotations
compileOnly("com.google.code.findbugs:jsr305")
testCompileOnly("com.google.code.findbugs:jsr305")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.29")
}
ext.javadocLinks = [
@@ -383,18 +383,12 @@ configure([rootProject] + javaProjects) { project ->
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
// Disabling linking to JUnit 5.8.2, since the `package-list` file no longer exists due to
// Disabling linking to JUnit 5.8.1, since the `package-list` file no longer exists due to
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
// "https://junit.org/junit5/docs/5.8.2/api/",
// "https://junit.org/junit5/docs/5.8.1/api/",
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
"https://r2dbc.io/spec/0.8.5.RELEASE/api/",
// The external Javadoc link for JSR 305 must come last to ensure that types from
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
// in a split package, and the javadoc tool does not support split packages
// across multiple external Javadoc sites.
"https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/"
"https://r2dbc.io/spec/0.8.5.RELEASE/api/"
] as String[]
}
@@ -405,6 +399,7 @@ configure(moduleProjects) { project ->
configure(rootProject) {
description = "Spring Framework"
apply plugin: "groovy"
apply plugin: "kotlin"
apply plugin: "io.spring.nohttp"
apply plugin: 'org.springframework.build.api-diff'
+2 -2
View File
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20220302
FROM ubuntu:focal-20210827
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
@@ -6,6 +6,6 @@ RUN ./setup.sh java8
ENV JAVA_HOME /opt/openjdk/java8
ENV JDK11 /opt/openjdk/java11
ENV JDK17 /opt/openjdk/java17
ENV JDK16 /opt/openjdk/java16
ENV PATH $JAVA_HOME/bin:$PATH
+4 -7
View File
@@ -3,16 +3,13 @@ set -e
case "$1" in
java8)
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u302-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u302b08.tar.gz"
;;
java11)
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.12%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz"
;;
java17)
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
;;
java18)
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
java16)
echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz"
;;
*)
echo $"Unknown java version"
+1 -1
View File
@@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java11 java17
for jdk in java8 java11 java16
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
+3
View File
@@ -1,3 +1,6 @@
email-server: "smtp.svc.pivotal.io"
email-from: "ci@spring.io"
email-to: ["spring-framework-dev@pivotal.io"]
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
docker-hub-organization: "springci"
+7 -7
View File
@@ -124,14 +124,14 @@ resources:
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk11-build
- name: repo-status-jdk17-build
- name: repo-status-jdk16-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk17-build
context: jdk16-build
- name: slack-alert
type: slack-notification
icon: slack
@@ -249,7 +249,7 @@ jobs:
<<: *slack-fail-params
- put: repo-status-jdk11-build
params: { state: "success", commit: "git-repo" }
- name: jdk17-build
- name: jdk16-build
serial: true
public: true
plan:
@@ -257,7 +257,7 @@ jobs:
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk17-build
- put: repo-status-jdk16-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
@@ -270,12 +270,12 @@ jobs:
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk17-build
- put: repo-status-jdk16-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk17-build
- put: repo-status-jdk16-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
@@ -458,7 +458,7 @@ jobs:
groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk17-build"]
jobs: ["build", "jdk11-build", "jdk16-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.17
version=5.3.13
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
@@ -306,26 +307,29 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
GenericWebApplicationContext context = new GenericWebApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.setScopeMetadataResolver(definition -> {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
scanner.setScopeMetadataResolver(new ScopeMetadataResolver() {
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
}
}
return metadata;
}
return metadata;
});
// Scan twice in order to find errors in the bean definition compatibility check.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
MyRepository repository = ctx.getBean(MyRepository.class);
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
assertThat(AopUtils.isCglibProxy(repository)).isTrue();
assertThat(AopUtils.isCglibProxy(repository)).isEqualTo(true);
assertThat(repository.getInvocationCount()).isGreaterThan(0);
assertThat(txManager.commits).isGreaterThan(0);
}
+3 -4
View File
@@ -1,14 +1,13 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
maven { url "https://repo.spring.io/release" }
maven { url "https://repo.spring.io/plugins-release" }
}
}
plugins {
id "com.gradle.enterprise" version "3.8.1"
id "io.spring.ge.conventions" version "0.0.9"
id "com.gradle.enterprise" version "3.6.1"
id "io.spring.ge.conventions" version "0.0.7"
}
include "spring-aop"
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,6 @@ import org.springframework.util.ReflectionUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @see org.springframework.aop.support.AopUtils
*/
public abstract class AopProxyUtils {
@@ -134,7 +133,7 @@ public abstract class AopProxyUtils {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
@@ -245,18 +244,4 @@ public abstract class AopProxyUtils {
return arguments;
}
/**
* Determine if the supplied {@link Class} is a JVM-generated implementation
* class for a lambda expression or method reference.
* <p>This method makes a best-effort attempt at determining this, based on
* checks that work on modern, main stream JVMs.
* @param clazz the class to check
* @return {@code true} if the class is a lambda implementation class
* @since 5.3.16
*/
static boolean isLambda(Class<?> clazz) {
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,16 +40,14 @@ import org.springframework.core.NativeDetector;
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @author Sam Brannen
* @since 12.03.2004
* @see AdvisedSupport#setOptimize
* @see AdvisedSupport#setProxyTargetClass
* @see AdvisedSupport#setInterfaces
*/
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
private static final long serialVersionUID = 7930414337282325166L;
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
@@ -60,7 +58,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
@@ -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.
@@ -421,7 +421,11 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
* are unaffected by such changes.
*/
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
@@ -460,9 +464,9 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
addAdvisorOnChainCreation(advice);
}
}
this.advisorChainInitialized = true;
}
this.advisorChainInitialized = true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@ import org.springframework.aop.Advisor;
import org.springframework.aop.ThrowsAdvice;
/**
* Adapter to enable {@link org.springframework.aop.ThrowsAdvice} to be used
* in the Spring AOP framework.
* Adapter to enable {@link org.springframework.aop.MethodBeforeAdvice}
* to be used in the Spring AOP framework.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -233,8 +233,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean. " +
"Continuing search for an Executor bean named 'taskExecutor'", ex);
logger.debug("Could not find unique TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
@@ -247,8 +246,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
}
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean. " +
"Continuing search for an Executor bean named 'taskExecutor'", ex);
logger.debug("Could not find default TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perTargetAspect() throws Exception {
void perTargetAspect() throws SecurityException, NoSuchMethodException {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -130,7 +130,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void multiplePerTargetAspects() throws Exception {
void multiplePerTargetAspects() throws SecurityException, NoSuchMethodException {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -158,7 +158,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void multiplePerTargetAspectsWithOrderAnnotation() throws Exception {
void multiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoSuchMethodException {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -184,7 +184,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perThisAspect() throws Exception {
void perThisAspect() throws SecurityException, NoSuchMethodException {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -220,7 +220,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perTypeWithinAspect() throws Exception {
void perTypeWithinAspect() throws SecurityException, NoSuchMethodException {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -322,7 +322,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
int b = 12;
int c = 25;
String d = "d";
StringBuilder e = new StringBuilder("stringbuf");
StringBuffer e = new StringBuffer("stringbuf");
String expectedResult = a + b+ c + d + e;
assertThat(mva.mungeArgs(a, b, c, d, e)).isEqualTo(expectedResult);
}
@@ -728,12 +728,12 @@ abstract class AbstractAspectJAdvisorFactoryTests {
@Aspect
static class ManyValuedArgs {
String mungeArgs(String a, int b, int c, String d, StringBuilder e) {
String mungeArgs(String a, int b, int c, String d, StringBuffer e) {
return a + b + c + d + e;
}
@Around(value="execution(String mungeArgs(..)) && args(a, b, c, d, e)", argNames="b,c,d,e,a")
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuilder e, String a) throws Throwable {
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuffer e, String a) throws Throwable {
assertThat(pjp.proceed()).isEqualTo(a + b+ c+ d+ e);
return a + b + c + d + e;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* @since 2.0
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
@@ -55,7 +56,7 @@ class AspectMetadataTests {
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTARGET);
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
.isEqualTo("execution(* *.getSpouse())");
.isEqualTo("execution(* *.getSpouse())");
}
@Test
@@ -66,7 +67,7 @@ class AspectMetadataTests {
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTHIS);
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
.isEqualTo("execution(* *.getSpouse())");
.isEqualTo("execution(* *.getSpouse())");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.aop.config;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -41,7 +40,7 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Juergen Hoeller
* @author Chris Beams
*/
class AopNamespaceHandlerEventTests {
public class AopNamespaceHandlerEventTests {
private static final Class<?> CLASS = AopNamespaceHandlerEventTests.class;
@@ -58,24 +57,25 @@ class AopNamespaceHandlerEventTests {
@BeforeEach
void setup() {
public void setup() {
this.reader = new XmlBeanDefinitionReader(this.beanFactory);
this.reader.setEventListener(this.eventListener);
}
@Test
void pointcutEvents() {
public void testPointcutEvents() {
this.reader.loadBeanDefinitions(POINTCUT_EVENTS_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(1);
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(1);
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition).as("No holder with nested components").isTrue();
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
PointcutComponentDefinition pcd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof PointcutComponentDefinition) {
@@ -84,77 +84,84 @@ class AopNamespaceHandlerEventTests {
}
}
assertThat(pcd).as("PointcutComponentDefinition not found").isNotNull();
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
}
@Test
void advisorEventsWithPointcutRef() {
public void testAdvisorEventsWithPointcutRef() {
this.reader.loadBeanDefinitions(POINTCUT_REF_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition1).as("No holder with nested components").isTrue();
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(3);
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(3);
AdvisorComponentDefinition acd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
for (int i = 0; i < nestedComponentDefs.length; i++) {
ComponentDefinition componentDefinition = nestedComponentDefs[i];
if (componentDefinition instanceof AdvisorComponentDefinition) {
acd = (AdvisorComponentDefinition) componentDefinition;
break;
}
}
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
assertThat(acd.getBeanDefinitions()).hasSize(1);
assertThat(acd.getBeanReferences()).hasSize(2);
assertThat(acd.getBeanDefinitions().length).isEqualTo(1);
assertThat(acd.getBeanReferences().length).isEqualTo(2);
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
assertThat(condition).as("No advice bean found").isTrue();
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
}
@Test
void advisorEventsWithDirectPointcut() {
public void testAdvisorEventsWithDirectPointcut() {
this.reader.loadBeanDefinitions(DIRECT_POINTCUT_EVENTS_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition1).as("No holder with nested components").isTrue();
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
AdvisorComponentDefinition acd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
for (int i = 0; i < nestedComponentDefs.length; i++) {
ComponentDefinition componentDefinition = nestedComponentDefs[i];
if (componentDefinition instanceof AdvisorComponentDefinition) {
acd = (AdvisorComponentDefinition) componentDefinition;
break;
}
}
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
assertThat(acd.getBeanDefinitions()).hasSize(2);
assertThat(acd.getBeanReferences()).hasSize(1);
assertThat(acd.getBeanDefinitions().length).isEqualTo(2);
assertThat(acd.getBeanReferences().length).isEqualTo(1);
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
assertThat(condition).as("No advice bean found").isTrue();
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
}
@Test
void aspectEvent() {
public void testAspectEvent() {
this.reader.loadBeanDefinitions(CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(5);
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition).as("No holder with nested components").isTrue();
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
AspectComponentDefinition acd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof AspectComponentDefinition) {
@@ -165,9 +172,9 @@ class AopNamespaceHandlerEventTests {
assertThat(acd).as("AspectComponentDefinition not found").isNotNull();
BeanDefinition[] beanDefinitions = acd.getBeanDefinitions();
assertThat(beanDefinitions).hasSize(5);
assertThat(beanDefinitions.length).isEqualTo(5);
BeanReference[] beanReferences = acd.getBeanReferences();
assertThat(beanReferences).hasSize(6);
assertThat(beanReferences.length).isEqualTo(6);
Set<String> expectedReferences = new HashSet<>();
expectedReferences.add("pc");
@@ -175,16 +182,19 @@ class AopNamespaceHandlerEventTests {
for (BeanReference beanReference : beanReferences) {
expectedReferences.remove(beanReference.getBeanName());
}
assertThat(expectedReferences).as("Incorrect references found").isEmpty();
assertThat(expectedReferences.size()).as("Incorrect references found").isEqualTo(0);
Arrays.stream(componentDefinitions).skip(1).forEach(definition ->
assertThat(definition).isInstanceOf(BeanComponentDefinition.class));
for (int i = 1; i < componentDefinitions.length; i++) {
boolean condition1 = componentDefinitions[i] instanceof BeanComponentDefinition;
assertThat(condition1).isTrue();
}
ComponentDefinition[] nestedComponentDefs2 = acd.getNestedComponents();
assertThat(nestedComponentDefs2).as("Inner PointcutComponentDefinition not found").hasSize(1);
assertThat(nestedComponentDefs2[0]).isInstanceOf(PointcutComponentDefinition.class);
assertThat(nestedComponentDefs2.length).as("Inner PointcutComponentDefinition not found").isEqualTo(1);
boolean condition1 = nestedComponentDefs2[0] instanceof PointcutComponentDefinition;
assertThat(condition1).isTrue();
PointcutComponentDefinition pcd = (PointcutComponentDefinition) nestedComponentDefs2[0];
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Mark Fisher
* @author Chris Beams
*/
class AopNamespaceHandlerPointcutErrorTests {
public class AopNamespaceHandlerPointcutErrorTests {
@Test
void duplicatePointcutConfig() {
public void testDuplicatePointcutConfig() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
@@ -42,7 +42,7 @@ class AopNamespaceHandlerPointcutErrorTests {
}
@Test
void missingPointcutConfig() {
public void testMissingPointcutConfig() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Rob Harrop
* @author Chris Beams
*/
class TopLevelAopTagTests {
public class TopLevelAopTagTests {
@Test
void parse() {
public void testParse() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(
qualifiedResource(TopLevelAopTagTests.class, "context.xml"));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.aop.framework;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@@ -33,7 +32,6 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
/**
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
*/
public class AopProxyUtilsTests {
@@ -134,61 +132,4 @@ public class AopProxyUtilsTests {
AopProxyUtils.proxiedUserInterfaces(proxy));
}
@Test
void isLambda() {
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
assertIsLambda(this.instanceLambdaExpression);
assertIsLambda(this::instanceStringFactory);
}
@Test
void isNotLambda() {
assertIsNotLambda(new EnigmaSupplier());
assertIsNotLambda(new Supplier<String>() {
@Override
public String get() {
return "anonymous inner class";
}
});
assertIsNotLambda(new Fake$$LambdaSupplier());
}
private static void assertIsLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
}
private static void assertIsNotLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
}
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
private static String staticStringFactory() {
return "static string factory";
}
private String instanceStringFactory() {
return "instance string factory";
}
private static class EnigmaSupplier implements Supplier<String> {
@Override
public String get() {
return "enigma";
}
}
private static class Fake$$LambdaSupplier implements Supplier<String> {
@Override
public String get() {
return "fake lambda";
}
}
}
@@ -125,7 +125,16 @@ public class ConcurrencyThrottleInterceptorTests {
try {
this.proxy.exceptional(this.ex);
}
catch (RuntimeException | Error err) {
catch (RuntimeException ex) {
if (ex == this.ex) {
logger.debug("Expected exception thrown", ex);
}
else {
// should never happen
ex.printStackTrace();
}
}
catch (Error err) {
if (err == this.ex) {
logger.debug("Expected exception thrown", err);
}
@@ -16,6 +16,12 @@
</aop:aspect>
</aop:config>
<bean id="getNameCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -9,6 +9,6 @@
<aop:advisor advice-ref="countingAdvice" pointcut="within(org.springframework..*)"/>
</aop:config>
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
</beans>
@@ -10,6 +10,6 @@
<aop:advisor advice-ref="countingAdvice" pointcut-ref="pc"/>
</aop:config>
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
</beans>
@@ -12,6 +12,10 @@
</aop:aspect>
</aop:config>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -12,6 +12,10 @@
</aop:aspect>
</aop:config>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.aop.testfixture.advice;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Abstract superclass for counting advices etc.
@@ -32,7 +31,7 @@ import java.util.Map;
public class MethodCounter implements Serializable {
/** Method name --> count, does not understand overloading */
private Map<String, Integer> map = new HashMap<>();
private HashMap<String, Integer> map = new HashMap<>();
private int allCount;
@@ -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.
@@ -20,6 +20,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
@@ -106,7 +107,10 @@ public class AspectJEnableCachingIsolatedTests {
try {
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
}
catch (IllegalStateException ex) {
catch (BeanCreationException ex) {
Throwable root = ex.getRootCause();
boolean condition = root instanceof IllegalStateException;
assertThat(condition).isTrue();
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -691,25 +691,7 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects.
* <p>The following table provides a non-exhaustive set of examples of source
* and target property types that can be copied as well as source and target
* property types that cannot be copied.
* <table border="1">
* <tr><th>source property type</th><th>target property type</th><th>copy supported</th></tr>
* <tr><td>{@code Integer}</td><td>{@code Integer}</td><td>yes</td></tr>
* <tr><td>{@code Integer}</td><td>{@code Number}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Integer>}</td><td>yes</td></tr>
* <tr><td>{@code List<?>}</td><td>{@code List<?>}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<?>}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<? extends Number>}</td><td>yes</td></tr>
* <tr><td>{@code String}</td><td>{@code Integer}</td><td>no</td></tr>
* <tr><td>{@code Number}</td><td>{@code Integer}</td><td>no</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Long>}</td><td>no</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Number>}</td><td>no</td></tr>
* </table>
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @throws BeansException if the copying failed
@@ -726,10 +708,7 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
@@ -747,10 +726,7 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @param ignoreProperties array of property names to ignore
@@ -767,8 +743,7 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* when matching properties in the source and target objects.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
@@ -214,7 +214,6 @@ public interface BeanFactory {
/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* <p>For matching a generic type, consider {@link #getBeanProvider(ResolvableType)}.
* @param requiredType type the bean must match; can be an interface or superclass
* @return a corresponding provider handle
* @since 5.1
@@ -224,20 +223,13 @@ public interface BeanFactory {
/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options. This variant allows
* for specifying a generic type to match, similar to reflective injection points
* with generic type declarations in method/constructor parameters.
* <p>Note that collections of beans are not supported here, in contrast to reflective
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be a generic type declaration.
* Note that collection types are not supported here, in contrast to reflective
* injection points. For programmatically retrieving a list of beans matching a
* specific type, specify the actual bean type as an argument here and subsequently
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
* <p>Also, generics matching is strict here, as per the Java assignment rules.
* For lenient fallback matching with unchecked semantics (similar to the ´unchecked´
* Java compiler warning), consider calling {@link #getBeanProvider(Class)} with the
* raw type as a second step if no full generic match is
* {@link ObjectProvider#getIfAvailable() available} with this variant.
* @return a corresponding provider handle
* @param requiredType type the bean must match; can be a generic type declaration
* @since 5.1
* @see ObjectProvider#iterator()
* @see ObjectProvider#stream()
@@ -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.
@@ -353,31 +353,9 @@ public interface ListableBeanFactory extends BeanFactory {
* @since 3.0
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
* @see #getType(String)
*/
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized
* just for the purpose of determining its object type
* @return the annotation of the given type if found, or {@code null} otherwise
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 5.3.14
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
* @see #getType(String, boolean)
*/
@Nullable
<A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException;
}
@@ -537,10 +537,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
return determineRequiredStatus(
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
checkedInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
checkedDestroyMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
@@ -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,7 +34,9 @@ import org.springframework.lang.Nullable;
*
* <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
* internal use within the framework. It is recommended to implement the plain
* {@link BeanPostProcessor} interface as far as possible.
* {@link BeanPostProcessor} interface as far as possible, or to derive from
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
* from extensions to this interface.
*
* @author Juergen Hoeller
* @author Rod Johnson
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1844,7 +1844,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
@@ -1868,7 +1868,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
@@ -1908,7 +1908,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
@@ -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.
@@ -103,14 +103,6 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
}
/**
* Return the bean factory to register the bean definitions with.
* <p>The factory is exposed through the BeanDefinitionRegistry interface,
* encapsulating the methods that are relevant for bean definition handling.
* @deprecated as of Spring Framework 5.3.15 in favor of {@link #getRegistry()},
* to be removed in Spring Framework 6.0
*/
@Deprecated
public final BeanDefinitionRegistry getBeanFactory() {
return this.registry;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -22,15 +22,15 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.Nullable;
/**
* Simple interface for bean definition readers that specifies load methods with
* {@link Resource} and {@link String} location parameters.
* Simple interface for bean definition readers.
* Specifies load methods with Resource and String location parameters.
*
* <p>Concrete bean definition readers can of course add additional
* load and register methods for bean definitions, specific to
* their bean definition format.
*
* <p>Note that a bean definition reader does not have to implement
* this interface. It only serves as a suggestion for bean definition
* this interface. It only serves as suggestion for bean definition
* readers that want to follow standard naming conventions.
*
* @author Juergen Hoeller
@@ -41,14 +41,14 @@ public interface BeanDefinitionReader {
/**
* Return the bean factory to register the bean definitions with.
* <p>The factory is exposed through the {@link BeanDefinitionRegistry} interface,
* <p>The factory is exposed through the BeanDefinitionRegistry interface,
* encapsulating the methods that are relevant for bean definition handling.
*/
BeanDefinitionRegistry getRegistry();
/**
* Return the {@link ResourceLoader} to use for resource locations.
* <p>Can be checked for the {@code ResourcePatternResolver} interface and cast
* Return the resource loader to use for resource locations.
* Can be checked for the <b>ResourcePatternResolver</b> interface and cast
* accordingly, for loading multiple resources for a given resource pattern.
* <p>A {@code null} return value suggests that absolute resource loading
* is not available for this bean definition reader.
@@ -56,10 +56,10 @@ public interface BeanDefinitionReader {
* from within a bean definition resource, for example via the "import"
* tag in XML bean definitions. It is recommended, however, to apply
* such imports relative to the defining resource; only explicit full
* resource locations will trigger absolute path based resource loading.
* resource locations will trigger absolute resource loading.
* <p>There is also a {@code loadBeanDefinitions(String)} method available,
* for loading bean definitions from a resource location (or location pattern).
* This is a convenience to avoid explicit {@code ResourceLoader} handling.
* This is a convenience to avoid explicit ResourceLoader handling.
* @see #loadBeanDefinitions(String)
* @see org.springframework.core.io.support.ResourcePatternResolver
*/
@@ -70,13 +70,13 @@ public interface BeanDefinitionReader {
* Return the class loader to use for bean classes.
* <p>{@code null} suggests to not load bean classes eagerly
* but rather to just register bean definitions with class names,
* with the corresponding classes to be resolved later (or never).
* with the corresponding Classes to be resolved later (or never).
*/
@Nullable
ClassLoader getBeanClassLoader();
/**
* Return the {@link BeanNameGenerator} to use for anonymous beans
* Return the BeanNameGenerator to use for anonymous beans
* (without explicit bean name specified).
*/
BeanNameGenerator getBeanNameGenerator();
@@ -101,10 +101,9 @@ public interface BeanDefinitionReader {
/**
* Load bean definitions from the specified resource location.
* <p>The location can also be a location pattern, provided that the
* {@link ResourceLoader} of this bean definition reader is a
* {@code ResourcePatternResolver}.
* @param location the resource location, to be loaded with the {@code ResourceLoader}
* (or {@code ResourcePatternResolver}) of this bean definition reader
* ResourceLoader of this bean definition reader is a ResourcePatternResolver.
* @param location the resource location, to be loaded with the ResourceLoader
* (or ResourcePatternResolver) of this bean definition reader
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
* @see #getResourceLoader()
@@ -115,8 +114,8 @@ public interface BeanDefinitionReader {
/**
* Load bean definitions from the specified resource locations.
* @param locations the resource locations, to be loaded with the {@code ResourceLoader}
* (or {@code ResourcePatternResolver}) of this bean definition reader
* @param locations the resource locations, to be loaded with the ResourceLoader
* (or ResourcePatternResolver) of this bean definition reader
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
@@ -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.
@@ -730,23 +730,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException {
return findAnnotationOnBean(beanName, annotationType, true);
}
@Override
@Nullable
public <A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException {
return findMergedAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit)
return findMergedAnnotationOnBean(beanName, annotationType)
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
private <A extends Annotation> MergedAnnotation<A> findMergedAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit) {
String beanName, Class<A> annotationType) {
Class<?> beanType = getType(beanName, allowFactoryBeanInit);
Class<?> beanType = getType(beanName);
if (beanType != null) {
MergedAnnotation<A> annotation =
MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,7 +52,6 @@ import org.springframework.util.StringUtils;
* @author Juergen Hoeller
* @author Costin Leau
* @author Stephane Nicoll
* @author Sam Brannen
* @since 2.0
* @see AbstractBeanFactory
* @see org.springframework.beans.factory.DisposableBean
@@ -110,12 +109,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.beanName = beanName;
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.invokeDisposableBean = (bean instanceof DisposableBean &&
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null &&
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
if (!this.invokeAutoCloseable) {
@@ -139,7 +138,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass());
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
@@ -253,9 +252,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method destroyMethod = determineDestroyMethod(this.destroyMethodName);
if (destroyMethod != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass()));
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.beans.factory.support;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.BeanMetadataElement;
@@ -54,20 +53,6 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
}
/**
* Return a new instance containing an arbitrary number of elements.
* @param elements the elements to be contained in the list
* @param <E> the {@code List}'s element type
* @return a {@code List} containing the specified elements
* @since 5.3.16
*/
@SuppressWarnings("unchecked")
public static <E> ManagedList<E> of(E... elements) {
ManagedList<E> list = new ManagedList<>();
list.addAll(Arrays.asList(elements));
return list;
}
/**
* Set the configuration source {@code Object} for this metadata element.
* <p>The exact type of the object will depend on the configuration mechanism used.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.beans.factory.support;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.Mergeable;
@@ -57,26 +56,6 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
}
/**
* Return a new instance containing keys and values extracted from the
* given entries. The entries themselves are not stored in the map.
* @param entries {@code Map.Entry}s containing the keys and values
* from which the map is populated
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
* @return a {@code Map} containing the specified mappings
* @since 5.3.16
*/
@SafeVarargs
@SuppressWarnings("unchecked")
public static <K,V> ManagedMap<K,V> ofEntries(Entry<? extends K, ? extends V>... entries) {
ManagedMap<K,V > map = new ManagedMap<>();
for (Entry<? extends K, ? extends V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
/**
* Set the configuration source {@code Object} for this metadata element.
* <p>The exact type of the object will depend on the configuration mechanism used.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.beans.factory.support;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -53,20 +52,6 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
}
/**
* Return a new instance containing an arbitrary number of elements.
* @param elements the elements to be contained in the set
* @param <E> the {@code Set}'s element type
* @return a {@code Set} containing the specified elements
* @since 5.3.16
*/
@SuppressWarnings("unchecked")
public static <E> ManagedSet<E> of(E... elements) {
ManagedSet<E> set = new ManagedSet<>();
set.addAll(Arrays.asList(elements));
return set;
}
/**
* Set the configuration source {@code Object} for this metadata element.
* <p>The exact type of the object will depend on the configuration mechanism used.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,6 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @see GenericBeanDefinition
* @see ChildBeanDefinition
*/
@@ -437,7 +436,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Determine if the given method or field is an externally managed configuration member.
* Check whether the given method or field is an externally managed configuration member.
*/
public boolean isExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
@@ -447,7 +446,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Get all externally managed configuration methods and fields (as an immutable Set).
* Return all externally managed configuration methods and fields (as an immutable Set).
* @since 5.3.11
*/
public Set<Member> getExternallyManagedConfigMembers() {
@@ -459,15 +458,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Register an externally managed configuration initialization method &mdash;
* for example, a method annotated with JSR-250's
* {@link javax.annotation.PostConstruct} annotation.
* <p>The supplied {@code initMethod} may be the
* {@linkplain Method#getName() simple method name} for non-private methods or the
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
* qualified method name} for {@code private} methods. A qualified name is
* necessary for {@code private} methods in order to disambiguate between
* multiple private methods with the same name within a class hierarchy.
* Register an externally managed configuration initialization method.
*/
public void registerExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
@@ -479,10 +470,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Determine if the given method name indicates an externally managed
* initialization method.
* <p>See {@link #registerExternallyManagedInitMethod} for details
* regarding the format for the supplied {@code initMethod}.
* Check whether the given method name indicates an externally managed initialization method.
*/
public boolean isExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
@@ -491,40 +479,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Determine if the given method name indicates an externally managed
* initialization method, regardless of method visibility.
* <p>In contrast to {@link #isExternallyManagedInitMethod(String)}, this
* method also returns {@code true} if there is a {@code private} externally
* managed initialization method that has been
* {@linkplain #registerExternallyManagedInitMethod(String) registered}
* using a qualified method name instead of a simple method name.
* @since 5.3.17
*/
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (isExternallyManagedInitMethod(initMethod)) {
return true;
}
if (this.externallyManagedInitMethods != null) {
for (String candidate : this.externallyManagedInitMethods) {
int indexOfDot = candidate.lastIndexOf('.');
if (indexOfDot >= 0) {
String methodName = candidate.substring(indexOfDot + 1);
if (methodName.equals(initMethod)) {
return true;
}
}
}
}
return false;
}
}
/**
* Return all externally managed initialization methods (as an immutable Set).
* <p>See {@link #registerExternallyManagedInitMethod} for details
* regarding the format for the initialization methods in the returned set.
* @since 5.3.11
*/
public Set<String> getExternallyManagedInitMethods() {
@@ -536,15 +492,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Register an externally managed configuration destruction method &mdash;
* for example, a method annotated with JSR-250's
* {@link javax.annotation.PreDestroy} annotation.
* <p>The supplied {@code destroyMethod} may be the
* {@linkplain Method#getName() simple method name} for non-private methods or the
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
* qualified method name} for {@code private} methods. A qualified name is
* necessary for {@code private} methods in order to disambiguate between
* multiple private methods with the same name within a class hierarchy.
* Register an externally managed configuration destruction method.
*/
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
@@ -556,10 +504,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Determine if the given method name indicates an externally managed
* destruction method.
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
* regarding the format for the supplied {@code destroyMethod}.
* Check whether the given method name indicates an externally managed destruction method.
*/
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
@@ -569,39 +514,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
* Determine if the given method name indicates an externally managed
* destruction method, regardless of method visibility.
* <p>In contrast to {@link #isExternallyManagedDestroyMethod(String)}, this
* method also returns {@code true} if there is a {@code private} externally
* managed destruction method that has been
* {@linkplain #registerExternallyManagedDestroyMethod(String) registered}
* using a qualified method name instead of a simple method name.
* @since 5.3.17
*/
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (isExternallyManagedDestroyMethod(destroyMethod)) {
return true;
}
if (this.externallyManagedDestroyMethods != null) {
for (String candidate : this.externallyManagedDestroyMethods) {
int indexOfDot = candidate.lastIndexOf('.');
if (indexOfDot >= 0) {
String methodName = candidate.substring(indexOfDot + 1);
if (methodName.equals(destroyMethod)) {
return true;
}
}
}
}
return false;
}
}
/**
* Get all externally managed destruction methods (as an immutable Set).
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
* regarding the format for the destruction methods in the returned set.
* Return all externally managed destruction methods (as an immutable Set).
* @since 5.3.11
*/
public Set<String> getExternallyManagedDestroyMethods() {
@@ -1,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.
@@ -459,16 +459,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException {
return findAnnotationOnBean(beanName, annotationType, true);
}
@Override
@Nullable
public <A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException {
Class<?> beanType = getType(beanName, allowFactoryBeanInit);
Class<?> beanType = getType(beanName);
return (beanType != null ? AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType) : null);
}
@@ -64,6 +64,6 @@ inline fun <reified T : Annotation> ListableBeanFactory.getBeansWithAnnotation()
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): T? =
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): Annotation? =
findAnnotationOnBean(beanName, T::class.java)
@@ -43,13 +43,13 @@ public abstract class AbstractPropertyValuesTests {
m.put("forname", "Tony");
m.put("surname", "Blair");
m.put("age", "50");
for (PropertyValue element : ps) {
Object val = m.get(element.getName());
for (int i = 0; i < ps.length; i++) {
Object val = m.get(ps[i].getName());
assertThat(val != null).as("Can't have unexpected value").isTrue();
boolean condition = val instanceof String;
assertThat(condition).as("Val i string").isTrue();
assertThat(val.equals(element.getValue())).as("val matches expected").isTrue();
m.remove(element.getName());
assertThat(val.equals(ps[i].getValue())).as("val matches expected").isTrue();
m.remove(ps[i].getName());
}
assertThat(m.size() == 0).as("Map size is 0").isTrue();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -203,25 +203,8 @@ class BeanUtilsTests {
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
}
/**
* {@code Integer} can be copied to {@code Number}.
*/
@Test
void copyPropertiesFromSubTypeToSuperType() {
IntegerHolder integerHolder = new IntegerHolder();
integerHolder.setNumber(42);
NumberHolder numberHolder = new NumberHolder();
BeanUtils.copyProperties(integerHolder, numberHolder);
assertThat(integerHolder.getNumber()).isEqualTo(42);
assertThat(numberHolder.getNumber()).isEqualTo(42);
}
/**
* {@code List<Integer>} can be copied to {@code List<Integer>}.
*/
@Test
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToInteger() {
void copyPropertiesHonorsGenericTypeMatches() {
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
integerListHolder1.getList().add(42);
IntegerListHolder2 integerListHolder2 = new IntegerListHolder2();
@@ -231,68 +214,6 @@ class BeanUtilsTests {
assertThat(integerListHolder2.getList()).containsOnly(42);
}
/**
* {@code List<?>} can be copied to {@code List<?>}.
*/
@Test
void copyPropertiesHonorsGenericTypeMatchesFromWildcardToWildcard() {
List<?> list = Arrays.asList("foo", 42);
WildcardListHolder1 wildcardListHolder1 = new WildcardListHolder1();
wildcardListHolder1.setList(list);
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
assertThat(wildcardListHolder2.getList()).isEmpty();
BeanUtils.copyProperties(wildcardListHolder1, wildcardListHolder2);
assertThat(wildcardListHolder1.getList()).isEqualTo(list);
assertThat(wildcardListHolder2.getList()).isEqualTo(list);
}
/**
* {@code List<Integer>} can be copied to {@code List<?>}.
*/
@Test
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToWildcard() {
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
integerListHolder1.getList().add(42);
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
BeanUtils.copyProperties(integerListHolder1, wildcardListHolder2);
assertThat(integerListHolder1.getList()).containsOnly(42);
assertThat(wildcardListHolder2.getList()).isEqualTo(Arrays.asList(42));
}
/**
* {@code List<Integer>} can be copied to {@code List<? extends Number>}.
*/
@Test
void copyPropertiesHonorsGenericTypeMatchesForUpperBoundedWildcard() {
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
integerListHolder1.getList().add(42);
NumberUpperBoundedWildcardListHolder numberListHolder = new NumberUpperBoundedWildcardListHolder();
BeanUtils.copyProperties(integerListHolder1, numberListHolder);
assertThat(integerListHolder1.getList()).containsOnly(42);
assertThat(numberListHolder.getList()).hasSize(1);
assertThat(numberListHolder.getList().contains(Integer.valueOf(42))).isTrue();
}
/**
* {@code Number} can NOT be copied to {@code Integer}.
*/
@Test
void copyPropertiesDoesNotCopyeFromSuperTypeToSubType() {
NumberHolder numberHolder = new NumberHolder();
numberHolder.setNumber(Integer.valueOf(42));
IntegerHolder integerHolder = new IntegerHolder();
BeanUtils.copyProperties(numberHolder, integerHolder);
assertThat(numberHolder.getNumber()).isEqualTo(42);
assertThat(integerHolder.getNumber()).isNull();
}
/**
* {@code List<Integer>} can NOT be copied to {@code List<Long>}.
*/
@Test
void copyPropertiesDoesNotHonorGenericTypeMismatches() {
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
@@ -304,20 +225,6 @@ class BeanUtilsTests {
assertThat(longListHolder.getList()).isEmpty();
}
/**
* {@code List<Integer>} can NOT be copied to {@code List<Number>}.
*/
@Test
void copyPropertiesDoesNotHonorGenericTypeMismatchesFromSubTypeToSuperType() {
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
integerListHolder.getList().add(42);
NumberListHolder numberListHolder = new NumberListHolder();
BeanUtils.copyProperties(integerListHolder, numberListHolder);
assertThat(integerListHolder.getList()).containsOnly(42);
assertThat(numberListHolder.getList()).isEmpty();
}
@Test // gh-26531
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() throws Exception {
Order original = new Order("test", Arrays.asList("foo", "bar"));
@@ -506,90 +413,6 @@ class BeanUtilsTests {
}
@SuppressWarnings("unused")
private static class NumberHolder {
private Number number;
public Number getNumber() {
return number;
}
public void setNumber(Number number) {
this.number = number;
}
}
@SuppressWarnings("unused")
private static class IntegerHolder {
private Integer number;
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
}
@SuppressWarnings("unused")
private static class WildcardListHolder1 {
private List<?> list = new ArrayList<>();
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}
@SuppressWarnings("unused")
private static class WildcardListHolder2 {
private List<?> list = new ArrayList<>();
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}
@SuppressWarnings("unused")
private static class NumberUpperBoundedWildcardListHolder {
private List<? extends Number> list = new ArrayList<>();
public List<? extends Number> getList() {
return list;
}
public void setList(List<? extends Number> list) {
this.list = list;
}
}
@SuppressWarnings("unused")
private static class NumberListHolder {
private List<Number> list = new ArrayList<>();
public List<Number> getList() {
return list;
}
public void setList(List<Number> list) {
this.list = list;
}
}
@SuppressWarnings("unused")
private static class IntegerListHolder1 {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@@ -46,7 +46,7 @@ public class BeanWrapperEnumTests {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("customEnum", null);
assertThat(gb.getCustomEnum()).isNull();
assertThat(gb.getCustomEnum()).isEqualTo(null);
}
@Test
@@ -54,7 +54,7 @@ public class BeanWrapperEnumTests {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("customEnum", "");
assertThat(gb.getCustomEnum()).isNull();
assertThat(gb.getCustomEnum()).isEqualTo(null);
}
@Test
@@ -483,7 +483,6 @@ public class BeanFactoryUtilsTests {
return TestBean.class;
}
@Override
public TestBean getObject() {
// We don't really care if the actual instance is a singleton or prototype
// for the tests that use this factory.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,6 +48,8 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
@@ -82,6 +84,7 @@ import org.springframework.beans.testfixture.beans.factory.DummyFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.io.Resource;
@@ -430,7 +433,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("x1", Object.class)).isTrue();
assertThat(lbf.isTypeMatch("&x1", Object.class)).isFalse();
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x1")).isNull();
assertThat(lbf.getType("&x1")).isEqualTo(null);
assertThat(TestBeanFactory.initialized).isFalse();
lbf.registerAlias("x1", "x2");
@@ -987,13 +990,16 @@ class DefaultListableBeanFactoryTests {
@Test
void customConverter() {
GenericConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(String.class, Float.class, source -> {
try {
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
return nf.parse(source).floatValue();
}
catch (ParseException ex) {
throw new IllegalArgumentException(ex);
conversionService.addConverter(new Converter<String, Float>() {
@Override
public Float convert(String source) {
try {
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
return nf.parse(source).floatValue();
}
catch (ParseException ex) {
throw new IllegalArgumentException(ex);
}
}
});
lbf.setConversionService(conversionService);
@@ -1008,9 +1014,12 @@ class DefaultListableBeanFactoryTests {
@Test
void customEditorWithBeanReference() {
lbf.addPropertyEditorRegistrar(registry -> {
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
}
});
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
@@ -2298,7 +2307,9 @@ class DefaultListableBeanFactoryTests {
@Test
void prototypeWithArrayConversionForConstructor() {
List<String> list = ManagedList.of("myName", "myBeanName");
List<String> list = new ManagedList<>();
list.add("myName");
list.add("myBeanName");
RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.getConstructorArgumentValues().addGenericArgumentValue(list);
@@ -2314,7 +2325,9 @@ class DefaultListableBeanFactoryTests {
@Test
void prototypeWithArrayConversionForFactoryMethod() {
List<String> list = ManagedList.of("myName", "myBeanName");
List<String> list = new ManagedList<>();
list.add("myName");
list.add("myBeanName");
RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.setFactoryMethodName("create");
@@ -2609,8 +2622,8 @@ class DefaultListableBeanFactoryTests {
void containsBeanReturnsTrueEvenForAbstractBeanDefinition() {
lbf.registerBeanDefinition("abs", BeanDefinitionBuilder
.rootBeanDefinition(TestBean.class).setAbstract(true).getBeanDefinition());
assertThat(lbf.containsBean("abs")).isTrue();
assertThat(lbf.containsBean("bogus")).isFalse();
assertThat(lbf.containsBean("abs")).isEqualTo(true);
assertThat(lbf.containsBean("bogus")).isEqualTo(false);
}
@Test
@@ -2705,12 +2718,8 @@ class DefaultListableBeanFactoryTests {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConstructorDependency that = (ConstructorDependency) o;
return spouseAge == that.spouseAge &&
Objects.equals(spouse, that.spouse) &&
@@ -22,6 +22,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
@@ -3659,8 +3660,11 @@ public class AutowiredAnnotationBeanPostProcessorTests {
@SuppressWarnings("unchecked")
public <T> T createMock(Class<T> toMock) {
return (T) Proxy.newProxyInstance(AutowiredAnnotationBeanPostProcessorTests.class.getClassLoader(), new Class<?>[] {toMock},
(InvocationHandler) (proxy, method, args) -> {
throw new UnsupportedOperationException("mocked!");
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw new UnsupportedOperationException("mocked!");
}
});
}
}
@@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.propertyeditors.CustomDateEditor;
@@ -49,7 +50,12 @@ public class CustomEditorConfigurerTests {
CustomEditorConfigurer cec = new CustomEditorConfigurer();
final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);
cec.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {
registry -> registry.registerCustomEditor(Date.class, new CustomDateEditor(df, true))});
new PropertyEditorRegistrar() {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new CustomDateEditor(df, true));
}
}});
cec.postProcessBeanFactory(bf);
MutablePropertyValues pvs = new MutablePropertyValues();
@@ -113,7 +113,7 @@ public class MethodInvokingFactoryBeanTests {
mcfb = new MethodInvokingFactoryBean();
mcfb.setTargetClass(TestClass1.class);
mcfb.setTargetMethod("supertypes");
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello");
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello");
mcfb.afterPropertiesSet();
mcfb.getObjectType();
@@ -184,7 +184,7 @@ public class MethodInvokingFactoryBeanTests {
mcfb = new MethodInvokingFactoryBean();
mcfb.setTargetClass(TestClass1.class);
mcfb.setTargetMethod("supertypes");
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello");
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello");
// should pass
mcfb.afterPropertiesSet();
}
@@ -194,7 +194,7 @@ public class MethodInvokingFactoryBeanTests {
MethodInvokingFactoryBean mcfb = new MethodInvokingFactoryBean();
mcfb.setTargetClass(TestClass1.class);
mcfb.setTargetMethod("supertypes");
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", "bogus");
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello", "bogus");
assertThatExceptionOfType(NoSuchMethodException.class).as(
"Matched method with wrong number of args").isThrownBy(
mcfb::afterPropertiesSet);
@@ -210,14 +210,14 @@ public class MethodInvokingFactoryBeanTests {
mcfb = new MethodInvokingFactoryBean();
mcfb.setTargetClass(TestClass1.class);
mcfb.setTargetMethod("supertypes2");
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", "bogus");
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello", "bogus");
mcfb.afterPropertiesSet();
assertThat(mcfb.getObject()).isEqualTo("hello");
mcfb = new MethodInvokingFactoryBean();
mcfb.setTargetClass(TestClass1.class);
mcfb.setTargetMethod("supertypes2");
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), new Object());
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), new Object());
assertThatExceptionOfType(NoSuchMethodException.class).as(
"Matched method when shouldn't have matched").isThrownBy(
mcfb::afterPropertiesSet);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.beans.factory.config;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -112,7 +111,7 @@ public class PropertyResourceConfigurerTests {
assertThat(tb1.getAge()).isEqualTo(99);
assertThat(tb2.getAge()).isEqualTo(99);
assertThat(tb1.getName()).isNull();
assertThat(tb1.getName()).isEqualTo(null);
assertThat(tb2.getName()).isEqualTo("test");
}
@@ -311,7 +310,7 @@ public class PropertyResourceConfigurerTests {
TestBean tb2 = (TestBean) factory.getBean("tb2");
assertThat(tb1.getAge()).isEqualTo(99);
assertThat(tb2.getAge()).isEqualTo(99);
assertThat(tb1.getName()).isNull();
assertThat(tb1.getName()).isEqualTo(null);
assertThat(tb2.getName()).isEqualTo("test");
}
@@ -358,18 +357,22 @@ public class PropertyResourceConfigurerTests {
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("stringArray", new String[] {"${os.name}", "${age}"});
List<Object> friends = ManagedList.of("na${age}me", new RuntimeBeanReference("${ref}"));
List<Object> friends = new ManagedList<>();
friends.add("na${age}me");
friends.add(new RuntimeBeanReference("${ref}"));
pvs.add("friends", friends);
Set<Object> someSet = ManagedSet.of("na${age}me",
new RuntimeBeanReference("${ref}"), new TypedStringValue("${age}", Integer.class));
Set<Object> someSet = new ManagedSet<>();
someSet.add("na${age}me");
someSet.add(new RuntimeBeanReference("${ref}"));
someSet.add(new TypedStringValue("${age}", Integer.class));
pvs.add("someSet", someSet);
Map<Object, Object> someMap = ManagedMap.ofEntries(
new SimpleEntry<>(new TypedStringValue("key${age}"), new TypedStringValue("${age}")),
new SimpleEntry<>(new TypedStringValue("key${age}ref"), new RuntimeBeanReference("${ref}")),
new SimpleEntry<>("key1", new RuntimeBeanReference("${ref}")),
new SimpleEntry<>("key2", "${age}name"));
Map<Object, Object> someMap = new ManagedMap<>();
someMap.put(new TypedStringValue("key${age}"), new TypedStringValue("${age}"));
someMap.put(new TypedStringValue("key${age}ref"), new RuntimeBeanReference("${ref}"));
someMap.put("key1", new RuntimeBeanReference("${ref}"));
someMap.put("key2", "${age}name");
MutablePropertyValues innerPvs = new MutablePropertyValues();
innerPvs.add("country", "${os.name}");
RootBeanDefinition innerBd = new RootBeanDefinition(TestBean.class);
@@ -420,7 +423,7 @@ public class PropertyResourceConfigurerTests {
TestBean inner1 = (TestBean) tb2.getSomeMap().get("key3");
TestBean inner2 = (TestBean) tb2.getSomeMap().get("mykey4");
assertThat(inner1.getAge()).isEqualTo(0);
assertThat(inner1.getName()).isNull();
assertThat(inner1.getName()).isEqualTo(null);
assertThat(inner1.getCountry()).isEqualTo(System.getProperty("os.name"));
assertThat(inner2.getAge()).isEqualTo(98);
assertThat(inner2.getName()).isEqualTo("namemyvarmyvar${");
@@ -17,6 +17,7 @@
package org.springframework.beans.factory.support;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URI;
@@ -33,6 +34,8 @@ import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
@@ -406,7 +409,12 @@ class BeanFactoryGenericsTests {
@Test
void testGenericMapWithCollectionValueConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addPropertyEditorRegistrar(registry -> registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)));
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
}
});
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
Map<String, AbstractCollection<?>> input = new HashMap<>();
@@ -560,7 +568,12 @@ class BeanFactoryGenericsTests {
@Test
void testGenericMapWithCollectionValueFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addPropertyEditorRegistrar(registry -> registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)));
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
}
});
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -997,8 +1010,11 @@ class BeanFactoryGenericsTests {
@SuppressWarnings("unchecked")
public <T> T createMock(Class<T> toMock) {
return (T) Proxy.newProxyInstance(BeanFactoryGenericsTests.class.getClassLoader(), new Class<?>[] {toMock},
(InvocationHandler) (proxy, method, args) -> {
throw new UnsupportedOperationException("mocked!");
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw new UnsupportedOperationException("mocked!");
}
});
}
}
@@ -18,6 +18,8 @@ package org.springframework.beans.factory.support;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.testfixture.beans.DerivedTestBean;
import org.springframework.beans.testfixture.beans.TestBean;
@@ -38,7 +40,12 @@ public class DefaultSingletonBeanRegistryTests {
beanRegistry.registerSingleton("tb", tb);
assertThat(beanRegistry.getSingleton("tb")).isSameAs(tb);
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", () -> new TestBean());
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return new TestBean();
}
});
assertThat(beanRegistry.getSingleton("tb2")).isSameAs(tb2);
assertThat(beanRegistry.getSingleton("tb")).isSameAs(tb);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,11 @@ public class ManagedListTests {
@Test
public void mergeSunnyDay() {
ManagedList parent = ManagedList.of("one", "two");
ManagedList child = ManagedList.of("three");
ManagedList parent = new ManagedList();
parent.add("one");
parent.add("two");
ManagedList child = new ManagedList();
child.add("three");
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
@@ -43,7 +46,8 @@ public class ManagedListTests {
@Test
public void mergeWithNullParent() {
ManagedList child = ManagedList.of("one");
ManagedList child = new ManagedList();
child.add("one");
child.setMergeEnabled(true);
assertThat(child.merge(null)).isSameAs(child);
}
@@ -57,7 +61,8 @@ public class ManagedListTests {
@Test
public void mergeWithNonCompatibleParentType() {
ManagedList child = ManagedList.of("one");
ManagedList child = new ManagedList();
child.add("one");
child.setMergeEnabled(true);
assertThatIllegalArgumentException().isThrownBy(() ->
child.merge("hello"));
@@ -65,7 +70,9 @@ public class ManagedListTests {
@Test
public void mergeEmptyChild() {
ManagedList parent = ManagedList.of("one", "two");
ManagedList parent = new ManagedList();
parent.add("one");
parent.add("two");
ManagedList child = new ManagedList();
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
@@ -75,8 +82,11 @@ public class ManagedListTests {
@Test
public void mergeChildValuesOverrideTheParents() {
// doesn't make much sense in the context of a list...
ManagedList parent = ManagedList.of("one", "two");
ManagedList child = ManagedList.of("one");
ManagedList parent = new ManagedList();
parent.add("one");
parent.add("two");
ManagedList child = new ManagedList();
child.add("one");
child.setMergeEnabled(true);
List mergedList = child.merge(parent);
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.beans.factory.support;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import org.junit.jupiter.api.Test;
@@ -35,9 +34,11 @@ public class ManagedMapTests {
@Test
public void mergeSunnyDay() {
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
new SimpleEntry<>("two", "two"));
ManagedMap child = ManagedMap.ofEntries(new SimpleEntry<>("tree", "three"));
ManagedMap parent = new ManagedMap();
parent.put("one", "one");
parent.put("two", "two");
ManagedMap child = new ManagedMap();
child.put("three", "three");
child.setMergeEnabled(true);
Map mergedMap = (Map) child.merge(parent);
assertThat(mergedMap.size()).as("merge() obviously did not work.").isEqualTo(3);
@@ -66,8 +67,9 @@ public class ManagedMapTests {
@Test
public void mergeEmptyChild() {
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
new SimpleEntry<>("two", "two"));
ManagedMap parent = new ManagedMap();
parent.put("one", "one");
parent.put("two", "two");
ManagedMap child = new ManagedMap();
child.setMergeEnabled(true);
Map mergedMap = (Map) child.merge(parent);
@@ -76,9 +78,11 @@ public class ManagedMapTests {
@Test
public void mergeChildValuesOverrideTheParents() {
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
new SimpleEntry<>("two", "two"));
ManagedMap child = ManagedMap.ofEntries(new SimpleEntry<>("one", "fork"));
ManagedMap parent = new ManagedMap();
parent.put("one", "one");
parent.put("two", "two");
ManagedMap child = new ManagedMap();
child.put("one", "fork");
child.setMergeEnabled(true);
Map mergedMap = (Map) child.merge(parent);
// child value for 'one' must override parent value...
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,10 @@ public class ManagedSetTests {
@Test
public void mergeSunnyDay() {
ManagedSet parent = ManagedSet.of("one", "two");
ManagedSet child = ManagedSet.of("three");
ManagedSet parent = new ManagedSet();
parent.add("one");
parent.add("two");
ManagedSet child = new ManagedSet();
child.add("three");
child.setMergeEnabled(true);
Set mergedSet = child.merge(parent);
@@ -44,7 +46,8 @@ public class ManagedSetTests {
@Test
public void mergeWithNullParent() {
ManagedSet child = ManagedSet.of("one");
ManagedSet child = new ManagedSet();
child.add("one");
child.setMergeEnabled(true);
assertThat(child.merge(null)).isSameAs(child);
}
@@ -57,7 +60,8 @@ public class ManagedSetTests {
@Test
public void mergeWithNonCompatibleParentType() {
ManagedSet child = ManagedSet.of("one");
ManagedSet child = new ManagedSet();
child.add("one");
child.setMergeEnabled(true);
assertThatIllegalArgumentException().isThrownBy(() ->
child.merge("hello"));
@@ -65,7 +69,9 @@ public class ManagedSetTests {
@Test
public void mergeEmptyChild() {
ManagedSet parent = ManagedSet.of("one", "two");
ManagedSet parent = new ManagedSet();
parent.add("one");
parent.add("two");
ManagedSet child = new ManagedSet();
child.setMergeEnabled(true);
Set mergedSet = child.merge(parent);
@@ -75,8 +81,11 @@ public class ManagedSetTests {
@Test
public void mergeChildValuesOverrideTheParents() {
// asserts that the set contract is not violated during a merge() operation...
ManagedSet parent = ManagedSet.of("one", "two");
ManagedSet child = ManagedSet.of("one");
ManagedSet parent = new ManagedSet();
parent.add("one");
parent.add("two");
ManagedSet child = new ManagedSet();
child.add("one");
child.setMergeEnabled(true);
Set mergedSet = child.merge(parent);
assertThat(mergedSet.size()).as("merge() obviously did not work.").isEqualTo(2);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -449,7 +449,7 @@ public class CallbacksSecurityTests {
public Object run() {
// sanity check
assertThat(getCurrentSubjectName()).isEqualTo("user1");
assertThat(NonPrivilegedBean.destroyed).isFalse();
assertThat(NonPrivilegedBean.destroyed).isEqualTo(false);
beanFactory.getBean("trusted-spring-callbacks");
beanFactory.getBean("trusted-custom-init-destroy");
@@ -465,7 +465,7 @@ public class CallbacksSecurityTests {
beanFactory.getBean("trusted-working-property-injection");
beanFactory.destroySingletons();
assertThat(NonPrivilegedBean.destroyed).isTrue();
assertThat(NonPrivilegedBean.destroyed).isEqualTo(true);
return null;
}
}, provider.getAccessControlContext());
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -100,17 +100,17 @@ public class FactoryMethodTests {
FactoryMethods fm = (FactoryMethods) xbf.getBean("fullWithNull");
assertThat(fm.getNum()).isEqualTo(27);
assertThat(fm.getName()).isNull();
assertThat(fm.getName()).isEqualTo(null);
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
fm = (FactoryMethods) xbf.getBean("fullWithGenericNull");
assertThat(fm.getNum()).isEqualTo(27);
assertThat(fm.getName()).isNull();
assertThat(fm.getName()).isEqualTo(null);
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
fm = (FactoryMethods) xbf.getBean("fullWithNamedNull");
assertThat(fm.getNum()).isEqualTo(27);
assertThat(fm.getName()).isNull();
assertThat(fm.getName()).isEqualTo(null);
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -342,7 +342,7 @@ public class UtilNamespaceHandlerTests {
public void testLoadProperties() {
Properties props = (Properties) this.beanFactory.getBean("myProperties");
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
Properties props2 = (Properties) this.beanFactory.getBean("myProperties");
assertThat(props == props2).isTrue();
}
@@ -351,17 +351,17 @@ public class UtilNamespaceHandlerTests {
public void testScopedProperties() {
Properties props = (Properties) this.beanFactory.getBean("myScopedProperties");
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
Properties props2 = (Properties) this.beanFactory.getBean("myScopedProperties");
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
assertThat(props != props2).isTrue();
}
@Test
public void testLocalProperties() {
Properties props = (Properties) this.beanFactory.getBean("myLocalProperties");
assertThat(props.get("foo")).as("Incorrect property value").isNull();
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo(null);
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("bar2");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -283,7 +283,7 @@ public class XmlBeanCollectionTests {
Iterator it = hasMap.getSet().iterator();
assertThat(it.next()).isEqualTo("bar");
assertThat(it.next()).isEqualTo(jenny);
assertThat(it.next()).isNull();
assertThat(it.next()).isEqualTo(null);
}
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -181,7 +181,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
assertThat(beanNames.contains("aliasWithoutId3")).isFalse();
TestBean tb4 = (TestBean) getBeanFactory().getBean(TestBean.class.getName() + "#0");
assertThat(tb4.getName()).isNull();
assertThat(tb4.getName()).isEqualTo(null);
Map drs = getListableBeanFactory().getBeansOfType(DummyReferencer.class, false, false);
assertThat(drs.size()).isEqualTo(5);
@@ -16,11 +16,9 @@
package org.springframework.beans.factory
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Test
import kotlin.reflect.full.createInstance
/**
* Mock object based tests for ListableBeanFactory Kotlin extensions
@@ -79,12 +77,10 @@ class ListableBeanFactoryExtensionsTests {
verify { lbf.getBeansWithAnnotation(Bar::class.java) }
}
@Suppress("UNUSED_VARIABLE")
@Test
fun `findAnnotationOnBean with String and reified type parameters`() {
val name = "bar"
every { lbf.findAnnotationOnBean(name, Bar::class.java) } returns Bar::class.createInstance()
val annotation: Bar? = lbf.findAnnotationOnBean(name)
lbf.findAnnotationOnBean<Bar>(name)
verify { lbf.findAnnotationOnBean(name, Bar::class.java) }
}
@@ -40,9 +40,8 @@ public class MustBeInitialized implements InitializingBean {
* managed the bean's lifecycle correctly
*/
public void businessMethod() {
if (!this.inited) {
if (!this.inited)
throw new RuntimeException("Factory didn't call afterPropertiesSet() on MustBeInitialized object");
}
}
}
@@ -39,18 +39,12 @@ public class Pet {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Pet pet = (Pet) o;
if (name != null ? !name.equals(pet.name) : pet.name != null) {
return false;
}
if (name != null ? !name.equals(pet.name) : pet.name != null) return false;
return true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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.
@@ -20,6 +20,7 @@ import java.util.function.Supplier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.cache.annotation.AbstractCachingConfiguration;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource;
import org.springframework.cache.jcache.interceptor.JCacheOperationSource;
@@ -45,14 +46,11 @@ public abstract class AbstractJCacheConfiguration extends AbstractCachingConfigu
@Override
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
super.useCachingConfigurer(cachingConfigurerSupplier);
this.exceptionCacheResolver = cachingConfigurerSupplier.adapt(config -> {
if (config instanceof JCacheConfigurer) {
return ((JCacheConfigurer) config).exceptionCacheResolver();
}
return null;
});
protected void useCachingConfigurer(CachingConfigurer config) {
super.useCachingConfigurer(config);
if (config instanceof JCacheConfigurer) {
this.exceptionCacheResolver = ((JCacheConfigurer) config)::exceptionCacheResolver;
}
}
@Bean(name = "jCacheOperationSource")
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@ import org.springframework.lang.Nullable;
* <p>To be implemented by classes annotated with
* {@link org.springframework.cache.annotation.EnableCaching} that wish
* or need to specify explicitly how exception caches are resolved for
* annotation-driven cache management.
* annotation-driven cache management. Consider extending {@link JCacheConfigurerSupport},
* which provides a stub implementation of all interface methods.
*
* <p>See {@link org.springframework.cache.annotation.EnableCaching} for
* general examples and context; see {@link #exceptionCacheResolver()} for
@@ -35,6 +36,7 @@ import org.springframework.lang.Nullable;
* @author Stephane Nicoll
* @since 4.1
* @see CachingConfigurer
* @see JCacheConfigurerSupport
* @see org.springframework.cache.annotation.EnableCaching
*/
public interface JCacheConfigurer extends CachingConfigurer {
@@ -58,8 +60,6 @@ public interface JCacheConfigurer extends CachingConfigurer {
* See {@link org.springframework.cache.annotation.EnableCaching} for more complete examples.
*/
@Nullable
default CacheResolver exceptionCacheResolver() {
return null;
}
CacheResolver exceptionCacheResolver();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ public abstract class AbstractFallbackJCacheOperationSource implements JCacheOpe
@Nullable
private JCacheOperation<?> computeCacheOperation(Method method, @Nullable Class<?> targetClass) {
// Don't allow non-public methods, as configured.
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -171,7 +171,6 @@ public class WorkManagerTaskExecutor extends JndiLocatorSupport
}
}
@Deprecated
@Override
public void execute(Runnable task, long startTimeout) {
execute(task);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,6 @@ import org.springframework.lang.Nullable;
* Subclass of Quartz's {@link JobStoreCMT} class that delegates to a Spring-managed
* {@link DataSource} instead of using a Quartz-managed JDBC connection pool.
* This JobStore will be used if SchedulerFactoryBean's "dataSource" property is set.
* You may also configure it explicitly, possibly as a custom subclass of this
* {@code LocalDataSourceJobStore} or as an equivalent {@code JobStoreCMT} variant.
*
* <p>Supports both transactional and non-transactional DataSource access.
* With a non-XA DataSource and local Spring transactions, a single DataSource
@@ -60,8 +58,6 @@ import org.springframework.lang.Nullable;
* @since 1.1
* @see SchedulerFactoryBean#setDataSource
* @see SchedulerFactoryBean#setNonTransactionalDataSource
* @see SchedulerFactoryBean#getConfigTimeDataSource()
* @see SchedulerFactoryBean#getConfigTimeNonTransactionalDataSource()
* @see org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection
* @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
*/
@@ -310,11 +310,9 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
/**
* Set the default {@link DataSource} to be used by the Scheduler.
* If set, this will override corresponding settings in Quartz properties.
* <p>Note: If this is set, the Quartz settings should not define
* a job store "dataSource" to avoid meaningless double configuration.
* Also, do not define a "org.quartz.jobStore.class" property at all.
* (You may explicitly define Spring's {@link LocalDataSourceJobStore}
* but that's the default when using this method anyway.)
* <p>A Spring-specific subclass of Quartz' JobStoreCMT will be used.
* It is therefore strongly recommended to perform all operations on
* the Scheduler within Spring-managed (or plain JTA) transactions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -76,7 +76,6 @@ public class SimpleThreadPoolTaskExecutor extends SimpleThreadPool
}
}
@Deprecated
@Override
public void execute(Runnable task, long startTimeout) {
execute(task);
@@ -178,11 +178,14 @@ public class CaffeineCacheManagerTests {
@Test
public void cacheLoaderUseLoadingCache() {
CaffeineCacheManager cm = new CaffeineCacheManager("c1");
cm.setCacheLoader(key -> {
if ("ping".equals(key)) {
return "pong";
cm.setCacheLoader(new CacheLoader<Object, Object>() {
@Override
public Object load(Object key) throws Exception {
if ("ping".equals(key)) {
return "pong";
}
throw new IllegalArgumentException("I only know ping");
}
throw new IllegalArgumentException("I only know ping");
});
Cache cache1 = cm.getCache("c1");
Cache.ValueWrapper value = cache1.get("ping");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -106,7 +106,7 @@ class CaffeineCacheTests extends AbstractValueAdaptingCacheTests<CaffeineCache>
Cache.ValueWrapper wrapper = cache.putIfAbsent(key, "anotherValue");
// A value is set but is 'null'
assertThat(wrapper).isNotNull();
assertThat(wrapper.get()).isNull();
assertThat(wrapper.get()).isEqualTo(null);
// not changed
assertThat(cache.get(key).get()).isEqualTo(value);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
@@ -104,7 +104,7 @@ public class JCacheEhCacheAnnotationTests extends AbstractCacheAnnotationTests {
@Configuration
@EnableCaching
static class EnableCachingConfig implements CachingConfigurer {
static class EnableCachingConfig extends CachingConfigurerSupport {
@Autowired
CachingProvider cachingProvider;
@@ -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.
@@ -180,7 +180,7 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@Configuration
@EnableCaching
public static class EmptyConfigSupportConfig implements JCacheConfigurer {
public static class EmptyConfigSupportConfig extends JCacheConfigurerSupport {
@Bean
public CacheManager cm() {
return new NoOpCacheManager();
@@ -190,7 +190,7 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@Configuration
@EnableCaching
static class FullCachingConfigSupport implements JCacheConfigurer {
static class FullCachingConfigSupport extends JCacheConfigurerSupport {
@Override
@Bean
@@ -220,7 +220,7 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@Configuration
@EnableCaching
static class NoExceptionCacheResolverConfig implements JCacheConfigurer {
static class NoExceptionCacheResolverConfig extends JCacheConfigurerSupport {
@Override
@Bean
@@ -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,7 +34,7 @@ import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.cache.jcache.config.JCacheConfigurer;
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -141,7 +141,7 @@ public class JCacheErrorHandlerTests {
@Configuration
@EnableCaching
static class Config implements JCacheConfigurer {
static class Config extends JCacheConfigurerSupport {
@Bean
@Override
@@ -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,7 +34,7 @@ import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.cache.jcache.config.JCacheConfigurer;
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -97,7 +97,7 @@ public class JCacheKeyGeneratorTests {
@Configuration
@EnableCaching
static class Config implements JCacheConfigurer {
static class Config extends JCacheConfigurerSupport {
@Bean
@Override
@@ -151,7 +151,7 @@ public class JCacheKeyGeneratorTests {
@Override
public Object generate(Object target, Method method, Object... params) {
assertThat(Arrays.equals(expectedParams, params)).as("Unexpected parameters: expected: "
+ Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params)).isTrue();
+ Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params)).isTrue();
return new SimpleKey(params);
}
}
@@ -182,9 +182,12 @@ public class JavaMailSenderTests {
final List<Message> messages = new ArrayList<>();
MimeMessagePreparator preparator = mimeMessage -> {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("you@mail.org"));
messages.add(mimeMessage);
MimeMessagePreparator preparator = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws MessagingException {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("you@mail.org"));
messages.add(mimeMessage);
}
};
sender.send(preparator);
@@ -205,13 +208,19 @@ public class JavaMailSenderTests {
final List<Message> messages = new ArrayList<>();
MimeMessagePreparator preparator1 = mimeMessage -> {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("he@mail.org"));
messages.add(mimeMessage);
MimeMessagePreparator preparator1 = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws MessagingException {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("he@mail.org"));
messages.add(mimeMessage);
}
};
MimeMessagePreparator preparator2 = mimeMessage -> {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("she@mail.org"));
messages.add(mimeMessage);
MimeMessagePreparator preparator2 = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws MessagingException {
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("she@mail.org"));
messages.add(mimeMessage);
}
};
sender.send(preparator1, preparator2);
@@ -314,7 +323,12 @@ public class JavaMailSenderTests {
@Test
public void javaMailSenderWithParseExceptionOnMimeMessagePreparator() {
MockJavaMailSender sender = new MockJavaMailSender();
MimeMessagePreparator preparator = mimeMessage -> mimeMessage.setFrom(new InternetAddress(""));
MimeMessagePreparator preparator = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws MessagingException {
mimeMessage.setFrom(new InternetAddress(""));
}
};
try {
sender.send(preparator);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,9 @@
package org.springframework.cache.annotation;
import java.util.List;
import java.util.function.Function;
import java.util.Collection;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
@@ -33,7 +30,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.function.SingletonSupplier;
/**
* Abstract base {@code @Configuration} class providing common structure
@@ -67,67 +63,36 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableCaching = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableCaching.class.getName()));
importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false));
if (this.enableCaching == null) {
throw new IllegalArgumentException(
"@EnableCaching is not present on importing class " + importMetadata.getClassName());
}
}
@Autowired
void setConfigurers(ObjectProvider<CachingConfigurer> configurers) {
Supplier<CachingConfigurer> configurer = () -> {
List<CachingConfigurer> candidates = configurers.stream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(candidates)) {
return null;
}
if (candidates.size() > 1) {
throw new IllegalStateException(candidates.size() + " implementations of " +
"CachingConfigurer were found when only 1 was expected. " +
"Refactor the configuration such that CachingConfigurer is " +
"implemented only once or not at all.");
}
return candidates.get(0);
};
useCachingConfigurer(new CachingConfigurerSupplier(configurer));
@Autowired(required = false)
void setConfigurers(Collection<CachingConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException(configurers.size() + " implementations of " +
"CachingConfigurer were found when only 1 was expected. " +
"Refactor the configuration such that CachingConfigurer is " +
"implemented only once or not at all.");
}
CachingConfigurer configurer = configurers.iterator().next();
useCachingConfigurer(configurer);
}
/**
* Extract the configuration from the nominated {@link CachingConfigurer}.
*/
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
this.cacheManager = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheManager);
this.cacheResolver = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheResolver);
this.keyGenerator = cachingConfigurerSupplier.adapt(CachingConfigurer::keyGenerator);
this.errorHandler = cachingConfigurerSupplier.adapt(CachingConfigurer::errorHandler);
}
protected static class CachingConfigurerSupplier {
private final Supplier<CachingConfigurer> supplier;
public CachingConfigurerSupplier(Supplier<CachingConfigurer> supplier) {
this.supplier = SingletonSupplier.of(supplier);
}
/**
* Adapt the {@link CachingConfigurer} supplier to another supplier
* provided by the specified mapping function. If the underlying
* {@link CachingConfigurer} is {@code null}, {@code null} is returned
* and the mapping function is not invoked.
* @param provider the provider to use to adapt the supplier
* @param <T> the type of the supplier
* @return another supplier mapped by the specified function
*/
@Nullable
public <T> Supplier<T> adapt(Function<CachingConfigurer, T> provider) {
return () -> {
CachingConfigurer cachingConfigurer = this.supplier.get();
return (cachingConfigurer != null ? provider.apply(cachingConfigurer) : null);
};
}
protected void useCachingConfigurer(CachingConfigurer config) {
this.cacheManager = config::cacheManager;
this.cacheResolver = config::cacheResolver;
this.keyGenerator = config::keyGenerator;
this.errorHandler = config::errorHandler;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@ import org.springframework.lang.Nullable;
* Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
* Configuration} classes annotated with @{@link EnableCaching} that wish or need to
* specify explicitly how caches are resolved and how keys are generated for annotation-driven
* cache management.
* cache management. Consider extending {@link CachingConfigurerSupport}, which provides a
* stub implementation of all interface methods.
*
* <p>See @{@link EnableCaching} for general examples and context; see
* {@link #cacheManager()}, {@link #cacheResolver()} and {@link #keyGenerator()}
@@ -36,6 +37,7 @@ import org.springframework.lang.Nullable;
* @author Stephane Nicoll
* @since 3.1
* @see EnableCaching
* @see CachingConfigurerSupport
*/
public interface CachingConfigurer {
@@ -62,9 +64,7 @@ public interface CachingConfigurer {
* See @{@link EnableCaching} for more complete examples.
*/
@Nullable
default CacheManager cacheManager() {
return null;
}
CacheManager cacheManager();
/**
* Return the {@link CacheResolver} bean to use to resolve regular caches for
@@ -89,9 +89,7 @@ public interface CachingConfigurer {
* See {@link EnableCaching} for more complete examples.
*/
@Nullable
default CacheResolver cacheResolver() {
return null;
}
CacheResolver cacheResolver();
/**
* Return the key generator bean to use for annotation-driven cache management.
@@ -112,9 +110,7 @@ public interface CachingConfigurer {
* See @{@link EnableCaching} for more complete examples.
*/
@Nullable
default KeyGenerator keyGenerator() {
return null;
}
KeyGenerator keyGenerator();
/**
* Return the {@link CacheErrorHandler} to use to handle cache-related errors.
@@ -137,8 +133,6 @@ public interface CachingConfigurer {
* See @{@link EnableCaching} for more complete examples.
*/
@Nullable
default CacheErrorHandler errorHandler() {
return null;
}
CacheErrorHandler errorHandler();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
@Nullable
private Collection<CacheOperation> computeCacheOperations(Method method, @Nullable Class<?> targetClass) {
// Don't allow non-public methods, as configured.
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
@@ -1,105 +0,0 @@
/*
* Copyright 2002-2022 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.cache.interceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cache.Cache;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* A {@link CacheErrorHandler} implementation that logs error message. Can be
* used when underlying cache errors should be ignored.
*
* @author Adam Ostrožlík
* @author Stephane Nicoll
* @since 5.3.16
*/
public class LoggingCacheErrorHandler implements CacheErrorHandler {
private final Log logger;
private final boolean logStacktrace;
/**
* Create an instance with the {@link Log logger} to use.
* @param logger the logger to use
* @param logStacktrace whether to log stack trace
*/
public LoggingCacheErrorHandler(Log logger, boolean logStacktrace) {
Assert.notNull(logger, "Logger must not be null");
this.logger = logger;
this.logStacktrace = logStacktrace;
}
/**
* Create an instance that does not log stack traces.
*/
public LoggingCacheErrorHandler() {
this(LogFactory.getLog(LoggingCacheErrorHandler.class), false);
}
@Override
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
logCacheError(logger,
createMessage(cache, "failed to get entry with key '" + key + "'"),
exception);
}
@Override
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, @Nullable Object value) {
logCacheError(logger,
createMessage(cache, "failed to put entry with key '" + key + "'"),
exception);
}
@Override
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
logCacheError(logger,
createMessage(cache, "failed to evict entry with key '" + key + "'"),
exception);
}
@Override
public void handleCacheClearError(RuntimeException exception, Cache cache) {
logCacheError(logger, createMessage(cache, "failed to clear entries"), exception);
}
/**
* Log the specified message.
* @param logger the logger
* @param message the message
* @param ex the exception
*/
protected void logCacheError(Log logger, String message, RuntimeException ex) {
if (this.logStacktrace) {
logger.warn(message, ex);
}
else {
logger.warn(message);
}
}
private String createMessage(Cache cache, String reason) {
return String.format("Cache '%s' %s", cache.getName(), reason);
}
}
@@ -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.
@@ -47,10 +47,9 @@ import org.springframework.util.StringUtils;
*
* <p>If the annotation's value doesn't indicate a bean name, an appropriate
* name will be built based on the short name of the class (with the first
* letter lower-cased), unless the two first letters are uppercase. For example:
* letter lower-cased). For example:
*
* <pre class="code">com.xyz.FooServiceImpl -&gt; fooServiceImpl</pre>
* <pre class="code">com.xyz.URLFooServiceImpl -&gt; URLFooServiceImpl</pre>
*
* @author Juergen Hoeller
* @author Mark Fisher
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -282,7 +282,7 @@ public abstract class AnnotationConfigUtils {
@Nullable
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName));
return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
}
static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata,
@@ -298,10 +298,10 @@ public abstract class AnnotationConfigUtils {
Set<AnnotationAttributes> result = new LinkedHashSet<>();
// Direct annotation present?
addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName));
addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));
// Container annotation present?
Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName);
Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName, false);
if (container != null && container.containsKey("value")) {
for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container.get("value")) {
addAttributesIfNotNull(result, containedAttributes);
@@ -1331,16 +1331,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
}
@Override
@Nullable
public <A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException {
assertBeanFactoryActive();
return getBeanFactory().findAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit);
}
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,12 +24,10 @@ import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.ConfigurablePropertyResolver;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
import org.springframework.core.env.PropertySourcesPropertyResolver;
@@ -59,7 +57,6 @@ import org.springframework.util.StringValueResolver;
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.1
* @see org.springframework.core.env.ConfigurableEnvironment
* @see org.springframework.beans.factory.config.PlaceholderConfigurerSupport
@@ -132,25 +129,12 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
PropertyResolver propertyResolver = this.environment;
// If the ignoreUnresolvablePlaceholders flag is set to true, we have to create a
// local PropertyResolver to enforce that setting, since the Environment is most
// likely not configured with ignoreUnresolvablePlaceholders set to true.
// See https://github.com/spring-projects/spring-framework/issues/27947
if (this.ignoreUnresolvablePlaceholders && (this.environment instanceof ConfigurableEnvironment)) {
ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) this.environment;
PropertySourcesPropertyResolver resolver =
new PropertySourcesPropertyResolver(configurableEnvironment.getPropertySources());
resolver.setIgnoreUnresolvableNestedPlaceholders(true);
propertyResolver = resolver;
}
PropertyResolver propertyResolverToUse = propertyResolver;
this.propertySources.addLast(
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
@Nullable
public String getProperty(String key) {
return propertyResolverToUse.getProperty(key);
return this.source.getProperty(key);
}
}
);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +16,11 @@
package org.springframework.scheduling.annotation;
import java.util.List;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
@@ -31,7 +28,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.function.SingletonSupplier;
/**
* Abstract base {@code Configuration} class providing common structure for enabling
@@ -59,7 +55,7 @@ public abstract class AbstractAsyncConfiguration implements ImportAware {
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName()));
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
@@ -69,27 +65,17 @@ public abstract class AbstractAsyncConfiguration implements ImportAware {
/**
* Collect any {@link AsyncConfigurer} beans through autowiring.
*/
@Autowired
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
List<AsyncConfigurer> candidates = configurers.stream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(candidates)) {
return null;
}
if (candidates.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
return candidates.get(0);
});
this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
}
private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
return () -> {
AsyncConfigurer configurer = supplier.get();
return (configurer != null ? provider.apply(configurer) : null);
};
@Autowired(required = false)
void setConfigurers(Collection<AsyncConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
AsyncConfigurer configurer = configurers.iterator().next();
this.executor = configurer::getAsyncExecutor;
this.exceptionHandler = configurer::getAsyncUncaughtExceptionHandler;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 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.
@@ -28,6 +28,11 @@ import org.springframework.lang.Nullable;
* {@link AsyncUncaughtExceptionHandler} instance used to process exception thrown from
* async method with {@code void} return type.
*
* <p>Consider using {@link AsyncConfigurerSupport} providing default implementations for
* both methods if only one element needs to be customized. Furthermore, backward compatibility
* of this interface will be insured in case new customization options are introduced
* in the future.
*
* <p>See @{@link EnableAsync} for usage examples.
*
* @author Chris Beams
@@ -35,6 +40,7 @@ import org.springframework.lang.Nullable;
* @since 3.1
* @see AbstractAsyncConfiguration
* @see EnableAsync
* @see AsyncConfigurerSupport
*/
public interface AsyncConfigurer {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -147,7 +147,6 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche
this.adaptedExecutor.execute(task);
}
@Deprecated
@Override
public void execute(Runnable task, long startTimeout) {
this.adaptedExecutor.execute(task, startTimeout);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,9 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
/**
@@ -63,7 +65,7 @@ import org.springframework.lang.Nullable;
*/
@SuppressWarnings("serial")
public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport
implements FactoryBean<ExecutorService> {
implements FactoryBean<ExecutorService>, InitializingBean, DisposableBean {
private int corePoolSize = 1;
@@ -73,8 +75,6 @@ public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport
private boolean allowCoreThreadTimeOut = false;
private boolean prestartAllCoreThreads = false;
private int queueCapacity = Integer.MAX_VALUE;
private boolean exposeUnconfigurableExecutor = false;
@@ -118,16 +118,6 @@ public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
}
/**
* Specify whether to start all core threads, causing them to idly wait for work.
* <p>Default is "false".
* @since 5.3.14
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
*/
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
this.prestartAllCoreThreads = prestartAllCoreThreads;
}
/**
* Set the capacity for the ThreadPoolExecutor's BlockingQueue.
* Default is {@code Integer.MAX_VALUE}.
@@ -163,9 +153,6 @@ public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport
if (this.allowCoreThreadTimeOut) {
executor.allowCoreThreadTimeOut(true);
}
if (this.prestartAllCoreThreads) {
executor.prestartAllCoreThreads();
}
// Wrap executor with an unconfigurable decorator.
this.exposedExecutor = (this.exposeUnconfigurableExecutor ?
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,8 +94,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
private boolean allowCoreThreadTimeOut = false;
private boolean prestartAllCoreThreads = false;
@Nullable
private TaskDecorator taskDecorator;
@@ -199,16 +197,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
}
/**
* Specify whether to start all core threads, causing them to idly wait for work.
* <p>Default is "false".
* @since 5.3.14
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
*/
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
this.prestartAllCoreThreads = prestartAllCoreThreads;
}
/**
* Specify a custom {@link TaskDecorator} to be applied to any {@link Runnable}
* about to be executed.
@@ -268,9 +256,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
if (this.allowCoreThreadTimeOut) {
executor.allowCoreThreadTimeOut(true);
}
if (this.prestartAllCoreThreads) {
executor.prestartAllCoreThreads();
}
this.threadPoolExecutor = executor;
return executor;
@@ -340,7 +325,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
}
}
@Deprecated
@Override
public void execute(Runnable task, long startTimeout) {
execute(task);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -282,7 +282,6 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
}
}
@Deprecated
@Override
public void execute(Runnable task, long startTimeout) {
execute(task);
@@ -18,7 +18,6 @@ package org.springframework.scheduling.support;
import java.time.DateTimeException;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.ValueRange;
import java.util.function.BiFunction;
@@ -169,25 +168,22 @@ abstract class CronField {
* day-of-month, month, day-of-week.
*/
protected enum Type {
NANO(ChronoField.NANO_OF_SECOND, ChronoUnit.SECONDS),
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoUnit.MINUTES, ChronoField.NANO_OF_SECOND),
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoUnit.HOURS, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
HOUR(ChronoField.HOUR_OF_DAY, ChronoUnit.DAYS, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoUnit.MONTHS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
MONTH(ChronoField.MONTH_OF_YEAR, ChronoUnit.YEARS, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoUnit.WEEKS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
NANO(ChronoField.NANO_OF_SECOND),
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
HOUR(ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
MONTH(ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
private final ChronoField field;
private final ChronoUnit higherOrder;
private final ChronoField[] lowerOrders;
Type(ChronoField field, ChronoUnit higherOrder, ChronoField... lowerOrders) {
Type(ChronoField field, ChronoField... lowerOrders) {
this.field = field;
this.higherOrder = higherOrder;
this.lowerOrders = lowerOrders;
}
@@ -270,9 +266,10 @@ abstract class CronField {
* @return the rolled forward temporal
*/
public <T extends Temporal & Comparable<? super T>> T rollForward(T temporal) {
T result = this.higherOrder.addTo(temporal, 1);
ValueRange range = result.range(this.field);
return this.field.adjustInto(result, range.getMinimum());
int current = get(temporal);
ValueRange range = temporal.range(this.field);
long amount = range.getMaximum() - current + 1;
return this.field.getBaseUnit().addTo(temporal, amount);
}
/**
@@ -251,46 +251,43 @@ final class QuartzCronField extends CronField {
private static TemporalAdjuster weekdayNearestTo(int dayOfMonth) {
return temporal -> {
int current = Type.DAY_OF_MONTH.get(temporal);
DayOfWeek dayOfWeek = DayOfWeek.from(temporal);
int dayOfWeek = temporal.get(ChronoField.DAY_OF_WEEK);
if ((current == dayOfMonth && isWeekday(dayOfWeek)) || // dayOfMonth is a weekday
(dayOfWeek == DayOfWeek.FRIDAY && current == dayOfMonth - 1) || // dayOfMonth is a Saturday, so Friday before
(dayOfWeek == DayOfWeek.MONDAY && current == dayOfMonth + 1) || // dayOfMonth is a Sunday, so Monday after
(dayOfWeek == DayOfWeek.MONDAY && dayOfMonth == 1 && current == 3)) { // dayOfMonth is Saturday 1st, so Monday 3rd
if ((current == dayOfMonth && dayOfWeek < 6) || // dayOfMonth is a weekday
(dayOfWeek == 5 && current == dayOfMonth - 1) || // dayOfMonth is a Saturday, so Friday before
(dayOfWeek == 1 && current == dayOfMonth + 1) || // dayOfMonth is a Sunday, so Monday after
(dayOfWeek == 1 && dayOfMonth == 1 && current == 3)) { // dayOfMonth is the 1st, so Monday 3rd
return temporal;
}
int count = 0;
while (count++ < CronExpression.MAX_ATTEMPTS) {
temporal = Type.DAY_OF_MONTH.elapseUntil(cast(temporal), dayOfMonth);
temporal = atMidnight().adjustInto(temporal);
current = Type.DAY_OF_MONTH.get(temporal);
if (current == dayOfMonth) {
dayOfWeek = DayOfWeek.from(temporal);
dayOfWeek = temporal.get(ChronoField.DAY_OF_WEEK);
if (dayOfWeek == DayOfWeek.SATURDAY) {
if (dayOfWeek == 6) { // Saturday
if (dayOfMonth != 1) {
temporal = temporal.minus(1, ChronoUnit.DAYS);
return temporal.minus(1, ChronoUnit.DAYS);
}
else {
// exception for "1W" fields: execute on next Monday
temporal = temporal.plus(2, ChronoUnit.DAYS);
// exception for "1W" fields: execute on nearest Monday
return temporal.plus(2, ChronoUnit.DAYS);
}
}
else if (dayOfWeek == DayOfWeek.SUNDAY) {
temporal = temporal.plus(1, ChronoUnit.DAYS);
else if (dayOfWeek == 7) { // Sunday
return temporal.plus(1, ChronoUnit.DAYS);
}
else {
return temporal;
}
return atMidnight().adjustInto(temporal);
}
else {
temporal = Type.DAY_OF_MONTH.elapseUntil(cast(temporal), dayOfMonth);
current = Type.DAY_OF_MONTH.get(temporal);
}
}
return null;
};
}
private static boolean isWeekday(DayOfWeek dayOfWeek) {
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
}
/**
* Return a temporal adjuster that finds the last of the given doy-of-week
* in a month.

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