mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9b6e94e00 |
@@ -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
|
||||
+1
-1
@@ -8,4 +8,4 @@ wiki page.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please see https://spring.io/security-policy.
|
||||
Please see https://pivotal.io/security.
|
||||
|
||||
+84
-99
@@ -1,17 +1,17 @@
|
||||
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.asciidoctor.jvm.convert' version '3.3.2'
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
|
||||
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
|
||||
id 'io.spring.nohttp' version '0.0.5.RELEASE'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.5.21' apply false
|
||||
id 'org.jetbrains.dokka' version '0.10.1' apply false
|
||||
id 'org.asciidoctor.jvm.convert' version '3.1.0'
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.1.0'
|
||||
id 'de.undercouch.download' version '4.1.1'
|
||||
id "io.freefair.aspectj" version '5.1.1' apply false
|
||||
id "com.github.ben-manes.versions" version '0.28.0'
|
||||
id "com.github.johnrengelman.shadow" version "6.1.0" apply false
|
||||
id "me.champeau.jmh" version "0.6.4" apply false
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.21" apply false
|
||||
id "org.unbroken-dome.xjc" version '2.0.0' apply false
|
||||
id "com.github.ben-manes.versions" version '0.39.0'
|
||||
id "com.github.johnrengelman.shadow" version '7.0.0' apply false
|
||||
id 'de.undercouch.download' version '4.1.2'
|
||||
id "me.champeau.jmh" version "0.6.6" apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -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.4"
|
||||
mavenBom "io.netty:netty-bom:4.1.65.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.9"
|
||||
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.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.eclipse.jetty:jetty-bom:9.4.43.v20210629"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.21"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.1"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.1"
|
||||
mavenBom "org.junit:junit-bom:5.7.2"
|
||||
}
|
||||
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.30"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
@@ -56,7 +56,7 @@ configure(allprojects) { project ->
|
||||
entry 'aspectjtools'
|
||||
entry 'aspectjweaver'
|
||||
}
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') {
|
||||
entry 'groovy'
|
||||
entry 'groovy-jsr223'
|
||||
entry 'groovy-templates' // requires findbugs for warning-free compilation
|
||||
@@ -67,23 +67,22 @@ 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.projectreactor.tools:blockhound:1.0.6.RELEASE"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.0.13"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.4.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.7"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.17.3"
|
||||
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.17") {
|
||||
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.10"
|
||||
dependency("org.codehaus.jettison:jettison:1.3.8") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
@@ -92,14 +91,14 @@ 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.1"
|
||||
dependency "com.github.librepdf:openpdf:1.3.26"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "com.rometools:rome:1.15.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
dependency "io.vavr:vavr:0.10.3"
|
||||
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
|
||||
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
|
||||
entry 'activemq-broker'
|
||||
@@ -123,48 +122,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.webjars:webjars-locator-core:0.48"
|
||||
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.47"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.50') {
|
||||
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.50') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.8.Final') {
|
||||
entry 'undertow-core'
|
||||
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"
|
||||
}
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_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"
|
||||
|
||||
@@ -188,28 +187,27 @@ configure(allprojects) { project ->
|
||||
exclude group: "junit", name: "junit"
|
||||
}
|
||||
dependency "org.testng:testng:7.4.0"
|
||||
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.20.2"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
|
||||
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: '3.11.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.11.0"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.51.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.51.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -217,7 +215,7 @@ configure(allprojects) { project ->
|
||||
exclude group: "io.netty", name: "netty"
|
||||
}
|
||||
dependency "org.skyscreamer:jsonassert:1.5.0"
|
||||
dependency "com.jayway.jsonpath:json-path:2.6.0"
|
||||
dependency "com.jayway.jsonpath:json-path:2.5.0"
|
||||
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
|
||||
|
||||
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
|
||||
@@ -237,8 +235,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"
|
||||
@@ -314,8 +312,6 @@ configure([rootProject] + javaProjects) { project ->
|
||||
|
||||
pluginManager.withPlugin("kotlin") {
|
||||
apply plugin: "org.jetbrains.dokka"
|
||||
apply from: "${rootDir}/gradle/docs-dokka.gradle"
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
languageVersion = "1.3"
|
||||
@@ -340,36 +336,35 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "9.3"
|
||||
toolVersion = "8.44"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-params")
|
||||
testImplementation("org.junit.platform:junit-platform-suite-api")
|
||||
testImplementation("org.mockito:mockito-core")
|
||||
testImplementation("org.mockito:mockito-junit-jupiter")
|
||||
testImplementation("io.mockk:mockk")
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
testCompile("org.junit.jupiter:junit-jupiter-api")
|
||||
testCompile("org.junit.jupiter:junit-jupiter-params")
|
||||
testCompile("org.mockito:mockito-core")
|
||||
testCompile("org.mockito:mockito-junit-jupiter")
|
||||
testCompile("io.mockk:mockk")
|
||||
testCompile("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.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")
|
||||
testRuntime("org.junit.platform:junit-platform-launcher")
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine")
|
||||
testRuntime("org.apache.logging.log4j:log4j-core")
|
||||
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
|
||||
testRuntime("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.15")
|
||||
}
|
||||
|
||||
ext.javadocLinks = [
|
||||
"https://docs.oracle.com/javase/8/docs/api/",
|
||||
"https://docs.oracle.com/javaee/7/api/",
|
||||
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
|
||||
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
|
||||
"https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
|
||||
"https://glassfish.java.net/nonav/docs/v3/api/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
|
||||
"https://tiles.apache.org/tiles-request/apidocs/",
|
||||
@@ -383,18 +378,7 @@ 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
|
||||
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
|
||||
// "https://junit.org/junit5/docs/5.8.2/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://junit.org/junit5/docs/5.7.2/api/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
@@ -405,6 +389,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'
|
||||
|
||||
@@ -8,7 +8,8 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
|
||||
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8"
|
||||
implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
|
||||
+2
-4
@@ -32,7 +32,6 @@ import org.gradle.api.tasks.compile.JavaCompile;
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Sam Brannen
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class CompilerConventionsPlugin implements Plugin<Project> {
|
||||
|
||||
@@ -44,8 +43,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
|
||||
List<String> commonCompilerArgs = Arrays.asList(
|
||||
"-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann",
|
||||
"-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides",
|
||||
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options",
|
||||
"-parameters"
|
||||
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options"
|
||||
);
|
||||
COMPILER_ARGS = new ArrayList<>();
|
||||
COMPILER_ARGS.addAll(commonCompilerArgs);
|
||||
@@ -56,7 +54,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
|
||||
TEST_COMPILER_ARGS = new ArrayList<>();
|
||||
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
|
||||
TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes",
|
||||
"-Xlint:-deprecation", "-Xlint:-unchecked"));
|
||||
"-Xlint:-deprecation", "-Xlint:-unchecked", "-parameters"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-9
@@ -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.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.build.optional;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.attributes.Usage;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
@@ -29,7 +28,7 @@ import org.gradle.plugins.ide.eclipse.model.EclipseModel;
|
||||
/**
|
||||
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
|
||||
* {@code optional} configuration. The {@code optional} configuration is part of the
|
||||
* project's compile and runtime classpaths but does not affect the classpath of
|
||||
* project's compile and runtime classpath's but does not affect the classpath of
|
||||
* dependent projects.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
@@ -44,16 +43,22 @@ public class OptionalDependenciesPlugin implements Plugin<Project> {
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
Configuration optional = project.getConfigurations().create("optional");
|
||||
optional.setCanBeConsumed(false);
|
||||
optional.setCanBeResolved(false);
|
||||
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
|
||||
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
|
||||
.getSourceSets();
|
||||
SourceSetContainer sourceSets = project.getConvention()
|
||||
.getPlugin(JavaPluginConvention.class).getSourceSets();
|
||||
sourceSets.all((sourceSet) -> {
|
||||
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
|
||||
project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional);
|
||||
sourceSet.setCompileClasspath(
|
||||
sourceSet.getCompileClasspath().plus(optional));
|
||||
sourceSet.setRuntimeClasspath(
|
||||
sourceSet.getRuntimeClasspath().plus(optional));
|
||||
});
|
||||
});
|
||||
project.getPlugins().withType(EclipsePlugin.class, (eclipePlugin) -> {
|
||||
project.getExtensions().getByType(EclipseModel.class)
|
||||
.classpath((classpath) -> {
|
||||
classpath.getPlusConfigurations().add(optional);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ changelog:
|
||||
- title: ":star: New Features"
|
||||
labels:
|
||||
- "type: enhancement"
|
||||
- title: ":lady_beetle: Bug Fixes"
|
||||
- title: ":beetle: Bug Fixes"
|
||||
labels:
|
||||
- "type: bug"
|
||||
- "type: regression"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220302
|
||||
FROM ubuntu:focal-20210119
|
||||
|
||||
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 JDK15 /opt/openjdk/java15
|
||||
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
|
||||
@@ -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/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u282-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u282b08.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/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.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"
|
||||
java15)
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_linux_hotspot_15.0.2_7.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
|
||||
+1
-1
@@ -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 java15
|
||||
do
|
||||
JDK_URL=$( /get-jdk-url.sh $jdk )
|
||||
mkdir $jdk
|
||||
|
||||
+4
-1
@@ -1,8 +1,11 @@
|
||||
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"
|
||||
artifactory-server: "https://repo.spring.io"
|
||||
branch: "5.3.x"
|
||||
branch: "main"
|
||||
milestone: "5.3.x"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
|
||||
+10
-15
@@ -2,7 +2,7 @@ anchors:
|
||||
git-repo-resource-source: &git-repo-resource-source
|
||||
uri: ((github-repo))
|
||||
username: ((github-username))
|
||||
password: ((github-ci-release-token))
|
||||
password: ((github-password))
|
||||
branch: ((branch))
|
||||
gradle-enterprise-task-params: &gradle-enterprise-task-params
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
@@ -45,12 +45,7 @@ resource_types:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/artifactory-resource
|
||||
tag: 0.0.17
|
||||
- name: github-release
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/github-release-resource
|
||||
tag: 1.5.5
|
||||
tag: 0.0.13
|
||||
- name: github-status-resource
|
||||
type: registry-image
|
||||
source:
|
||||
@@ -124,14 +119,14 @@ resources:
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk11-build
|
||||
- name: repo-status-jdk17-build
|
||||
- name: repo-status-jdk15-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: jdk15-build
|
||||
- name: slack-alert
|
||||
type: slack-notification
|
||||
icon: slack
|
||||
@@ -249,7 +244,7 @@ jobs:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk17-build
|
||||
- name: jdk15-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
@@ -257,7 +252,7 @@ jobs:
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk17-build
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
@@ -270,12 +265,12 @@ jobs:
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk17-build
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk17-build
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: build-pull-requests
|
||||
serial: true
|
||||
@@ -297,7 +292,7 @@ jobs:
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
<<: *build-project-task-params
|
||||
on_success:
|
||||
put: git-pull-request
|
||||
params:
|
||||
@@ -458,7 +453,7 @@ jobs:
|
||||
|
||||
groups:
|
||||
- name: "builds"
|
||||
jobs: ["build", "jdk11-build", "jdk17-build"]
|
||||
jobs: ["build", "jdk11-build", "jdk15-build"]
|
||||
- name: "releases"
|
||||
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
|
||||
- name: "ci-images"
|
||||
|
||||
@@ -29,8 +29,8 @@ fi
|
||||
echo "Staging $stageVersion (next version will be $nextVersion)"
|
||||
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
|
||||
|
||||
git config user.name "Spring Builds" > /dev/null
|
||||
git config user.email "spring-builds@users.noreply.github.com" > /dev/null
|
||||
git config user.name "Spring Buildmaster" > /dev/null
|
||||
git config user.email "buildmaster@springframework.org" > /dev/null
|
||||
git add gradle.properties > /dev/null
|
||||
git commit -m"Release v$stageVersion" > /dev/null
|
||||
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
|
||||
|
||||
@@ -4,7 +4,7 @@ image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/github-changelog-generator
|
||||
tag: '0.0.7'
|
||||
tag: '0.0.6'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=5.3.17
|
||||
version=5.3.9
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
tasks.findByName("dokkaHtmlPartial")?.configure {
|
||||
outputDirectory.set(new File(buildDir, "docs/kdoc"))
|
||||
dokkaSourceSets {
|
||||
configureEach {
|
||||
sourceRoots.setFrom(file("src/main/kotlin"))
|
||||
classpath.from(sourceSets["main"].runtimeClasspath)
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://projectreactor.io/docs/core/release/api/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
-14
@@ -46,9 +46,8 @@ task api(type: Javadoc) {
|
||||
stylesheetFile = file("src/docs/api/stylesheet.css")
|
||||
splitIndex = true
|
||||
links(project.ext.javadocLinks)
|
||||
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
|
||||
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
addStringOption('Xdoclint:none', '-quiet')
|
||||
if(JavaVersion.current().isJava9Compatible()) {
|
||||
addBooleanOption('html5', true)
|
||||
}
|
||||
}
|
||||
@@ -62,13 +61,57 @@ task api(type: Javadoc) {
|
||||
/**
|
||||
* Produce KDoc for all Spring Framework modules in "build/docs/kdoc"
|
||||
*/
|
||||
pluginManager.withPlugin("kotlin") {
|
||||
tasks.dokkaHtmlMultiModule.configure {
|
||||
dependsOn {
|
||||
tasks.getByName("api")
|
||||
dokka {
|
||||
dependsOn {
|
||||
tasks.getByName("api")
|
||||
}
|
||||
|
||||
doFirst {
|
||||
configuration {
|
||||
classpath = moduleProjects.collect { project -> project.jar.outputs.files.getFiles() }.flatten()
|
||||
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
|
||||
|
||||
moduleProjects.findAll {
|
||||
it.pluginManager.hasPlugin("kotlin")
|
||||
}.each { project ->
|
||||
def kotlinDirs = project.sourceSets.main.kotlin.srcDirs.collect()
|
||||
kotlinDirs -= project.sourceSets.main.java.srcDirs
|
||||
kotlinDirs.each { dir ->
|
||||
if (dir.exists()) {
|
||||
sourceRoot {
|
||||
path = dir.path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outputFormat = "html"
|
||||
outputDirectory = "$buildDir/docs/kdoc"
|
||||
|
||||
configuration {
|
||||
moduleName = "spring-framework"
|
||||
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/")
|
||||
packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL()
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://projectreactor.io/docs/core/release/api/")
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")
|
||||
}
|
||||
/*
|
||||
This link causes errors, removing to fix the build.
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
|
||||
}
|
||||
*/
|
||||
externalDocumentationLink {
|
||||
url = new URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/")
|
||||
}
|
||||
moduleName.set("spring-framework")
|
||||
outputDirectory.set(project.file("$buildDir/docs/kdoc"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +139,7 @@ asciidoctorj {
|
||||
icons: 'font',
|
||||
idprefix: '',
|
||||
idseparator: '-',
|
||||
docinfo: 'shared,private-header', // https://docs.asciidoctor.org/asciidoctor/latest/docinfo/
|
||||
docinfo: 'shared',
|
||||
revnumber: project.version,
|
||||
sectanchors: '',
|
||||
sectnums: '',
|
||||
@@ -120,6 +163,9 @@ asciidoctorj {
|
||||
asciidoctor {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations 'asciidoctorExt'
|
||||
attributes([
|
||||
noheader: '' // custom header in docinfo-header.html
|
||||
])
|
||||
sources {
|
||||
include '*.adoc'
|
||||
}
|
||||
@@ -150,7 +196,7 @@ asciidoctorPdf {
|
||||
/**
|
||||
* Zip all docs (API and reference) into a single archive
|
||||
*/
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokka']) {
|
||||
group = "Distribution"
|
||||
description = "Builds -${archiveClassifier} archive containing api and reference " +
|
||||
"for deployment at https://docs.spring.io/spring-framework/docs."
|
||||
@@ -169,7 +215,7 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dok
|
||||
from ("$asciidoctorPdf.outputDir") {
|
||||
into "reference/pdf"
|
||||
}
|
||||
from (dokkaHtmlMultiModule.outputDirectory) {
|
||||
from (dokka) {
|
||||
into "kdoc-api"
|
||||
}
|
||||
}
|
||||
@@ -226,11 +272,11 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
|
||||
expand(copyright: new Date().format("yyyy"), version: project.version)
|
||||
}
|
||||
|
||||
from(zipTree(docsZip.archiveFile)) {
|
||||
from(zipTree(docsZip.archivePath)) {
|
||||
into "${baseDir}/docs"
|
||||
}
|
||||
|
||||
from(zipTree(schemaZip.archiveFile)) {
|
||||
from(zipTree(schemaZip.archivePath)) {
|
||||
into "${baseDir}/schema"
|
||||
}
|
||||
|
||||
|
||||
+49
-27
@@ -1,7 +1,7 @@
|
||||
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
|
||||
import org.gradle.plugins.ide.eclipse.model.SourceFolder
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: "eclipse"
|
||||
|
||||
eclipse.jdt {
|
||||
sourceCompatibility = 1.8
|
||||
@@ -18,45 +18,40 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
if (matcher) {
|
||||
def projectName = matcher[0][1]
|
||||
def path = "/${projectName}"
|
||||
if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
|
||||
def recursiveDependency = entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')
|
||||
// Avoid recursive dependency on current project.
|
||||
if (!recursiveDependency) {
|
||||
classpath.entries.add(new ProjectDependency(path))
|
||||
}
|
||||
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
|
||||
def dependency = new ProjectDependency(path)
|
||||
dependency.exported = true
|
||||
classpath.entries.add(dependency)
|
||||
}
|
||||
classpath.entries.remove(entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any remaining direct depencencies on JARs in the build/libs folder
|
||||
// except Spring's spring-cglib-repack and spring-objenesis-repack JARs.
|
||||
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
|
||||
}
|
||||
|
||||
// Use separate main/test outputs (prevents WTP from packaging test classes)
|
||||
eclipse.classpath.defaultOutputDir = file(project.name + '/bin/eclipse')
|
||||
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
|
||||
eclipse.classpath.file.beforeMerged { classpath ->
|
||||
classpath.entries.findAll{ it instanceof SourceFolder }.each {
|
||||
if (it.output.startsWith('bin/')) {
|
||||
if (it.output.startsWith("bin/")) {
|
||||
it.output = null
|
||||
}
|
||||
}
|
||||
}
|
||||
eclipse.classpath.file.whenMerged {
|
||||
entries.findAll{ it instanceof SourceFolder }.each {
|
||||
it.output = 'bin/' + it.path.split('/')[1]
|
||||
eclipse.classpath.file.whenMerged { classpath ->
|
||||
classpath.entries.findAll{ it instanceof SourceFolder }.each {
|
||||
it.output = "bin/" + it.path.split("/")[1]
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
|
||||
// https://jira.spring.io/browse/SPR-11836
|
||||
eclipse.classpath.file.whenMerged {
|
||||
entries.findAll { it instanceof ProjectDependency }.each {
|
||||
eclipse.classpath.file.whenMerged { classpath ->
|
||||
classpath.entries.findAll { it instanceof ProjectDependency }.each {
|
||||
// delete from original position
|
||||
entries.remove(it)
|
||||
classpath.entries.remove(it)
|
||||
// append to end of classpath
|
||||
entries.add(it)
|
||||
classpath.entries.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,20 +64,47 @@ eclipse.classpath.file.whenMerged {
|
||||
}
|
||||
}
|
||||
|
||||
// Allow projects to be used as WTP modules
|
||||
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
|
||||
|
||||
// Include project specific settings
|
||||
task eclipseSettings(type: Copy) {
|
||||
from rootProject.files(
|
||||
'src/eclipse/org.eclipse.jdt.core.prefs',
|
||||
'src/eclipse/org.eclipse.jdt.ui.prefs')
|
||||
"src/eclipse/org.eclipse.jdt.ui.prefs",
|
||||
"src/eclipse/org.eclipse.wst.common.project.facet.core.xml")
|
||||
into project.file('.settings/')
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
task cleanEclipseSettings(type: Delete) {
|
||||
delete project.file('.settings/org.eclipse.jdt.core.prefs')
|
||||
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
|
||||
task eclipseWstComponent(type: Copy) {
|
||||
from rootProject.files(
|
||||
"src/eclipse/org.eclipse.wst.common.component")
|
||||
into project.file('.settings/')
|
||||
expand(deployname: project.name)
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
tasks['eclipse'].dependsOn(eclipseSettings)
|
||||
tasks['eclipseJdt'].dependsOn(eclipseSettings)
|
||||
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
|
||||
task eclipseJdtPrepare(type: Copy) {
|
||||
from rootProject.file("src/eclipse/org.eclipse.jdt.core.prefs")
|
||||
into project.file(".settings/")
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
task cleanEclipseJdtUi(type: Delete) {
|
||||
delete project.file(".settings/org.eclipse.jdt.core.prefs")
|
||||
delete project.file(".settings/org.eclipse.jdt.ui.prefs")
|
||||
delete project.file(".settings/org.eclipse.wst.common.component")
|
||||
delete project.file(".settings/org.eclipse.wst.common.project.facet.core.xml")
|
||||
}
|
||||
|
||||
task eclipseBuildship(type: Copy) {
|
||||
from rootProject.files(
|
||||
"src/eclipse/org.eclipse.jdt.ui.prefs",
|
||||
"src/eclipse/org.eclipse.jdt.core.prefs")
|
||||
into project.file('.settings/')
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
|
||||
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
|
||||
tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent)
|
||||
|
||||
@@ -8,19 +8,15 @@ apply plugin: 'me.champeau.jmh'
|
||||
apply from: "$rootDir/gradle/publications.gradle"
|
||||
|
||||
dependencies {
|
||||
jmh 'org.openjdk.jmh:jmh-core:1.32'
|
||||
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.32'
|
||||
jmh 'net.sf.jopt-simple:jopt-simple'
|
||||
jmh 'org.openjdk.jmh:jmh-core:1.28'
|
||||
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.28'
|
||||
jmh 'net.sf.jopt-simple:jopt-simple:4.6'
|
||||
}
|
||||
|
||||
jmh {
|
||||
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
tasks.findByName("processJmhResources").configure {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
jmhJar {
|
||||
// Uncomment the following for Shadow's Transformer support.
|
||||
// mergeServiceFiles()
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,101 +17,67 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@@ -121,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -132,7 +98,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -140,95 +106,80 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
+20
-24
@@ -3,11 +3,11 @@
|
||||
This document will guide you through the process of importing the Spring Framework
|
||||
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
|
||||
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
|
||||
8 support, Eclipse Buildship, and the Groovy plugin.
|
||||
8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin.
|
||||
|
||||
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
|
||||
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
|
||||
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
|
||||
The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2
|
||||
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog))
|
||||
(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
|
||||
The instructions should work with the latest Eclipse distribution as long as you install
|
||||
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
|
||||
that STS 4 comes with Buildship preinstalled.
|
||||
@@ -16,32 +16,28 @@ that STS 4 comes with Buildship preinstalled.
|
||||
|
||||
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
|
||||
|
||||
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
|
||||
1. Switch to Groovy 3.0 in Eclipse (Preferences → Groovy → Compiler → Switch to 3.0...).
|
||||
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
|
||||
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
|
||||
(Preferences → Java → Compiler → Errors/Warnings → Deprecated and restricted API → Forbidden reference (access rule)).
|
||||
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
|
||||
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
|
||||
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
|
||||
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
|
||||
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
|
||||
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
|
||||
1. Ensure that Eclipse launches with JDK 8.
|
||||
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
|
||||
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
|
||||
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
|
||||
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
|
||||
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
|
||||
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
|
||||
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
|
||||
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
|
||||
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
|
||||
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
|
||||
1. Import all projects into Eclipse (File → Import → Gradle → Existing Gradle Project → Navigate to the locally cloned `spring-framework` directory → Select Finish).
|
||||
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
|
||||
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
|
||||
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
|
||||
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences → Gradle → Java home).
|
||||
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path → Use as Source Folder").
|
||||
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
|
||||
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
|
||||
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
|
||||
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
|
||||
1. Code away!
|
||||
|
||||
## Known Issues
|
||||
|
||||
1. `spring-core` should be pre-compiled due to repackaged dependencies.
|
||||
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
|
||||
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
|
||||
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
|
||||
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
|
||||
- See `*RepackJar` tasks in the build.
|
||||
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
|
||||
- If you installed _AJDT_ into Eclipse it should work.
|
||||
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
description = "Spring Integration Tests"
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(":spring-aop"))
|
||||
testImplementation(project(":spring-beans"))
|
||||
testImplementation(project(":spring-context"))
|
||||
testImplementation(project(":spring-core"))
|
||||
testImplementation(testFixtures(project(":spring-aop")))
|
||||
testImplementation(testFixtures(project(":spring-beans")))
|
||||
testImplementation(testFixtures(project(":spring-core")))
|
||||
testImplementation(testFixtures(project(":spring-tx")))
|
||||
testImplementation(project(":spring-expression"))
|
||||
testImplementation(project(":spring-jdbc"))
|
||||
testImplementation(project(":spring-orm"))
|
||||
testImplementation(project(":spring-test"))
|
||||
testImplementation(project(":spring-tx"))
|
||||
testImplementation(project(":spring-web"))
|
||||
testImplementation("javax.inject:javax.inject")
|
||||
testImplementation("javax.resource:javax.resource-api")
|
||||
testImplementation("javax.servlet:javax.servlet-api")
|
||||
testImplementation("org.aspectj:aspectjweaver")
|
||||
testImplementation("org.hsqldb:hsqldb")
|
||||
testImplementation("org.hibernate:hibernate-core")
|
||||
testCompile(project(":spring-aop"))
|
||||
testCompile(project(":spring-beans"))
|
||||
testCompile(project(":spring-context"))
|
||||
testCompile(project(":spring-core"))
|
||||
testCompile(testFixtures(project(":spring-aop")))
|
||||
testCompile(testFixtures(project(":spring-beans")))
|
||||
testCompile(testFixtures(project(":spring-core")))
|
||||
testCompile(testFixtures(project(":spring-tx")))
|
||||
testCompile(project(":spring-expression"))
|
||||
testCompile(project(":spring-jdbc"))
|
||||
testCompile(project(":spring-orm"))
|
||||
testCompile(project(":spring-test"))
|
||||
testCompile(project(":spring-tx"))
|
||||
testCompile(project(":spring-web"))
|
||||
testCompile("javax.inject:javax.inject")
|
||||
testCompile("javax.resource:javax.resource-api")
|
||||
testCompile("javax.servlet:javax.servlet-api")
|
||||
testCompile("org.aspectj:aspectjweaver")
|
||||
testCompile("org.hsqldb:hsqldb")
|
||||
testCompile("org.hibernate:hibernate-core")
|
||||
}
|
||||
|
||||
normalization {
|
||||
|
||||
+22
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+6
-5
@@ -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"
|
||||
@@ -18,6 +17,8 @@ include "spring-context"
|
||||
include "spring-context-indexer"
|
||||
include "spring-context-support"
|
||||
include "spring-core"
|
||||
include "kotlin-coroutines"
|
||||
project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines')
|
||||
include "spring-expression"
|
||||
include "spring-instrument"
|
||||
include "spring-jcl"
|
||||
@@ -50,7 +51,7 @@ settings.gradle.projectsLoaded {
|
||||
buildScanPublished { scan ->
|
||||
if (buildDir.exists()) {
|
||||
new File(buildDir, "build-scan-uri.txt").text = "${scan.buildScanUri}\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
description = "Spring AOP"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-beans"))
|
||||
api(project(":spring-core"))
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional("org.aspectj:aspectjweaver")
|
||||
optional("org.apache.commons:commons-pool2")
|
||||
optional("com.jamonapi:jamon")
|
||||
testImplementation(testFixtures(project(":spring-beans")))
|
||||
testImplementation(testFixtures(project(":spring-core")))
|
||||
testFixturesImplementation(testFixtures(project(":spring-beans")))
|
||||
testCompile(testFixtures(project(":spring-beans")))
|
||||
testCompile(testFixtures(project(":spring-core")))
|
||||
testFixturesImplementation(testFixtures(project(":spring-core")))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,7 @@ import javax.annotation.Nullable;
|
||||
* terminology).
|
||||
*
|
||||
* <p>A runtime joinpoint is an <i>event</i> that occurs on a static
|
||||
* joinpoint (i.e. a location in a program). For instance, an
|
||||
* joinpoint (i.e. a location in a the program). For instance, an
|
||||
* invocation is the runtime joinpoint on a method (static joinpoint).
|
||||
* The static part of a given joinpoint can be generically retrieved
|
||||
* using the {@link #getStaticPart()} method.
|
||||
|
||||
+4
-5
@@ -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.
|
||||
@@ -103,11 +103,10 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
@Override
|
||||
public void validate(Class<?> aspectClass) throws AopConfigException {
|
||||
// If the parent has the annotation and isn't abstract it's an error
|
||||
Class<?> superclass = aspectClass.getSuperclass();
|
||||
if (superclass.getAnnotation(Aspect.class) != null &&
|
||||
!Modifier.isAbstract(superclass.getModifiers())) {
|
||||
if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
|
||||
!Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
|
||||
throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" +
|
||||
superclass.getName() + "]");
|
||||
aspectClass.getSuperclass().getName() + "]");
|
||||
}
|
||||
|
||||
AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
|
||||
|
||||
@@ -521,8 +521,8 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
copy.copyFrom(this);
|
||||
copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic());
|
||||
copy.advisorChainFactory = this.advisorChainFactory;
|
||||
copy.interfaces = new ArrayList<>(this.interfaces);
|
||||
copy.advisors = new ArrayList<>(this.advisors);
|
||||
copy.interfaces = this.interfaces;
|
||||
copy.advisors = this.advisors;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@@ -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-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.
|
||||
@@ -237,7 +237,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* validates it if not.
|
||||
*/
|
||||
private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) {
|
||||
if (!this.advised.isOptimize() && logger.isInfoEnabled()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
synchronized (validatedClasses) {
|
||||
if (!validatedClasses.containsKey(proxySuperClass)) {
|
||||
doValidateClass(proxySuperClass, proxyClassLoader,
|
||||
@@ -679,19 +679,13 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object retVal;
|
||||
// Check whether we only have one InvokerInterceptor: that is,
|
||||
// no real advice, but just reflective invocation of the target.
|
||||
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
|
||||
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
|
||||
// We can skip creating a MethodInvocation: just invoke the target directly.
|
||||
// Note that the final invoker must be an InvokerInterceptor, so we know
|
||||
// it does nothing but a reflective operation on the target, and no hot
|
||||
// swapping or fancy proxying.
|
||||
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
|
||||
try {
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
|
||||
}
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
else {
|
||||
// We need to create a method invocation...
|
||||
@@ -743,7 +737,10 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
|
||||
// Only use method proxy for public methods not derived from java.lang.Object
|
||||
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
|
||||
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
|
||||
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
|
||||
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
|
||||
methodProxy : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -779,25 +776,10 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.methodProxy != null) {
|
||||
try {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
logFastClassGenerationFailure(this.method);
|
||||
}
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
return super.invokeJoinpoint();
|
||||
}
|
||||
|
||||
static boolean isMethodProxyCompatible(Method method) {
|
||||
return (Modifier.isPublic(method.getModifiers()) &&
|
||||
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
|
||||
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
|
||||
}
|
||||
|
||||
static void logFastClassGenerationFailure(Method method) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to generate CGLIB fast class for method: " + method);
|
||||
else {
|
||||
return super.invokeJoinpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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-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.
|
||||
@@ -73,9 +73,11 @@ public class ProxyConfig implements Serializable {
|
||||
* The exact meaning of "aggressive optimizations" will differ
|
||||
* between proxies, but there is usually some tradeoff.
|
||||
* Default is "false".
|
||||
* <p>With Spring's current proxy options, this flag effectively
|
||||
* enforces CGLIB proxies (similar to {@link #setProxyTargetClass})
|
||||
* but without any class validation checks (for final methods etc).
|
||||
* <p>For example, optimization will usually mean that advice changes won't
|
||||
* take effect after a proxy has been created. For this reason, optimization
|
||||
* is disabled by default. An optimize value of "true" may be ignored
|
||||
* if other settings preclude optimization: for example, if "exposeProxy"
|
||||
* is set to "true" and that's not compatible with the optimization.
|
||||
*/
|
||||
public void setOptimize(boolean optimize) {
|
||||
this.optimize = optimize;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -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
-1
@@ -61,7 +61,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.
|
||||
* If you intend to proxy a FactoryBean instance itself (a rare use case, but
|
||||
* Spring 1.2's default behavior), specify the bean name of the FactoryBean
|
||||
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
|
||||
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
|
||||
*/
|
||||
|
||||
+7
-3
@@ -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.
|
||||
@@ -125,8 +125,12 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
*/
|
||||
protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
|
||||
synchronized (this.internalBeanFactories) {
|
||||
return this.internalBeanFactories.computeIfAbsent(beanName,
|
||||
name -> buildInternalBeanFactory(this.beanFactory));
|
||||
DefaultListableBeanFactory internalBeanFactory = this.internalBeanFactories.get(beanName);
|
||||
if (internalBeanFactory == null) {
|
||||
internalBeanFactory = buildInternalBeanFactory(this.beanFactory);
|
||||
this.internalBeanFactories.put(beanName, internalBeanFactory);
|
||||
}
|
||||
return internalBeanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -25,11 +25,9 @@ import org.springframework.lang.Nullable;
|
||||
/**
|
||||
* Convenient TargetSourceCreator using bean name prefixes to create one of three
|
||||
* well-known TargetSource types:
|
||||
* <ul>
|
||||
* <li>: CommonsPool2TargetSource</li>
|
||||
* <li>% ThreadLocalTargetSource</li>
|
||||
* <li>! PrototypeTargetSource</li>
|
||||
* </ul>
|
||||
* <li>: CommonsPool2TargetSource
|
||||
* <li>% ThreadLocalTargetSource
|
||||
* <li>! PrototypeTargetSource
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Stephane Nicoll
|
||||
|
||||
+3
-5
@@ -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-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.
|
||||
@@ -146,7 +146,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + this.methodName;
|
||||
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -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;
|
||||
}
|
||||
|
||||
+4
-3
@@ -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())");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+47
-37
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-1
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -30,10 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
*/
|
||||
class ClassUtilsTests {
|
||||
public class ClassUtilsTests {
|
||||
|
||||
@Test
|
||||
void getShortNameForCglibClass() {
|
||||
public void getShortNameForCglibClass() {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTarget(tb);
|
||||
@@ -42,5 +41,4 @@ class ClassUtilsTests {
|
||||
String className = ClassUtils.getShortName(proxy.getClass());
|
||||
assertThat(className).as("Class name did not match").isEqualTo("TestBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+4
@@ -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>
|
||||
|
||||
+4
@@ -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>
|
||||
|
||||
+2
-3
@@ -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;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ sourceSets.test.java.srcDirs = files()
|
||||
aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver']
|
||||
|
||||
dependencies {
|
||||
api("org.aspectj:aspectjweaver")
|
||||
compile("org.aspectj:aspectjweaver")
|
||||
compileOnly("org.aspectj:aspectjrt")
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
@@ -21,13 +21,13 @@ dependencies {
|
||||
optional(project(":spring-tx")) // for JPA, @Transactional support
|
||||
optional("javax.cache:cache-api") // for JCache aspect
|
||||
optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support
|
||||
testImplementation(project(":spring-core")) // for CodeStyleAspect
|
||||
testImplementation(project(":spring-test"))
|
||||
testImplementation(testFixtures(project(":spring-context")))
|
||||
testImplementation(testFixtures(project(":spring-context-support")))
|
||||
testImplementation(testFixtures(project(":spring-core")))
|
||||
testImplementation(testFixtures(project(":spring-tx")))
|
||||
testImplementation("javax.mail:javax.mail-api")
|
||||
testCompile(project(":spring-core")) // for CodeStyleAspect
|
||||
testCompile(project(":spring-test"))
|
||||
testCompile(testFixtures(project(":spring-context")))
|
||||
testCompile(testFixtures(project(":spring-context-support")))
|
||||
testCompile(testFixtures(project(":spring-core")))
|
||||
testCompile(testFixtures(project(":spring-tx")))
|
||||
testCompile("javax.mail:javax.mail-api")
|
||||
testCompileOnly("org.aspectj:aspectjrt")
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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.
|
||||
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
/**
|
||||
* Marker interface for domain objects that need DI through aspects.
|
||||
* Marker interface for domain object that need DI through aspects.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface ConfigurableObject {
|
||||
|
||||
}
|
||||
|
||||
+6
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2014 the original author 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,18 +22,13 @@ import org.springframework.contextsupport.testfixture.jcache.AbstractJCacheAnnot
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class JCacheAspectJNamespaceConfigTests extends AbstractJCacheAnnotationTests {
|
||||
|
||||
@Override
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
|
||||
// Disallow bean definition overriding to test https://github.com/spring-projects/spring-framework/pull/27499
|
||||
context.setAllowBeanDefinitionOverriding(false);
|
||||
context.load("/org/springframework/cache/config/annotation-jcache-aspectj.xml");
|
||||
context.refresh();
|
||||
return context;
|
||||
return new GenericXmlApplicationContext(
|
||||
"/org/springframework/cache/config/annotation-jcache-aspectj.xml");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-2
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -30,5 +29,4 @@ public class ClassWithPrivateAnnotatedMember {
|
||||
|
||||
@Transactional
|
||||
private void doInTransaction() {}
|
||||
|
||||
}
|
||||
|
||||
-2
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -30,5 +29,4 @@ public class ClassWithProtectedAnnotatedMember {
|
||||
|
||||
@Transactional
|
||||
protected void doInTransaction() {}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@ apply plugin: "groovy"
|
||||
apply plugin: "kotlin"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-core"))
|
||||
compile(project(":spring-core"))
|
||||
optional("javax.inject:javax.inject")
|
||||
optional("org.yaml:snakeyaml")
|
||||
optional("org.codehaus.groovy:groovy-xml")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
testImplementation(testFixtures(project(":spring-core")))
|
||||
testImplementation("javax.annotation:javax.annotation-api")
|
||||
testCompile(testFixtures(project(":spring-core")))
|
||||
testCompile("javax.annotation:javax.annotation-api")
|
||||
testFixturesApi("org.junit.jupiter:junit-jupiter-api")
|
||||
testFixturesImplementation("org.assertj:assertj-core")
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -87,10 +87,7 @@ public abstract class BeanUtils {
|
||||
values.put(byte.class, (byte) 0);
|
||||
values.put(short.class, (short) 0);
|
||||
values.put(int.class, 0);
|
||||
values.put(long.class, 0L);
|
||||
values.put(float.class, 0F);
|
||||
values.put(double.class, 0D);
|
||||
values.put(char.class, '\0');
|
||||
values.put(long.class, (long) 0);
|
||||
DEFAULT_TYPE_VALUES = Collections.unmodifiableMap(values);
|
||||
}
|
||||
|
||||
@@ -100,9 +97,9 @@ public abstract class BeanUtils {
|
||||
* @param clazz class to instantiate
|
||||
* @return the new instance
|
||||
* @throws BeanInstantiationException if the bean cannot be instantiated
|
||||
* @see Class#newInstance()
|
||||
* @deprecated as of Spring 5.0, following the deprecation of
|
||||
* {@link Class#newInstance()} in JDK 9
|
||||
* @see Class#newInstance()
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T> T instantiate(Class<T> clazz) throws BeanInstantiationException {
|
||||
@@ -226,45 +223,32 @@ public abstract class BeanUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resolvable constructor for the provided class, either a primary or single
|
||||
* public constructor with arguments, or a single non-public constructor with arguments,
|
||||
* or simply a default constructor. Callers have to be prepared to resolve arguments
|
||||
* for the returned constructor's parameters, if any.
|
||||
* Return a resolvable constructor for the provided class, either a primary constructor
|
||||
* or single public constructor or simply a default constructor. Callers have to be
|
||||
* prepared to resolve arguments for the returned constructor's parameters, if any.
|
||||
* @param clazz the class to check
|
||||
* @throws IllegalStateException in case of no unique constructor found at all
|
||||
* @since 5.3
|
||||
* @see #findPrimaryConstructor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Constructor<T> getResolvableConstructor(Class<T> clazz) {
|
||||
Constructor<T> ctor = findPrimaryConstructor(clazz);
|
||||
if (ctor != null) {
|
||||
return ctor;
|
||||
}
|
||||
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single public constructor
|
||||
return (Constructor<T>) ctors[0];
|
||||
}
|
||||
else if (ctors.length == 0){
|
||||
ctors = clazz.getDeclaredConstructors();
|
||||
if (ctor == null) {
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single non-public constructor, e.g. from a non-public record type
|
||||
return (Constructor<T>) ctors[0];
|
||||
ctor = (Constructor<T>) ctors[0];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ctor = clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("No primary or single public constructor found for " +
|
||||
clazz + " - and no default constructor found either");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Several constructors -> let's try to take the default constructor
|
||||
try {
|
||||
return clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// Giving up...
|
||||
}
|
||||
|
||||
// No unique constructor at all
|
||||
throw new IllegalStateException("No primary or single unique constructor found for " + clazz);
|
||||
return ctor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -540,7 +524,7 @@ public abstract class BeanUtils {
|
||||
|
||||
/**
|
||||
* Find a JavaBeans PropertyEditor following the 'Editor' suffix convention
|
||||
* (e.g. "mypackage.MyDomainClass" → "mypackage.MyDomainClassEditor").
|
||||
* (e.g. "mypackage.MyDomainClass" -> "mypackage.MyDomainClassEditor").
|
||||
* <p>Compatible to the standard JavaBeans convention as implemented by
|
||||
* {@link java.beans.PropertyEditorManager} but isolated from the latter's
|
||||
* registered default editors for primitive types.
|
||||
@@ -691,25 +675,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 +692,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 +710,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 +727,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
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -138,7 +138,7 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
Set<Method> ambiguousCandidates = this.ambiguousWriteMethods;
|
||||
if (ambiguousCandidates != null) {
|
||||
this.ambiguousWriteMethods = null;
|
||||
LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).debug("Non-unique JavaBean property '" +
|
||||
LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).warn("Invalid JavaBean property '" +
|
||||
getName() + "' being accessed! Ambiguous write methods found next to actually used [" +
|
||||
this.writeMethod + "]: " + ambiguousCandidates);
|
||||
}
|
||||
|
||||
@@ -134,8 +134,8 @@ public abstract class PropertyAccessorUtils {
|
||||
/**
|
||||
* Determine the canonical name for the given property path.
|
||||
* Removes surrounding quotes from map keys:<br>
|
||||
* {@code map['key']} → {@code map[key]}<br>
|
||||
* {@code map["key"]} → {@code map[key]}
|
||||
* {@code map['key']} -> {@code map[key]}<br>
|
||||
* {@code map["key"]} -> {@code map[key]}
|
||||
* @param propertyName the bean property path
|
||||
* @return the canonical representation of the property path
|
||||
*/
|
||||
|
||||
+4
-7
@@ -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.
|
||||
@@ -422,13 +422,10 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
}
|
||||
if (editor == null) {
|
||||
// Find editor for superclass or interface.
|
||||
for (Map.Entry<Class<?>, PropertyEditor> entry : this.customEditors.entrySet()) {
|
||||
if (editor != null) {
|
||||
break;
|
||||
}
|
||||
Class<?> key = entry.getKey();
|
||||
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) {
|
||||
Class<?> key = it.next();
|
||||
if (key.isAssignableFrom(requiredType)) {
|
||||
editor = entry.getValue();
|
||||
editor = this.customEditors.get(key);
|
||||
// Cache editor for search type, to avoid the overhead
|
||||
// of repeated assignable-from checks.
|
||||
if (this.customEditorCache == null) {
|
||||
|
||||
@@ -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
-23
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -459,7 +459,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
|
||||
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
|
||||
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
|
||||
return InjectionMetadata.EMPTY;
|
||||
}
|
||||
@@ -537,10 +537,11 @@ 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())));
|
||||
// The following (AnnotationAttributes) cast is required on JDK 9+.
|
||||
return determineRequiredStatus((AnnotationAttributes)
|
||||
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -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.
|
||||
@@ -351,9 +351,7 @@ public class ConstructorArgumentValues {
|
||||
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||
*/
|
||||
@Nullable
|
||||
public ValueHolder getArgumentValue(int index, @Nullable Class<?> requiredType,
|
||||
@Nullable String requiredName, @Nullable Set<ValueHolder> usedValueHolders) {
|
||||
|
||||
public ValueHolder getArgumentValue(int index, @Nullable Class<?> requiredType, @Nullable String requiredName, @Nullable Set<ValueHolder> usedValueHolders) {
|
||||
Assert.isTrue(index >= 0, "Index must not be negative");
|
||||
ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType, requiredName);
|
||||
if (valueHolder == null) {
|
||||
|
||||
+4
-2
@@ -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
|
||||
|
||||
+7
-7
@@ -47,17 +47,17 @@ import org.springframework.util.ClassUtils;
|
||||
* which uses this class to call a static initialization method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClass.init"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClass.init"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* <p>An example of calling an instance method to start some server bean:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="targetObject" ref="myServer"/>
|
||||
* <property name="targetMethod" value="start"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="targetObject" ref="myServer"/>
|
||||
* <property name="targetMethod" value="start"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0.3
|
||||
|
||||
+12
-12
@@ -56,24 +56,24 @@ import org.springframework.lang.Nullable;
|
||||
* which uses this class to call a static factory method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* <p>An example of calling a static method then an instance method to get at a
|
||||
* Java system property. Somewhat verbose, but it works.
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetClass" value="java.lang.System"/>
|
||||
* <property name="targetMethod" value="getProperties"/>
|
||||
* </bean>
|
||||
* <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetClass" value="java.lang.System"/>
|
||||
* <property name="targetMethod" value="getProperties"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetObject" ref="sysProps"/>
|
||||
* <property name="targetMethod" value="getProperty"/>
|
||||
* <property name="arguments" value="java.version"/>
|
||||
* </bean></pre>
|
||||
* <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetObject" ref="sysProps"/>
|
||||
* <property name="targetMethod" value="getProperty"/>
|
||||
* <property name="arguments" value="java.version"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+22
-22
@@ -83,22 +83,22 @@ import org.springframework.util.StringUtils;
|
||||
* <p>A sample config in an XML-based
|
||||
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
|
||||
*
|
||||
* <pre class="code"><beans>
|
||||
* <pre class="code"><beans>
|
||||
*
|
||||
* <!-- Prototype bean since we have state -->
|
||||
* <bean id="myService" class="a.b.c.MyService" singleton="false"/>
|
||||
* <!-- Prototype bean since we have state -->
|
||||
* <bean id="myService" class="a.b.c.MyService" singleton="false"/>
|
||||
*
|
||||
* <!-- will lookup the above 'myService' bean by *TYPE* -->
|
||||
* <!-- will lookup the above 'myService' bean by *TYPE* -->
|
||||
* <bean id="myServiceFactory"
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
*</beans></pre>
|
||||
*</beans></pre>
|
||||
*
|
||||
* <p>The attendant {@code MyClientBean} class implementation might then
|
||||
* look something like this:
|
||||
@@ -135,22 +135,22 @@ import org.springframework.util.StringUtils;
|
||||
* <p>A sample config in an XML-based
|
||||
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
|
||||
*
|
||||
* <pre class="code"><beans>
|
||||
* <pre class="code"><beans>
|
||||
*
|
||||
* <!-- Prototype beans since we have state (both extend MyService) -->
|
||||
* <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
|
||||
* <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
|
||||
* <!-- Prototype beans since we have state (both extend MyService) -->
|
||||
* <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
|
||||
* <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
|
||||
*
|
||||
* <bean id="myServiceFactory"
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
*</beans></pre>
|
||||
*</beans></pre>
|
||||
*
|
||||
* <p>The attendant {@code MyClientBean} class implementation might then
|
||||
* look something like this:
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public abstract class YamlProcessor {
|
||||
* </pre>
|
||||
* when mapped with
|
||||
* <pre class="code">
|
||||
* setDocumentMatchers(properties ->
|
||||
* setDocumentMatchers(properties ->
|
||||
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
|
||||
* </pre>
|
||||
* would end up as
|
||||
|
||||
+5
-5
@@ -75,18 +75,18 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* def reader = new GroovyBeanDefinitionReader(myApplicationContext)
|
||||
* reader.beans {
|
||||
* dataSource(BasicDataSource) { // <--- invokeMethod
|
||||
* dataSource(BasicDataSource) { // <--- invokeMethod
|
||||
* driverClassName = "org.hsqldb.jdbcDriver"
|
||||
* url = "jdbc:hsqldb:mem:grailsDB"
|
||||
* username = "sa" // <-- setProperty
|
||||
* username = "sa" // <-- setProperty
|
||||
* password = ""
|
||||
* settings = [mynew:"setting"]
|
||||
* }
|
||||
* sessionFactory(SessionFactory) {
|
||||
* dataSource = dataSource // <-- getProperty for retrieving references
|
||||
* dataSource = dataSource // <-- getProperty for retrieving references
|
||||
* }
|
||||
* myService(MyService) {
|
||||
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
|
||||
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* }
|
||||
@@ -113,7 +113,7 @@ import org.springframework.util.StringUtils;
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* myService(MyService) {
|
||||
* nestedBean = { AnotherBean bean ->
|
||||
* nestedBean = { AnotherBean bean ->
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* }
|
||||
|
||||
+6
-24
@@ -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.
|
||||
@@ -246,15 +246,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
this.allowCircularReferences = allowCircularReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to allow circular references between beans.
|
||||
* @since 5.3.10
|
||||
* @see #setAllowCircularReferences
|
||||
*/
|
||||
public boolean isAllowCircularReferences() {
|
||||
return this.allowCircularReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to allow the raw injection of a bean instance into some other
|
||||
* bean's property, despite the injected bean eventually getting wrapped
|
||||
@@ -273,15 +264,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to allow the raw injection of a bean instance.
|
||||
* @since 5.3.10
|
||||
* @see #setAllowRawInjectionDespiteWrapping
|
||||
*/
|
||||
public boolean isAllowRawInjectionDespiteWrapping() {
|
||||
return this.allowRawInjectionDespiteWrapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore the given dependency type for autowiring:
|
||||
* for example, String. Default is none.
|
||||
@@ -1342,7 +1324,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (implying the use of constructor argument values from bean definition)
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @see #getBean(String, Object[])
|
||||
*/
|
||||
@@ -1363,7 +1345,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param ctors the chosen candidate constructors
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (implying the use of constructor argument values from bean definition)
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper autowireConstructor(
|
||||
@@ -1844,7 +1826,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 +1850,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 +1890,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
-9
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -361,7 +361,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
else {
|
||||
String scopeName = mbd.getScope();
|
||||
if (!StringUtils.hasLength(scopeName)) {
|
||||
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
|
||||
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
|
||||
}
|
||||
Scope scope = this.scopes.get(scopeName);
|
||||
if (scope == null) {
|
||||
|
||||
+16
-17
@@ -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
|
||||
*/
|
||||
|
||||
+4
-13
@@ -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);
|
||||
|
||||
+63
-105
@@ -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
|
||||
@@ -62,8 +61,6 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
|
||||
private static final String DESTROY_METHOD_NAME = "destroy";
|
||||
|
||||
private static final String CLOSE_METHOD_NAME = "close";
|
||||
|
||||
private static final String SHUTDOWN_METHOD_NAME = "shutdown";
|
||||
@@ -75,11 +72,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
|
||||
private final String beanName;
|
||||
|
||||
private final boolean nonPublicAccessAllowed;
|
||||
|
||||
private final boolean invokeDisposableBean;
|
||||
|
||||
private boolean invokeAutoCloseable;
|
||||
private final boolean nonPublicAccessAllowed;
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
|
||||
@Nullable
|
||||
private String destroyMethodName;
|
||||
@@ -90,9 +88,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
@Nullable
|
||||
private final List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new DisposableBeanAdapter for the given bean.
|
||||
@@ -108,45 +103,38 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = beanName;
|
||||
this.invokeDisposableBean =
|
||||
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.invokeDisposableBean = (bean instanceof DisposableBean &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null &&
|
||||
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
||||
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
|
||||
if (!this.invokeAutoCloseable) {
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
Method destroyMethod = determineDestroyMethod(destroyMethodName);
|
||||
if (destroyMethod == null) {
|
||||
if (beanDefinition.isEnforceDestroyMethod()) {
|
||||
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
|
||||
destroyMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (destroyMethod.getParameterCount() > 0) {
|
||||
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
|
||||
if (paramTypes.length > 1) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has more than one parameter - not supported as destroy method");
|
||||
}
|
||||
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has a non-boolean parameter - not supported as destroy method");
|
||||
}
|
||||
}
|
||||
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass());
|
||||
}
|
||||
this.destroyMethod = destroyMethod;
|
||||
}
|
||||
}
|
||||
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
this.acc = acc;
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
Method destroyMethod = determineDestroyMethod(destroyMethodName);
|
||||
if (destroyMethod == null) {
|
||||
if (beanDefinition.isEnforceDestroyMethod()) {
|
||||
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
|
||||
destroyMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (destroyMethod.getParameterCount() > 0) {
|
||||
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
|
||||
if (paramTypes.length > 1) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has more than one parameter - not supported as destroy method");
|
||||
}
|
||||
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has a non-boolean parameter - not supported as destroy method");
|
||||
}
|
||||
}
|
||||
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
|
||||
}
|
||||
this.destroyMethod = destroyMethod;
|
||||
}
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,27 +149,26 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = bean.getClass().getName();
|
||||
this.nonPublicAccessAllowed = true;
|
||||
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
this.nonPublicAccessAllowed = true;
|
||||
this.acc = acc;
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DisposableBeanAdapter for the given bean.
|
||||
*/
|
||||
private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAccessAllowed,
|
||||
boolean invokeDisposableBean, boolean invokeAutoCloseable, @Nullable String destroyMethodName,
|
||||
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
|
||||
boolean nonPublicAccessAllowed, @Nullable String destroyMethodName,
|
||||
@Nullable List<DestructionAwareBeanPostProcessor> postProcessors) {
|
||||
|
||||
this.bean = bean;
|
||||
this.beanName = beanName;
|
||||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||
this.invokeDisposableBean = invokeDisposableBean;
|
||||
this.invokeAutoCloseable = invokeAutoCloseable;
|
||||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||
this.acc = null;
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
this.beanPostProcessors = postProcessors;
|
||||
this.acc = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -224,38 +211,13 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.invokeAutoCloseable) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking close() on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
((AutoCloseable) this.bean).close();
|
||||
return null;
|
||||
}, this.acc);
|
||||
}
|
||||
else {
|
||||
((AutoCloseable) this.bean).close();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
String msg = "Invocation of close method failed on bean with name '" + this.beanName + "'";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(msg, ex);
|
||||
}
|
||||
else {
|
||||
logger.warn(msg + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.destroyMethod != null) {
|
||||
if (this.destroyMethod != null) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,7 +259,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
args[0] = Boolean.TRUE;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking custom destroy method '" + this.destroyMethodName +
|
||||
logger.trace("Invoking destroy method '" + this.destroyMethodName +
|
||||
"' on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
@@ -320,7 +282,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" +
|
||||
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
|
||||
this.beanName + "' threw an exception";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(msg, ex.getTargetException());
|
||||
@@ -330,7 +292,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName +
|
||||
logger.warn("Failed to invoke destroy method '" + this.destroyMethodName +
|
||||
"' on bean with name '" + this.beanName + "'", ex);
|
||||
}
|
||||
}
|
||||
@@ -350,9 +312,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new DisposableBeanAdapter(
|
||||
this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean,
|
||||
this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors);
|
||||
return new DisposableBeanAdapter(this.bean, this.beanName, this.invokeDisposableBean,
|
||||
this.nonPublicAccessAllowed, this.destroyMethodName, serializablePostProcessors);
|
||||
}
|
||||
|
||||
|
||||
@@ -362,7 +323,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @param beanDefinition the corresponding bean definition
|
||||
*/
|
||||
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
|
||||
return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null);
|
||||
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
|
||||
return true;
|
||||
}
|
||||
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -384,27 +348,21 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
|
||||
if (destroyMethodName == null) {
|
||||
destroyMethodName = beanDefinition.getDestroyMethodName();
|
||||
boolean autoCloseable = (bean instanceof AutoCloseable);
|
||||
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
|
||||
(destroyMethodName == null && autoCloseable)) {
|
||||
// Only perform destroy method inference in case of the bean
|
||||
// not explicitly implementing the DisposableBean interface
|
||||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
|
||||
// Only perform destroy method inference or Closeable detection
|
||||
// in case of the bean not explicitly implementing DisposableBean
|
||||
destroyMethodName = null;
|
||||
if (!(bean instanceof DisposableBean)) {
|
||||
if (autoCloseable) {
|
||||
destroyMethodName = CLOSE_METHOD_NAME;
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
|
||||
}
|
||||
else {
|
||||
catch (NoSuchMethodException ex) {
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
|
||||
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
|
||||
}
|
||||
catch (NoSuchMethodException ex2) {
|
||||
// no candidate destroy method found
|
||||
}
|
||||
catch (NoSuchMethodException ex2) {
|
||||
// no candidate destroy method found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-16
@@ -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
-22
@@ -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
-16
@@ -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.
|
||||
|
||||
+5
-147
@@ -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.
|
||||
@@ -21,8 +21,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -49,7 +48,6 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see GenericBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
@@ -424,21 +422,15 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
return this.factoryMethodToIntrospect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration method or field.
|
||||
*/
|
||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedConfigMembers == null) {
|
||||
this.externallyManagedConfigMembers = new LinkedHashSet<>(1);
|
||||
this.externallyManagedConfigMembers = new HashSet<>(1);
|
||||
}
|
||||
this.externallyManagedConfigMembers.add(configMember);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method or field is an externally managed configuration member.
|
||||
*/
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedConfigMembers != null &&
|
||||
@@ -446,44 +438,15 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed configuration methods and fields (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<Member> getExternallyManagedConfigMembers() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedConfigMembers != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration initialization method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PostConstruct} annotation.
|
||||
* <p>The supplied {@code initMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedInitMethods == null) {
|
||||
this.externallyManagedInitMethods = new LinkedHashSet<>(1);
|
||||
this.externallyManagedInitMethods = new HashSet<>(1);
|
||||
}
|
||||
this.externallyManagedInitMethods.add(initMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedInitMethods != null &&
|
||||
@@ -491,76 +454,15 @@ 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() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedInitMethods != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration destruction method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PreDestroy} annotation.
|
||||
* <p>The supplied {@code destroyMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedDestroyMethods == null) {
|
||||
this.externallyManagedDestroyMethods = new LinkedHashSet<>(1);
|
||||
this.externallyManagedDestroyMethods = new HashSet<>(1);
|
||||
}
|
||||
this.externallyManagedDestroyMethods.add(destroyMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedDestroyMethods != null &&
|
||||
@@ -568,50 +470,6 @@ 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.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedDestroyMethods() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedDestroyMethods != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RootBeanDefinition cloneBeanDefinition() {
|
||||
|
||||
+2
-11
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ import org.springframework.util.xml.XmlValidationModeDetector;
|
||||
* when starting your JVM. For example, to use the Oracle {@link DocumentBuilder},
|
||||
* you might start your application like as follows:
|
||||
*
|
||||
* <pre class="code">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
|
||||
* <pre code="class">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
|
||||
@@ -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.
|
||||
@@ -64,24 +64,24 @@ public final class ParserContext {
|
||||
}
|
||||
|
||||
|
||||
public XmlReaderContext getReaderContext() {
|
||||
public final XmlReaderContext getReaderContext() {
|
||||
return this.readerContext;
|
||||
}
|
||||
|
||||
public BeanDefinitionRegistry getRegistry() {
|
||||
public final BeanDefinitionRegistry getRegistry() {
|
||||
return this.readerContext.getRegistry();
|
||||
}
|
||||
|
||||
public BeanDefinitionParserDelegate getDelegate() {
|
||||
public final BeanDefinitionParserDelegate getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BeanDefinition getContainingBeanDefinition() {
|
||||
public final BeanDefinition getContainingBeanDefinition() {
|
||||
return this.containingBeanDefinition;
|
||||
}
|
||||
|
||||
public boolean isNested() {
|
||||
public final boolean isNested() {
|
||||
return (this.containingBeanDefinition != null);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -71,13 +71,13 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
|
||||
private final String schemaMappingsLocation;
|
||||
|
||||
/** Stores the mapping of schema URL → local schema path. */
|
||||
/** Stores the mapping of schema URL -> local schema path. */
|
||||
@Nullable
|
||||
private volatile Map<String, String> schemaMappings;
|
||||
|
||||
|
||||
/**
|
||||
* Loads the schema URL → schema file location mappings using the default
|
||||
* Loads the schema URL -> schema file location mappings using the default
|
||||
* mapping file pattern "META-INF/spring.schemas".
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
@@ -89,7 +89,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the schema URL → schema file location mappings using the given
|
||||
* Loads the schema URL -> schema file location mappings using the given
|
||||
* mapping file pattern.
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
+269
-200
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -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.
|
||||
@@ -49,7 +49,6 @@ import org.springframework.lang.Nullable;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.SoftAssertions.assertSoftly;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BeanUtils}.
|
||||
@@ -86,43 +85,19 @@ class BeanUtilsTests {
|
||||
}
|
||||
|
||||
@Test // gh-22531
|
||||
void instantiateClassWithFewerArgsThanParameters() throws NoSuchMethodException {
|
||||
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
|
||||
|
||||
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() ->
|
||||
BeanUtils.instantiateClass(constructor, null, null, "foo"));
|
||||
void instantiateClassWithOptionalPrimitiveType() throws NoSuchMethodException {
|
||||
Constructor<BeanWithPrimitiveTypes> ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class);
|
||||
BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(ctor, null, null, "foo");
|
||||
assertThat(bean.getCounter()).isEqualTo(0);
|
||||
assertThat(bean.isFlag()).isEqualTo(false);
|
||||
assertThat(bean.getValue()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test // gh-22531
|
||||
void instantiateClassWithMoreArgsThanParameters() throws NoSuchMethodException {
|
||||
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
|
||||
|
||||
Constructor<BeanWithPrimitiveTypes> ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class);
|
||||
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() ->
|
||||
BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo", null));
|
||||
}
|
||||
|
||||
@Test // gh-22531, gh-27390
|
||||
void instantiateClassWithOptionalPrimitiveTypes() throws NoSuchMethodException {
|
||||
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
|
||||
|
||||
BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo");
|
||||
|
||||
assertSoftly(softly -> {
|
||||
softly.assertThat(bean.isFlag()).isFalse();
|
||||
softly.assertThat(bean.getByteCount()).isEqualTo((byte) 0);
|
||||
softly.assertThat(bean.getShortCount()).isEqualTo((short) 0);
|
||||
softly.assertThat(bean.getIntCount()).isEqualTo(0);
|
||||
softly.assertThat(bean.getLongCount()).isEqualTo(0L);
|
||||
softly.assertThat(bean.getFloatCount()).isEqualTo(0F);
|
||||
softly.assertThat(bean.getDoubleCount()).isEqualTo(0D);
|
||||
softly.assertThat(bean.getCharacter()).isEqualTo('\0');
|
||||
softly.assertThat(bean.getText()).isEqualTo("foo");
|
||||
});
|
||||
}
|
||||
|
||||
private Constructor<BeanWithPrimitiveTypes> getBeanWithPrimitiveTypesConstructor() throws NoSuchMethodException {
|
||||
return BeanWithPrimitiveTypes.class.getConstructor(boolean.class, byte.class, short.class, int.class,
|
||||
long.class, float.class, double.class, char.class, String.class);
|
||||
BeanUtils.instantiateClass(ctor, null, null, "foo", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -203,25 +178,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 +189,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 +200,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 +388,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 {
|
||||
|
||||
@@ -830,68 +628,30 @@ class BeanUtilsTests {
|
||||
|
||||
private static class BeanWithPrimitiveTypes {
|
||||
|
||||
private boolean flag;
|
||||
private byte byteCount;
|
||||
private short shortCount;
|
||||
private int intCount;
|
||||
private long longCount;
|
||||
private float floatCount;
|
||||
private double doubleCount;
|
||||
private char character;
|
||||
private String text;
|
||||
private int counter;
|
||||
|
||||
private boolean flag;
|
||||
|
||||
private String value;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public BeanWithPrimitiveTypes(boolean flag, byte byteCount, short shortCount, int intCount, long longCount,
|
||||
float floatCount, double doubleCount, char character, String text) {
|
||||
|
||||
public BeanWithPrimitiveTypes(int counter, boolean flag, String value) {
|
||||
this.counter = counter;
|
||||
this.flag = flag;
|
||||
this.byteCount = byteCount;
|
||||
this.shortCount = shortCount;
|
||||
this.intCount = intCount;
|
||||
this.longCount = longCount;
|
||||
this.floatCount = floatCount;
|
||||
this.doubleCount = doubleCount;
|
||||
this.character = character;
|
||||
this.text = text;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public boolean isFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public byte getByteCount() {
|
||||
return byteCount;
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public short getShortCount() {
|
||||
return shortCount;
|
||||
}
|
||||
|
||||
public int getIntCount() {
|
||||
return intCount;
|
||||
}
|
||||
|
||||
public long getLongCount() {
|
||||
return longCount;
|
||||
}
|
||||
|
||||
public float getFloatCount() {
|
||||
return floatCount;
|
||||
}
|
||||
|
||||
public double getDoubleCount() {
|
||||
return doubleCount;
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PrivateBeanWithPrivateConstructor {
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
public void setUp() {
|
||||
wrapper.setAutoGrowNestedPaths(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+80
-72
@@ -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,6 +16,7 @@
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -45,10 +46,10 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Chris Beams
|
||||
* @since 18.01.2006
|
||||
*/
|
||||
class BeanWrapperGenericsTests {
|
||||
public class BeanWrapperGenericsTests {
|
||||
|
||||
@Test
|
||||
void testGenericSet() {
|
||||
public void testGenericSet() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
Set<String> input = new HashSet<>();
|
||||
@@ -60,7 +61,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericLowerBoundedSet() {
|
||||
public void testGenericLowerBoundedSet() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, true));
|
||||
@@ -73,7 +74,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericSetWithConversionFailure() {
|
||||
public void testGenericSetWithConversionFailure() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
Set<TestBean> input = new HashSet<>();
|
||||
@@ -84,7 +85,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericList() throws Exception {
|
||||
public void testGenericList() throws MalformedURLException {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
List<String> input = new ArrayList<>();
|
||||
@@ -96,7 +97,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListElement() throws Exception {
|
||||
public void testGenericListElement() throws MalformedURLException {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
gb.setResourceList(new ArrayList<>());
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
@@ -105,29 +106,29 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMap() {
|
||||
public void testGenericMap() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
Map<String, String> input = new HashMap<>();
|
||||
input.put("4", "5");
|
||||
input.put("6", "7");
|
||||
bw.setPropertyValue("shortMap", input);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
|
||||
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapElement() {
|
||||
public void testGenericMapElement() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
gb.setShortMap(new HashMap<>());
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("shortMap[4]", "5");
|
||||
assertThat(bw.getPropertyValue("shortMap[4]")).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapWithKeyType() {
|
||||
public void testGenericMapWithKeyType() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
Map<String, String> input = new HashMap<>();
|
||||
@@ -139,17 +140,17 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapElementWithKeyType() {
|
||||
public void testGenericMapElementWithKeyType() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
gb.setLongMap(new HashMap<Long, Integer>());
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("longMap[4]", "5");
|
||||
assertThat(gb.getLongMap().get(Long.valueOf("4"))).isEqualTo("5");
|
||||
assertThat(gb.getLongMap().get(new Long("4"))).isEqualTo("5");
|
||||
assertThat(bw.getPropertyValue("longMap[4]")).isEqualTo("5");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapWithCollectionValue() {
|
||||
public void testGenericMapWithCollectionValue() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
|
||||
@@ -161,12 +162,14 @@ class BeanWrapperGenericsTests {
|
||||
value2.add(Boolean.TRUE);
|
||||
input.put("2", value2);
|
||||
bw.setPropertyValue("collectionMap", input);
|
||||
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
|
||||
assertThat(gb.getCollectionMap().get(2) instanceof ArrayList).isTrue();
|
||||
boolean condition1 = gb.getCollectionMap().get(1) instanceof HashSet;
|
||||
assertThat(condition1).isTrue();
|
||||
boolean condition = gb.getCollectionMap().get(2) instanceof ArrayList;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapElementWithCollectionValue() {
|
||||
public void testGenericMapElementWithCollectionValue() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
gb.setCollectionMap(new HashMap<>());
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
@@ -174,23 +177,24 @@ class BeanWrapperGenericsTests {
|
||||
HashSet<Integer> value1 = new HashSet<>();
|
||||
value1.add(1);
|
||||
bw.setPropertyValue("collectionMap[1]", value1);
|
||||
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
|
||||
boolean condition = gb.getCollectionMap().get(1) instanceof HashSet;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapFromProperties() {
|
||||
public void testGenericMapFromProperties() {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
Properties input = new Properties();
|
||||
input.setProperty("4", "5");
|
||||
input.setProperty("6", "7");
|
||||
bw.setPropertyValue("shortMap", input);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
|
||||
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfLists() {
|
||||
public void testGenericListOfLists() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
list.add(new ArrayList<>());
|
||||
@@ -202,7 +206,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfListsWithElementConversion() {
|
||||
public void testGenericListOfListsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
list.add(new ArrayList<>());
|
||||
@@ -214,7 +218,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfArrays() {
|
||||
public void testGenericListOfArrays() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
ArrayList<String[]> list = new ArrayList<>();
|
||||
list.add(new String[] {"str1", "str2"});
|
||||
@@ -226,7 +230,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfArraysWithElementConversion() {
|
||||
public void testGenericListOfArraysWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
ArrayList<String[]> list = new ArrayList<>();
|
||||
list.add(new String[] {"str1", "str2"});
|
||||
@@ -239,55 +243,55 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfMaps() {
|
||||
public void testGenericListOfMaps() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<Map<Integer, Long>> list = new ArrayList<>();
|
||||
list.add(new HashMap<>());
|
||||
gb.setListOfMaps(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("listOfMaps[0][10]", 5L);
|
||||
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(5L);
|
||||
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(Long.valueOf(5));
|
||||
bw.setPropertyValue("listOfMaps[0][10]", new Long(5));
|
||||
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(new Long(5));
|
||||
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(new Long(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericListOfMapsWithElementConversion() {
|
||||
public void testGenericListOfMapsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
List<Map<Integer, Long>> list = new ArrayList<>();
|
||||
list.add(new HashMap<>());
|
||||
gb.setListOfMaps(list);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("listOfMaps[0][10]", "5");
|
||||
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(5L);
|
||||
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(Long.valueOf(5));
|
||||
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(new Long(5));
|
||||
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(new Long(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapOfMaps() {
|
||||
public void testGenericMapOfMaps() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<String, Map<Integer, Long>> map = new HashMap<>();
|
||||
map.put("mykey", new HashMap<>());
|
||||
gb.setMapOfMaps(map);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("mapOfMaps[mykey][10]", 5L);
|
||||
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(5L);
|
||||
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(Long.valueOf(5));
|
||||
bw.setPropertyValue("mapOfMaps[mykey][10]", new Long(5));
|
||||
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(new Long(5));
|
||||
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(new Long(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapOfMapsWithElementConversion() {
|
||||
public void testGenericMapOfMapsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<String, Map<Integer, Long>> map = new HashMap<>();
|
||||
map.put("mykey", new HashMap<>());
|
||||
gb.setMapOfMaps(map);
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("mapOfMaps[mykey][10]", "5");
|
||||
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(Long.valueOf(5));
|
||||
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(Long.valueOf(5));
|
||||
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(new Long(5));
|
||||
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(new Long(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapOfLists() {
|
||||
public void testGenericMapOfLists() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
map.put(1, new ArrayList<>());
|
||||
@@ -299,7 +303,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericMapOfListsWithElementConversion() {
|
||||
public void testGenericMapOfListsWithElementConversion() throws MalformedURLException {
|
||||
GenericBean<String> gb = new GenericBean<>();
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
map.put(1, new ArrayList<>());
|
||||
@@ -311,7 +315,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericTypeNestingMapOfInteger() {
|
||||
public void testGenericTypeNestingMapOfInteger() throws Exception {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("testKey", "100");
|
||||
|
||||
@@ -320,13 +324,14 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfInteger().get("testKey");
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
boolean condition = obj instanceof Integer;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericTypeNestingMapOfListOfInteger() {
|
||||
public void testGenericTypeNestingMapOfListOfInteger() throws Exception {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
List<String> list = Arrays.asList("1", "2", "3");
|
||||
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
|
||||
map.put("testKey", list);
|
||||
|
||||
NestedGenericCollectionBean gb = new NestedGenericCollectionBean();
|
||||
@@ -334,12 +339,13 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfListOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfListOfInteger().get("testKey").get(0);
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
boolean condition = obj instanceof Integer;
|
||||
assertThat(condition).isTrue();
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericTypeNestingListOfMapOfInteger() {
|
||||
public void testGenericTypeNestingListOfMapOfInteger() throws Exception {
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("testKey", "5");
|
||||
@@ -350,14 +356,15 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("listOfMapOfInteger", list);
|
||||
|
||||
Object obj = gb.getListOfMapOfInteger().get(0).get("testKey");
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
boolean condition = obj instanceof Integer;
|
||||
assertThat(condition).isTrue();
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericTypeNestingMapOfListOfListOfInteger() {
|
||||
public void testGenericTypeNestingMapOfListOfListOfInteger() throws Exception {
|
||||
Map<String, List<List<String>>> map = new HashMap<>();
|
||||
List<String> list = Arrays.asList("1", "2", "3");
|
||||
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
|
||||
map.put("testKey", Collections.singletonList(list));
|
||||
|
||||
NestedGenericCollectionBean gb = new NestedGenericCollectionBean();
|
||||
@@ -365,12 +372,13 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("mapOfListOfListOfInteger", map);
|
||||
|
||||
Object obj = gb.getMapOfListOfListOfInteger().get("testKey").get(0).get(0);
|
||||
assertThat(obj instanceof Integer).isTrue();
|
||||
boolean condition = obj instanceof Integer;
|
||||
assertThat(condition).isTrue();
|
||||
assertThat(((Integer) obj).intValue()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexGenericMap() {
|
||||
public void testComplexGenericMap() {
|
||||
Map<List<String>, List<String>> inputMap = new HashMap<>();
|
||||
List<String> inputKey = new ArrayList<>();
|
||||
inputKey.add("1");
|
||||
@@ -383,11 +391,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("genericMap", inputMap);
|
||||
|
||||
assertThat(holder.getGenericMap().keySet().iterator().next().get(0)).isEqualTo(1);
|
||||
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexGenericMapWithCollectionConversion() {
|
||||
public void testComplexGenericMapWithCollectionConversion() {
|
||||
Map<Set<String>, Set<String>> inputMap = new HashMap<>();
|
||||
Set<String> inputKey = new HashSet<>();
|
||||
inputKey.add("1");
|
||||
@@ -400,11 +408,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("genericMap", inputMap);
|
||||
|
||||
assertThat(holder.getGenericMap().keySet().iterator().next().get(0)).isEqualTo(1);
|
||||
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexGenericIndexedMapEntry() {
|
||||
public void testComplexGenericIndexedMapEntry() {
|
||||
List<String> inputValue = new ArrayList<>();
|
||||
inputValue.add("10");
|
||||
|
||||
@@ -413,11 +421,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("genericIndexedMap[1]", inputValue);
|
||||
|
||||
assertThat(holder.getGenericIndexedMap().keySet().iterator().next()).isEqualTo(1);
|
||||
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexGenericIndexedMapEntryWithCollectionConversion() {
|
||||
public void testComplexGenericIndexedMapEntryWithCollectionConversion() {
|
||||
Set<String> inputValue = new HashSet<>();
|
||||
inputValue.add("10");
|
||||
|
||||
@@ -426,11 +434,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("genericIndexedMap[1]", inputValue);
|
||||
|
||||
assertThat(holder.getGenericIndexedMap().keySet().iterator().next()).isEqualTo(1);
|
||||
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexDerivedIndexedMapEntry() {
|
||||
public void testComplexDerivedIndexedMapEntry() {
|
||||
List<String> inputValue = new ArrayList<>();
|
||||
inputValue.add("10");
|
||||
|
||||
@@ -439,11 +447,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("derivedIndexedMap[1]", inputValue);
|
||||
|
||||
assertThat(holder.getDerivedIndexedMap().keySet().iterator().next()).isEqualTo(1);
|
||||
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexDerivedIndexedMapEntryWithCollectionConversion() {
|
||||
public void testComplexDerivedIndexedMapEntryWithCollectionConversion() {
|
||||
Set<String> inputValue = new HashSet<>();
|
||||
inputValue.add("10");
|
||||
|
||||
@@ -452,11 +460,11 @@ class BeanWrapperGenericsTests {
|
||||
bw.setPropertyValue("derivedIndexedMap[1]", inputValue);
|
||||
|
||||
assertThat(holder.getDerivedIndexedMap().keySet().iterator().next()).isEqualTo(1);
|
||||
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
|
||||
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericallyTypedIntegerBean() {
|
||||
public void testGenericallyTypedIntegerBean() throws Exception {
|
||||
GenericIntegerBean gb = new GenericIntegerBean();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("genericProperty", "10");
|
||||
@@ -467,7 +475,7 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenericallyTypedSetOfIntegerBean() {
|
||||
public void testGenericallyTypedSetOfIntegerBean() throws Exception {
|
||||
GenericSetOfIntegerBean gb = new GenericSetOfIntegerBean();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("genericProperty", "10");
|
||||
@@ -478,23 +486,23 @@ class BeanWrapperGenericsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSettingGenericPropertyWithReadOnlyInterface() {
|
||||
public void testSettingGenericPropertyWithReadOnlyInterface() {
|
||||
Bar bar = new Bar();
|
||||
BeanWrapper bw = new BeanWrapperImpl(bar);
|
||||
bw.setPropertyValue("version", "10");
|
||||
assertThat(bar.getVersion()).isEqualTo(Double.valueOf(10.0));
|
||||
assertThat(bar.getVersion()).isEqualTo(new Double(10.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSettingLongPropertyWithGenericInterface() {
|
||||
public void testSettingLongPropertyWithGenericInterface() {
|
||||
Promotion bean = new Promotion();
|
||||
BeanWrapper bw = new BeanWrapperImpl(bean);
|
||||
bw.setPropertyValue("id", "10");
|
||||
assertThat(bean.getId()).isEqualTo(Long.valueOf(10));
|
||||
assertThat(bean.getId()).isEqualTo(new Long(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUntypedPropertyWithMapAtRuntime() {
|
||||
public void testUntypedPropertyWithMapAtRuntime() {
|
||||
class Holder<D> {
|
||||
private final D data;
|
||||
public Holder(D data) {
|
||||
|
||||
@@ -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,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
|
||||
/**
|
||||
* Specific {@link BeanWrapperImpl} tests.
|
||||
@@ -38,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
* @author Chris Beams
|
||||
* @author Dave Syer
|
||||
*/
|
||||
class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
public class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
@Override
|
||||
protected BeanWrapperImpl createAccessor(Object target) {
|
||||
@@ -47,7 +46,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
|
||||
@Test
|
||||
void setterDoesNotCallGetter() {
|
||||
public void setterDoesNotCallGetter() {
|
||||
GetterBean target = new GetterBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("name", "tom");
|
||||
@@ -56,7 +55,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getterSilentlyFailWithOldValueExtraction() {
|
||||
public void getterSilentlyFailWithOldValueExtraction() {
|
||||
GetterBean target = new GetterBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setExtractOldValueForEditor(true); // This will call the getter
|
||||
@@ -66,7 +65,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void aliasedSetterThroughDefaultMethod() {
|
||||
public void aliasedSetterThroughDefaultMethod() {
|
||||
GetterBean target = new GetterBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("aliasedName", "tom");
|
||||
@@ -75,7 +74,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void setValidAndInvalidPropertyValuesShouldContainExceptionDetails() {
|
||||
public void setValidAndInvalidPropertyValuesShouldContainExceptionDetails() {
|
||||
TestBean target = new TestBean();
|
||||
String newName = "tony";
|
||||
String invalidTouchy = ".valid";
|
||||
@@ -92,12 +91,12 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
.getNewValue()).isEqualTo(invalidTouchy);
|
||||
});
|
||||
// Test validly set property matches
|
||||
assertThat(target.getName()).as("Valid set property must stick").isEqualTo(newName);
|
||||
assertThat(target.getAge()).as("Invalid set property must retain old value").isEqualTo(0);
|
||||
assertThat(target.getName().equals(newName)).as("Valid set property must stick").isTrue();
|
||||
assertThat(target.getAge() == 0).as("Invalid set property must retain old value").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkNotWritablePropertyHoldPossibleMatches() {
|
||||
public void checkNotWritablePropertyHoldPossibleMatches() {
|
||||
TestBean target = new TestBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
assertThatExceptionOfType(NotWritablePropertyException.class).isThrownBy(() ->
|
||||
@@ -106,15 +105,15 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test // Can't be shared; there is no such thing as a read-only field
|
||||
void setReadOnlyMapProperty() {
|
||||
public void setReadOnlyMapProperty() {
|
||||
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
|
||||
TypedReadOnlyMapClient target = new TypedReadOnlyMapClient();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
assertThatNoException().isThrownBy(() -> accessor.setPropertyValue("map", map));
|
||||
accessor.setPropertyValue("map", map);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notWritablePropertyExceptionContainsAlternativeMatch() {
|
||||
public void notWritablePropertyExceptionContainsAlternativeMatch() {
|
||||
IntelliBean target = new IntelliBean();
|
||||
BeanWrapper bw = createAccessor(target);
|
||||
try {
|
||||
@@ -122,12 +121,12 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
assertThat(ex.getPossibleMatches()).as("Possible matches not determined").isNotNull();
|
||||
assertThat(ex.getPossibleMatches()).as("Invalid amount of alternatives").hasSize(1);
|
||||
assertThat(ex.getPossibleMatches().length).as("Invalid amount of alternatives").isEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void notWritablePropertyExceptionContainsAlternativeMatches() {
|
||||
public void notWritablePropertyExceptionContainsAlternativeMatches() {
|
||||
IntelliBean target = new IntelliBean();
|
||||
BeanWrapper bw = createAccessor(target);
|
||||
try {
|
||||
@@ -135,23 +134,23 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
assertThat(ex.getPossibleMatches()).as("Possible matches not determined").isNotNull();
|
||||
assertThat(ex.getPossibleMatches()).as("Invalid amount of alternatives").hasSize(3);
|
||||
assertThat(ex.getPossibleMatches().length).as("Invalid amount of alternatives").isEqualTo(3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test // Can't be shared: no type mismatch with a field
|
||||
void setPropertyTypeMismatch() {
|
||||
public void setPropertyTypeMismatch() {
|
||||
PropertyTypeMismatch target = new PropertyTypeMismatch();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("object", "a String");
|
||||
assertThat(target.value).isEqualTo("a String");
|
||||
assertThat(target.getObject()).isEqualTo(8);
|
||||
assertThat(target.getObject() == 8).isTrue();
|
||||
assertThat(accessor.getPropertyValue("object")).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyDescriptors() {
|
||||
public void propertyDescriptors() {
|
||||
TestBean target = new TestBean();
|
||||
target.setSpouse(new TestBean());
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
@@ -167,7 +166,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void getPropertyWithOptional() {
|
||||
public void getPropertyWithOptional() {
|
||||
GetterWithOptional target = new GetterWithOptional();
|
||||
TestBean tb = new TestBean("x");
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
@@ -190,7 +189,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyWithOptionalAndAutoGrow() {
|
||||
public void getPropertyWithOptionalAndAutoGrow() {
|
||||
GetterWithOptional target = new GetterWithOptional();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setAutoGrowNestedPaths(true);
|
||||
@@ -202,7 +201,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void incompletelyQuotedKeyLeadsToPropertyException() {
|
||||
public void incompletelyQuotedKeyLeadsToPropertyException() {
|
||||
TestBean target = new TestBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
assertThatExceptionOfType(NotWritablePropertyException.class).isThrownBy(() ->
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user