Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Buildmaster b1280ffeaa Release v5.3.7 2021-05-12 05:38:51 +00:00
325 changed files with 2462 additions and 4445 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ to start a discussion first or have already created an issue, once a pull reques
created, we will close the issue as superseded by the pull request, and the discussion
about the issue will continue under the pull request.
1. Always check out the `main` branch and submit pull requests against it
1. Always check out the `master` branch and submit pull requests against it
(for target version see [settings.gradle](settings.gradle)).
Backports to prior versions will be considered on a case-by-case basis and reflected as
the fix version in the issue tracker.
+40 -40
View File
@@ -1,7 +1,7 @@
plugins {
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.5.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.5.21' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.0' 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'
@@ -10,7 +10,7 @@ plugins {
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.jetbrains.kotlin.plugin.serialization" version "1.5.0" apply false
id "org.unbroken-dome.xjc" version '2.0.0' apply false
}
@@ -27,16 +27,16 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
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.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"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.3"
mavenBom "io.netty:netty-bom:4.1.63.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.7"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR9"
mavenBom "io.rsocket:rsocket-bom:1.1.0"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.40.v20210413"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.0"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.3"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.0"
mavenBom "org.junit:junit-bom:5.7.1"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
@@ -51,7 +51,7 @@ configure(allprojects) { project ->
}
dependency "com.google.code.findbugs:jsr305:3.0.2"
dependencySet(group: 'org.aspectj', version: '1.9.7') {
dependencySet(group: 'org.aspectj', version: '1.9.6') {
entry 'aspectjrt'
entry 'aspectjtools'
entry 'aspectjweaver'
@@ -67,18 +67,18 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.0.13"
dependency "io.reactivex.rxjava3:rxjava:3.0.12"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.0"
dependency "com.fasterxml:aalto-xml:1.2.2"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") {
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.7"
dependency "com.google.protobuf:protobuf-java-util:3.17.3"
dependency "com.google.code.gson:gson:2.8.6"
dependency "com.google.protobuf:protobuf-java-util:3.15.8"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.17") {
dependency("com.thoughtworks.xstream:xstream:1.4.16") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
@@ -91,7 +91,7 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.29"
dependency "org.yaml:snakeyaml:1.28"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.1"
@@ -100,7 +100,7 @@ configure(allprojects) { project ->
dependency "commons-io:commons-io:2.5"
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') {
dependencySet(group: 'org.apache.activemq', version: '5.16.1') {
entry 'activemq-broker'
entry('activemq-kahadb-store') {
exclude group: "org.springframework", name: "spring-context"
@@ -116,29 +116,29 @@ configure(allprojects) { project ->
dependency "org.apache.poi:poi-ooxml:4.1.2"
dependency "org.apache-extras.beanshell:bsh:2.0b6"
dependency "org.freemarker:freemarker:2.3.31"
dependency "org.hsqldb:hsqldb:2.5.2"
dependency "org.hsqldb:hsqldb:2.5.1"
dependency "org.quartz-scheduler:quartz:2.3.2"
dependency "org.codehaus.fabric3.api:commonj:1.1.0"
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.32.Final"
dependency "org.hibernate:hibernate-core:5.4.31.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.47"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.50') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.45') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.50') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.45') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.8.Final') {
dependencySet(group: 'io.undertow', version: '2.2.7.Final') {
entry 'undertow-core'
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
@@ -159,11 +159,11 @@ configure(allprojects) { project ->
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.apache.httpcomponents.client5:httpclient5:5.0.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.3'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.6"
dependency "org.jruby:jruby:9.2.19.0"
dependency "org.jruby:jruby:9.2.16.0"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
@@ -189,25 +189,25 @@ configure(allprojects) { project ->
dependency "org.testng:testng:7.4.0"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.20.2"
dependency "org.assertj:assertj-core:3.19.0"
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: '3.11.0') {
dependencySet(group: 'org.mockito', version: '3.9.0') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.11.0"
dependency "io.mockk:mockk:1.10.2"
dependency("net.sourceforge.htmlunit:htmlunit:2.51.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.49.1") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.51.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.49.1") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -236,7 +236,7 @@ configure(allprojects) { project ->
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.10"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.8"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -316,7 +316,7 @@ configure([rootProject] + javaProjects) { project ->
kotlinOptions {
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-Xopt-in=kotlin.RequiresOptIn"]
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings"]
allWarningsAsErrors = true
}
}
@@ -336,7 +336,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.44"
toolVersion = "8.42"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -375,10 +375,10 @@ configure([rootProject] + javaProjects) { project ->
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
"https://junit.org/junit5/docs/5.7.2/api/"
"https://junit.org/junit5/docs/5.7.1/api/"
] as String[]
}
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.9
version=5.3.7
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+1 -13
View File
@@ -103,12 +103,9 @@ dokka {
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/")
}
@@ -130,8 +127,6 @@ task extractDocResources(type: Copy, dependsOn: downloadResources) {
}
asciidoctorj {
def docRoot = 'https://docs.spring.io'
def docsSpringFramework = "${docRoot}/spring-framework/docs/${project.version}"
version = '2.4.1'
fatalWarnings ".*"
options doctype: 'book', eruby: 'erubis'
@@ -148,11 +143,7 @@ asciidoctorj {
'highlightjs-theme': 'googlecode',
stylesdir: 'css/',
stylesheet: 'stylesheet.css',
'spring-version': project.version,
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main',
'doc-root': docRoot,
'docs-spring-framework': docsSpringFramework,
'api-spring-framework': "${docsSpringFramework}/javadoc-api/org/springframework"
'spring-version': project.version
])
}
@@ -163,9 +154,6 @@ asciidoctorj {
asciidoctor {
baseDirFollowsSourceDir()
configurations 'asciidoctorExt'
attributes([
noheader: '' // custom header in docinfo-header.html
])
sources {
include '*.adoc'
}
@@ -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.
@@ -625,7 +625,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
StringBuilder sb = new StringBuilder();
if (bodyStart >= 0 && bodyStart != (currentToken.length() - 1)) {
sb.append(currentToken.substring(bodyStart + 1));
sb.append(' ');
sb.append(" ");
}
numTokensConsumed++;
int currentIndex = startIndex + numTokensConsumed;
@@ -645,7 +645,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
toAppend = toAppend.substring(1);
}
sb.append(toAppend);
sb.append(' ');
sb.append(" ");
currentIndex++;
numTokensConsumed++;
}
@@ -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.
@@ -547,7 +547,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
StringBuilder sb = new StringBuilder("AspectJExpressionPointcut: (");
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
sb.append(this.pointcutParameterTypes[i].getName());
sb.append(' ');
sb.append(" ");
sb.append(this.pointcutParameterNames[i]);
if ((i+1) < this.pointcutParameterTypes.length) {
sb.append(", ");
@@ -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.
@@ -255,19 +255,19 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
StringBuilder sb = new StringBuilder();
if (includeModifier) {
sb.append(Modifier.toString(getModifiers()));
sb.append(' ');
sb.append(" ");
}
if (includeReturnTypeAndArgs) {
appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
sb.append(' ');
sb.append(" ");
}
appendType(sb, getDeclaringType(), useLongTypeName);
sb.append('.');
sb.append(".");
sb.append(getMethod().getName());
sb.append('(');
sb.append("(");
Class<?>[] parametersTypes = getParameterTypes();
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
sb.append(')');
sb.append(")");
return sb.toString();
}
@@ -278,7 +278,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(',');
sb.append(",");
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,7 @@ package org.springframework.aop.framework;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
@@ -31,9 +29,7 @@ import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.core.DecoratingProxy;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
/**
* Utility methods for AOP proxy factories.
@@ -48,11 +44,6 @@ import org.springframework.util.ReflectionUtils;
*/
public abstract class AopProxyUtils {
// JDK 17 Class.isSealed() method available?
@Nullable
private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed");
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
@@ -139,23 +130,34 @@ public abstract class AopProxyUtils {
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
for (Class<?> ifc : specifiedInterfaces) {
// Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17)
if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
proxiedInterfaces.add(ifc);
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (!advised.isInterfaceProxied(SpringProxy.class)) {
proxiedInterfaces.add(SpringProxy.class);
if (addAdvised) {
nonUserIfcCount++;
}
if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
proxiedInterfaces.add(Advised.class);
if (addDecoratingProxy) {
nonUserIfcCount++;
}
if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
proxiedInterfaces.add(DecoratingProxy.class);
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
return ClassUtils.toClassArray(proxiedInterfaces);
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
/**
@@ -17,7 +17,6 @@
package org.springframework.aop.framework.autoproxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -441,17 +440,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
@@ -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.
@@ -137,7 +137,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append(": advice ");
if (this.adviceBeanName != null) {
sb.append("bean '").append(this.adviceBeanName).append('\'');
sb.append("bean '").append(this.adviceBeanName).append("'");
}
else {
sb.append(this.advice);
@@ -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.
@@ -71,8 +71,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
if (introductionInfo != null) {
Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
if (introducedInterfaces.length == 0) {
throw new IllegalArgumentException(
"IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces");
}
for (Class<?> ifc : introducedInterfaces) {
addInterface(ifc);
@@ -191,9 +191,9 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
sb.append(" for target bean '").append(this.targetBeanName).append('\'');
sb.append(" for target bean '").append(this.targetBeanName).append("'");
if (this.targetClass != null) {
sb.append(" of type [").append(this.targetClass.getName()).append(']');
sb.append(" of type [").append(this.targetClass.getName()).append("]");
}
return sb.toString();
}
@@ -276,14 +276,14 @@ public class AspectJAdviceParameterNameDiscovererTests {
private static String format(String[] names) {
StringBuilder sb = new StringBuilder();
sb.append('(');
sb.append("(");
for (int i = 0; i < names.length; i++) {
sb.append(names[i]);
if ((i + 1) < names.length) {
sb.append(',');
sb.append(",");
}
}
sb.append(')');
sb.append(")");
return sb.toString();
}
@@ -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.
@@ -183,7 +183,7 @@ public class ProxyFactoryTests {
}
@Test
public void testGetsAllInterfaces() {
public void testGetsAllInterfaces() throws Exception {
// Extend to get new interface
class TestBeanSubclass extends TestBean implements Comparable<Object> {
@Override
@@ -240,16 +240,6 @@ public class ProxyFactoryTests {
assertThat(factory.countAdvicesOfType(NopInterceptor.class) == 2).isTrue();
}
@Test
public void testSealedInterfaceExclusion() {
// String implements ConstantDesc on JDK 12+, sealed as of JDK 17
ProxyFactory factory = new ProxyFactory(new String());
NopInterceptor di = new NopInterceptor();
factory.addAdvice(0, di);
Object proxy = factory.getProxy();
assertThat(proxy).isInstanceOf(CharSequence.class);
}
/**
* Should see effect immediately on behavior.
*/
@@ -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.
@@ -41,6 +41,8 @@ import kotlin.reflect.KParameter;
import kotlin.reflect.full.KClasses;
import kotlin.reflect.jvm.KCallablesJvm;
import kotlin.reflect.jvm.ReflectJvmMapping;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.KotlinDetector;
@@ -73,6 +75,8 @@ import org.springframework.util.StringUtils;
*/
public abstract class BeanUtils {
private static final Log logger = LogFactory.getLog(BeanUtils.class);
private static final ParameterNameDiscoverer parameterNameDiscoverer =
new DefaultParameterNameDiscoverer();
@@ -547,6 +551,9 @@ public abstract class BeanUtils {
}
catch (Throwable ex) {
// e.g. AccessControlException on Google App Engine
if (logger.isDebugEnabled()) {
logger.debug("Could not access system ClassLoader: " + ex);
}
return null;
}
}
@@ -557,6 +564,10 @@ public abstract class BeanUtils {
Class<?> editorClass = cl.loadClass(editorName);
if (editorClass != null) {
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
unknownEditorTypes.add(targetType);
return null;
}
@@ -568,6 +579,10 @@ public abstract class BeanUtils {
catch (ClassNotFoundException ex) {
// Ignore - fall back to unknown editor type registration below
}
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
}
@@ -247,14 +247,14 @@ class TypeConverterDelegate {
// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
StringBuilder msg = new StringBuilder();
msg.append("Cannot convert value of type '").append(ClassUtils.getDescriptiveType(newValue));
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append('\'');
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append("'");
if (propertyName != null) {
msg.append(" for property '").append(propertyName).append('\'');
msg.append(" for property '").append(propertyName).append("'");
}
if (editor != null) {
msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
"] returned inappropriate value of type '").append(
ClassUtils.getDescriptiveType(convertedValue)).append('\'');
ClassUtils.getDescriptiveType(convertedValue)).append("'");
throw new IllegalArgumentException(msg.toString());
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ import org.springframework.lang.Nullable;
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom {@code init-method} definition
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
@@ -92,7 +92,7 @@ import org.springframework.lang.Nullable;
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom {@code destroy-method} definition
* <li>a custom destroy-method definition
* </ol>
*
* @author Rod Johnson
@@ -102,8 +102,6 @@ import org.springframework.lang.Nullable;
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.EnvironmentAware#setEnvironment
* @see org.springframework.context.EmbeddedValueResolverAware#setEmbeddedValueResolver
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
@@ -113,7 +111,6 @@ import org.springframework.lang.Nullable;
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
@@ -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.
@@ -217,13 +217,13 @@ public class RequiredAnnotationBeanPostProcessor implements SmartInstantiationAw
sb.append(" and");
}
else {
sb.append(',');
sb.append(",");
}
}
sb.append(" '").append(propertyName).append('\'');
sb.append(" '").append(propertyName).append("'");
}
sb.append(size == 1 ? " is" : " are");
sb.append(" required for bean '").append(beanName).append('\'');
sb.append(" required for bean '").append(beanName).append("'");
return sb.toString();
}
@@ -489,9 +489,9 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class<?>) args[1], constructorArgs);
Map<?, ?> namedArgs = (Map<?, ?>) args[0];
for (Map.Entry<?, ?> entity : namedArgs.entrySet()) {
String propName = (String) entity.getKey();
setProperty(propName, entity.getValue());
for (Object key : namedArgs.keySet()) {
String propName = (String) key;
setProperty(propName, namedArgs.get(propName));
}
}
// factory method syntax
@@ -1241,7 +1241,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
@Override
public String toString() {
StringBuilder sb = new StringBuilder("class [");
sb.append(getBeanClassName()).append(']');
sb.append(getBeanClassName()).append("]");
sb.append("; scope=").append(this.scope);
sb.append("; abstract=").append(this.abstractFlag);
sb.append("; lazyInit=").append(this.lazyInit);
@@ -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.
@@ -21,7 +21,6 @@ import java.util.function.Supplier;
import org.springframework.beans.factory.config.AutowiredPropertyMarker;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
@@ -103,7 +102,7 @@ public final class BeanDefinitionBuilder {
* @param beanClass the {@code Class} of the bean that the definition is being created for
*/
public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass) {
return rootBeanDefinition(beanClass, (String) null);
return rootBeanDefinition(beanClass, null);
}
/**
@@ -118,30 +117,6 @@ public final class BeanDefinitionBuilder {
return builder;
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}.
* @param beanType the {@link ResolvableType type} of the bean that the definition is being created for
* @param instanceSupplier a callback for creating an instance of the bean
* @since 5.3.9
*/
public static <T> BeanDefinitionBuilder rootBeanDefinition(ResolvableType beanType, Supplier<T> instanceSupplier) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setTargetType(beanType);
beanDefinition.setInstanceSupplier(instanceSupplier);
return new BeanDefinitionBuilder(beanDefinition);
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}.
* @param beanClass the {@code Class} of the bean that the definition is being created for
* @param instanceSupplier a callback for creating an instance of the bean
* @since 5.3.9
* @see #rootBeanDefinition(ResolvableType, Supplier)
*/
public static <T> BeanDefinitionBuilder rootBeanDefinition(Class<T> beanClass, Supplier<T> instanceSupplier) {
return rootBeanDefinition(ResolvableType.forClass(beanClass), instanceSupplier);
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link ChildBeanDefinition}.
* @param parentName the name of the parent bean
@@ -356,16 +331,6 @@ public final class BeanDefinitionBuilder {
return this;
}
/**
* Set whether this bean is 'synthetic', that is, not defined by
* the application itself.
* @since 5.3.9
*/
public BeanDefinitionBuilder setSynthetic(boolean synthetic) {
this.beanDefinition.setSynthetic(synthetic);
return this;
}
/**
* Apply the given customizers to the underlying bean definition.
* @since 5.0
@@ -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.
@@ -35,7 +35,6 @@ import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -245,10 +244,8 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
return (bean.equals(null) ? null : bean);
}
else {
// Find target bean matching the (potentially generic) method return type
ResolvableType genericReturnType = ResolvableType.forMethodReturnType(method);
return (argsToUse != null ? this.owner.getBeanProvider(genericReturnType).getObject(argsToUse) :
this.owner.getBeanProvider(genericReturnType).getObject());
return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
this.owner.getBean(method.getReturnType()));
}
}
}
@@ -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.
@@ -277,12 +277,12 @@ class ConstructorResolver {
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
@@ -608,7 +608,7 @@ class ConstructorResolver {
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found on class [" + factoryClass.getName() + "]: " +
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
@@ -619,12 +619,12 @@ class ConstructorResolver {
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" +
factoryClass.getName() + "]: needs to have a non-void return type!");
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
@@ -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.
@@ -19,25 +19,17 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* Represents an override of a method that looks up an object in the same IoC context,
* either by bean name or by bean type (based on the declared method return type).
* Represents an override of a method that looks up an object in the same IoC context.
*
* <p>Methods eligible for lookup override may declare arguments in which case the
* given arguments are passed to the bean retrieval operation.
* <p>Methods eligible for lookup override must not have arguments.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.1
* @see org.springframework.beans.factory.BeanFactory#getBean(String)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class)
* @see org.springframework.beans.factory.BeanFactory#getBean(String, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBeanProvider(ResolvableType)
*/
public class LookupOverride extends MethodOverride {
@@ -51,8 +43,8 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param methodName the name of the method to override
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
*/
public LookupOverride(String methodName, @Nullable String beanName) {
super(methodName);
@@ -61,9 +53,9 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param method the method declaration to override
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
* @param method the method to override
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
*/
public LookupOverride(Method method, @Nullable String beanName) {
super(method.getName());
@@ -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.
@@ -19,8 +19,9 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
/**
* Interface to be implemented by classes that can reimplement any method on an
* IoC-managed object: the <b>Method Injection</b> form of Dependency Injection.
* Interface to be implemented by classes that can reimplement any method
* on an IoC-managed object: the <b>Method Injection</b> form of
* Dependency Injection.
*
* <p>Such methods may be (but need not be) abstract, in which case the
* container will create a concrete subclass to instantiate.
@@ -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.
@@ -25,7 +25,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Extension of {@link MethodOverride} that represents an arbitrary
* Extension of MethodOverride that represents an arbitrary
* override of a method by the IoC container.
*
* <p>Any non-final method can be overridden, irrespective of its
@@ -45,7 +45,7 @@ public class ReplaceOverride extends MethodOverride {
/**
* Construct a new ReplaceOverride.
* @param methodName the name of the method to override
* @param methodReplacerBeanName the bean name of the {@link MethodReplacer}
* @param methodReplacerBeanName the bean name of the MethodReplacer
*/
public ReplaceOverride(String methodName, String methodReplacerBeanName) {
super(methodName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,14 @@ package org.springframework.beans;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,21 +36,23 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Chris Beams
* @since 08.03.2004
*/
class ConcurrentBeanWrapperTests {
public class ConcurrentBeanWrapperTests {
private final Log logger = LogFactory.getLog(getClass());
private final Set<TestRun> set = ConcurrentHashMap.newKeySet();
private Set<TestRun> set = Collections.synchronizedSet(new HashSet<TestRun>());
private Throwable ex = null;
@RepeatedTest(100)
void testSingleThread() {
performSet();
@Test
public void testSingleThread() {
for (int i = 0; i < 100; i++) {
performSet();
}
}
@Test
void testConcurrent() {
public void testConcurrent() {
for (int i = 0; i < 10; i++) {
TestRun run = new TestRun(this);
set.add(run);
@@ -80,7 +82,7 @@ class ConcurrentBeanWrapperTests {
Properties p = (Properties) System.getProperties().clone();
assertThat(p).as("The System properties must not be empty").isNotEmpty();
assertThat(p.size() != 0).as("The System properties must not be empty").isTrue();
for (Iterator<?> i = p.entrySet().iterator(); i.hasNext();) {
i.next();
@@ -109,7 +111,7 @@ class ConcurrentBeanWrapperTests {
private ConcurrentBeanWrapperTests test;
TestRun(ConcurrentBeanWrapperTests test) {
public TestRun(ConcurrentBeanWrapperTests test) {
this.test = test;
}
@@ -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.
@@ -31,7 +31,6 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.ro
* invoking a factory method is not instructive to the user and rather misleading.
*
* @author Chris Beams
* @author Juergen Hoeller
*/
public class Spr5475Tests {
@@ -41,8 +40,7 @@ public class Spr5475Tests {
rootBeanDefinition(Foo.class)
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg").getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String)'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String)'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -53,8 +51,7 @@ public class Spr5475Tests {
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg1")
.addConstructorArgValue("bogusArg2".getBytes()).getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -68,8 +65,7 @@ public class Spr5475Tests {
def.setConstructorArgumentValues(cav);
assertExceptionMessageForMisconfiguredFactoryMethod(def,
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -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.
@@ -121,18 +121,6 @@ public class LookupAnnotationTests {
assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean);
}
@Test
public void testWithGenericBean() {
beanFactory.registerBeanDefinition("numberBean", new RootBeanDefinition(NumberBean.class));
beanFactory.registerBeanDefinition("doubleStore", new RootBeanDefinition(DoubleStore.class));
beanFactory.registerBeanDefinition("floatStore", new RootBeanDefinition(FloatStore.class));
NumberBean bean = (NumberBean) beanFactory.getBean("numberBean");
assertThat(bean).isNotNull();
assertThat(beanFactory.getBean(DoubleStore.class)).isSameAs(bean.getDoubleStore());
assertThat(beanFactory.getBean(FloatStore.class)).isSameAs(bean.getFloatStore());
}
public static abstract class AbstractBean {
@@ -159,26 +147,4 @@ public class LookupAnnotationTests {
AbstractBean abstractBean;
}
public static class NumberStore<T extends Number> {
}
public static class DoubleStore extends NumberStore<Double> {
}
public static class FloatStore extends NumberStore<Float> {
}
public static abstract class NumberBean {
@Lookup
public abstract NumberStore<Double> getDoubleStore();
@Lookup
public abstract NumberStore<Float> getFloatStore();
}
}
@@ -141,7 +141,6 @@ class YamlProcessorTests {
}
@Test
@SuppressWarnings("unchecked")
void standardTypesSupportedByDefault() throws Exception {
setYaml("value: !!set\n ? first\n ? second");
this.processor.process((properties, map) -> {
@@ -17,25 +17,22 @@
package org.springframework.beans.factory.support;
import java.util.Arrays;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Stephane Nicoll
*/
class BeanDefinitionBuilderTests {
public class BeanDefinitionBuilderTests {
@Test
void builderWithBeanClassWithSimpleProperty() {
public void beanClassWithSimpleProperty() {
String[] dependsOn = new String[] { "A", "B", "C" };
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE);
@@ -52,7 +49,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassAndFactoryMethod() {
public void beanClassWithFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class, "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isTrue();
@@ -61,7 +58,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassName() {
public void beanClassName() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName());
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -69,7 +66,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassNameAndFactoryMethod() {
public void beanClassNameWithFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName(), "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -77,78 +74,4 @@ class BeanDefinitionBuilderTests {
assertThat(rbd.getFactoryMethodName()).isEqualTo("create");
}
@Test
void builderWithResolvableTypeAndInstanceSupplier() {
ResolvableType type = ResolvableType.forClassWithGenerics(Function.class, Integer.class, String.class);
Function<Integer, String> function = i -> "value " + i;
RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder
.rootBeanDefinition(type, () -> function).getBeanDefinition();
assertThat(rbd.getResolvableType()).isEqualTo(type);
assertThat(rbd.getInstanceSupplier()).isNotNull();
assertThat(rbd.getInstanceSupplier().get()).isInstanceOf(Function.class);
}
@Test
void builderWithBeanClassAndInstanceSupplier() {
RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder
.rootBeanDefinition(String.class, () -> "test").getBeanDefinition();
assertThat(rbd.getResolvableType().resolve()).isEqualTo(String.class);
assertThat(rbd.getInstanceSupplier()).isNotNull();
assertThat(rbd.getInstanceSupplier().get()).isEqualTo("test");
}
@Test
void builderWithAutowireMode() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE).getBeanDefinition().getAutowireMode())
.isEqualTo(RootBeanDefinition.AUTOWIRE_BY_TYPE);
}
@Test
void builderWithDependencyCheck() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_ALL)
.getBeanDefinition().getDependencyCheck())
.isEqualTo(RootBeanDefinition.DEPENDENCY_CHECK_ALL);
}
@Test
void builderWithDependsOn() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class).addDependsOn("test")
.addDependsOn("test2").getBeanDefinition().getDependsOn())
.containsExactly("test", "test2");
}
@Test
void builderWithPrimary() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setPrimary(true).getBeanDefinition().isPrimary()).isTrue();
}
@Test
void builderWithRole() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition().getRole())
.isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
}
@Test
void builderWithSynthetic() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setSynthetic(true).getBeanDefinition().isSynthetic()).isTrue();
}
@Test
void builderWithCustomizers() {
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.applyCustomizers(builder -> {
builder.setFactoryMethodName("create");
builder.setRole(BeanDefinition.ROLE_SUPPORT);
})
.applyCustomizers(builder -> builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE))
.getBeanDefinition();
assertThat(beanDefinition.getFactoryMethodName()).isEqualTo("create");
assertThat(beanDefinition.getRole()).isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
}
}
@@ -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.
@@ -36,7 +36,7 @@ public class LookupMethodTests {
@BeforeEach
public void setup() {
public void setUp() {
beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("lookupMethodTests.xml", getClass()));
@@ -83,8 +83,8 @@ public class LookupMethodTests {
public void testWithThreeArgsShouldFail() {
AbstractBean bean = (AbstractBean) beanFactory.getBean("abstractBean");
assertThat(bean).isNotNull();
assertThatExceptionOfType(AbstractMethodError.class).as("does not have a three arg constructor")
.isThrownBy(() -> bean.getThreeArguments("name", 1, 2));
assertThatExceptionOfType(AbstractMethodError.class).as("does not have a three arg constructor").isThrownBy(() ->
bean.getThreeArguments("name", 1, 2));
}
@Test
@@ -97,21 +97,6 @@ public class LookupMethodTests {
assertThat(expected.isJedi()).isTrue();
}
@Test
public void testWithGenericBean() {
RootBeanDefinition bd = new RootBeanDefinition(NumberBean.class);
bd.getMethodOverrides().addOverride(new LookupOverride("getDoubleStore", null));
bd.getMethodOverrides().addOverride(new LookupOverride("getFloatStore", null));
beanFactory.registerBeanDefinition("numberBean", bd);
beanFactory.registerBeanDefinition("doubleStore", new RootBeanDefinition(DoubleStore.class));
beanFactory.registerBeanDefinition("floatStore", new RootBeanDefinition(FloatStore.class));
NumberBean bean = (NumberBean) beanFactory.getBean("numberBean");
assertThat(bean).isNotNull();
assertThat(beanFactory.getBean(DoubleStore.class)).isSameAs(bean.getDoubleStore());
assertThat(beanFactory.getBean(FloatStore.class)).isSameAs(bean.getFloatStore());
}
public static abstract class AbstractBean {
@@ -126,24 +111,4 @@ public class LookupMethodTests {
public abstract TestBean getThreeArguments(String name, int age, int anotherArg);
}
public static class NumberStore<T extends Number> {
}
public static class DoubleStore extends NumberStore<Double> {
}
public static class FloatStore extends NumberStore<Float> {
}
public static abstract class NumberBean {
public abstract NumberStore<Double> getDoubleStore();
public abstract NumberStore<Float> getFloatStore();
}
}
@@ -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.
@@ -244,7 +244,7 @@ public class QualifierAnnotationAutowireBeanFactoryTests {
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
private @interface TestQualifier {
private static @interface TestQualifier {
}
}
@@ -36,7 +36,7 @@ import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
/**
* Annotation {@link Processor} that writes a {@link CandidateComponentsMetadata}
* Annotation {@link Processor} that writes {@link CandidateComponentsMetadata}
* file for spring components.
*
* @author Stephane Nicoll
@@ -26,7 +26,7 @@ import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} implementation that extracts the stereotypes
* flagged by the {@value #INDEXED_ANNOTATION} annotation. This implementation
* flagged by the {@value INDEXED_ANNOTATION} annotation. This implementation
* honors stereotypes defined this way on meta-annotations.
*
* @author Stephane Nicoll
@@ -24,7 +24,7 @@ import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} implementation that provides the
* {@value #STEREOTYPE} stereotype for each package-info.
* {@value STEREOTYPE} stereotype for each package-info.
*
* @author Stephane Nicoll
* @since 5.0
@@ -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.
@@ -24,8 +24,8 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} that extracts a stereotype for each
* {@code javax.*} annotation <i>present</i> on a class or interface.
* A {@link StereotypesProvider} that extract a stereotype for each
* {@code javax.*} annotation placed on a class or interface.
*
* @author Stephane Nicoll
* @since 5.0
@@ -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.
@@ -22,7 +22,7 @@ import javax.lang.model.element.Element;
/**
* Provide the list of stereotypes that match an {@link Element}.
* <p>If an element has one or more stereotypes, it is referenced in the index
* If an element has one more stereotypes, it is referenced in the index
* of candidate components and each stereotype can be queried individually.
*
* @author Stephane Nicoll
@@ -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.
@@ -138,7 +138,7 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp
@Override
public String toString() {
return getOperationDescription().append(']').toString();
return getOperationDescription().append("]").toString();
}
/**
@@ -148,7 +148,7 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp
protected StringBuilder getOperationDescription() {
StringBuilder result = new StringBuilder();
result.append(getClass().getSimpleName());
result.append('[');
result.append("[");
result.append(this.methodDetails);
return result;
}
@@ -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.
@@ -71,9 +71,9 @@ public class CacheEvictOperation extends CacheOperation {
@Override
protected StringBuilder getOperationDescription() {
StringBuilder sb = super.getOperationDescription();
sb.append(',');
sb.append(",");
sb.append(this.cacheWide);
sb.append(',');
sb.append(",");
sb.append(this.beforeInvocation);
return sb;
}
@@ -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.
@@ -216,13 +216,13 @@ public abstract class CacheOperation implements BasicOperation {
*/
protected StringBuilder getOperationDescription() {
StringBuilder result = new StringBuilder(getClass().getSimpleName());
result.append('[').append(this.name);
result.append("[").append(this.name);
result.append("] caches=").append(this.cacheNames);
result.append(" | key='").append(this.key);
result.append("' | keyGenerator='").append(this.keyGenerator);
result.append("' | cacheManager='").append(this.cacheManager);
result.append("' | cacheResolver='").append(this.cacheResolver);
result.append("' | condition='").append(this.condition).append('\'');
result.append("' | condition='").append(this.condition).append("'");
return result;
}
@@ -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.
@@ -66,7 +66,7 @@ public class CachePutOperation extends CacheOperation {
StringBuilder sb = super.getOperationDescription();
sb.append(" | unless='");
sb.append(this.unless);
sb.append('\'');
sb.append("'");
return sb;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,10 +79,10 @@ public class CacheableOperation extends CacheOperation {
StringBuilder sb = super.getOperationDescription();
sb.append(" | unless='");
sb.append(this.unless);
sb.append('\'');
sb.append("'");
sb.append(" | sync='");
sb.append(this.sync);
sb.append('\'');
sb.append("'");
return sb;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.context;
import java.time.Clock;
import java.util.EventObject;
/**
@@ -38,37 +37,18 @@ public abstract class ApplicationEvent extends EventObject {
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to {@link System#currentTimeMillis()}.
* Create a new {@code ApplicationEvent}.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @see #ApplicationEvent(Object, Clock)
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to the value returned by {@link Clock#millis()} in the provided {@link Clock}.
* <p>This constructor is typically used in testing scenarios.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @param clock a clock which will provide the timestamp
* @since 5.3.8
* @see #ApplicationEvent(Object)
*/
public ApplicationEvent(Object source, Clock clock) {
super(source);
this.timestamp = clock.millis();
}
/**
* Return the time in milliseconds when the event occurred.
* @see #ApplicationEvent(Object)
* @see #ApplicationEvent(Object, Clock)
* Return the system time in milliseconds when the event occurred.
*/
public final long getTimestamp() {
return this.timestamp;
@@ -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.
@@ -19,15 +19,13 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
/**
* Represents a {@link Configuration @Configuration} class method annotated with
* {@link Bean @Bean}.
* Represents a {@link Configuration @Configuration} class method marked with the
* {@link Bean @Bean} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
* @see ConfigurationClass
* @see ConfigurationClassParser
@@ -35,7 +33,7 @@ import org.springframework.lang.Nullable;
*/
final class BeanMethod extends ConfigurationMethod {
BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
public BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
super(metadata, configurationClass);
}
@@ -54,28 +52,12 @@ final class BeanMethod extends ConfigurationMethod {
}
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof BeanMethod) &&
this.metadata.equals(((BeanMethod) obj).metadata)));
}
@Override
public int hashCode() {
return this.metadata.hashCode();
}
@Override
public String toString() {
return "BeanMethod: " + this.metadata;
}
private class NonOverridableMethodError extends Problem {
NonOverridableMethodError() {
public NonOverridableMethodError() {
super(String.format("@Bean method '%s' must not be private or final; change the method's modifiers to continue",
getMetadata().getMethodName()), getResourceLocation());
}
}
}
@@ -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.
@@ -36,7 +36,7 @@ import org.springframework.util.ClassUtils;
/**
* Represents a user-defined {@link Configuration @Configuration} class.
* <p>Includes a set of {@link Bean} methods, including all such methods
* Includes a set of {@link Bean} methods, including all such methods
* defined in the ancestry of the class, in a 'flattened-out' manner.
*
* @author Chris Beams
@@ -74,7 +74,7 @@ final class ConfigurationClass {
* @param beanName must not be {@code null}
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(MetadataReader metadataReader, String beanName) {
public ConfigurationClass(MetadataReader metadataReader, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
@@ -89,7 +89,7 @@ final class ConfigurationClass {
* @param importedBy the configuration class importing this one or {@code null}
* @since 3.1.1
*/
ConfigurationClass(MetadataReader metadataReader, @Nullable ConfigurationClass importedBy) {
public ConfigurationClass(MetadataReader metadataReader, @Nullable ConfigurationClass importedBy) {
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
this.importedBy.add(importedBy);
@@ -101,7 +101,7 @@ final class ConfigurationClass {
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(Class<?> clazz, String beanName) {
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = AnnotationMetadata.introspect(clazz);
this.resource = new DescriptiveResource(clazz.getName());
@@ -116,7 +116,7 @@ final class ConfigurationClass {
* @param importedBy the configuration class importing this one (or {@code null})
* @since 3.1.1
*/
ConfigurationClass(Class<?> clazz, @Nullable ConfigurationClass importedBy) {
public ConfigurationClass(Class<?> clazz, @Nullable ConfigurationClass importedBy) {
this.metadata = AnnotationMetadata.introspect(clazz);
this.resource = new DescriptiveResource(clazz.getName());
this.importedBy.add(importedBy);
@@ -128,7 +128,7 @@ final class ConfigurationClass {
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(AnnotationMetadata metadata, String beanName) {
public ConfigurationClass(AnnotationMetadata metadata, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = metadata;
this.resource = new DescriptiveResource(metadata.getClassName());
@@ -136,19 +136,19 @@ final class ConfigurationClass {
}
AnnotationMetadata getMetadata() {
public AnnotationMetadata getMetadata() {
return this.metadata;
}
Resource getResource() {
public Resource getResource() {
return this.resource;
}
String getSimpleName() {
public String getSimpleName() {
return ClassUtils.getShortName(getMetadata().getClassName());
}
void setBeanName(String beanName) {
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@@ -171,7 +171,7 @@ final class ConfigurationClass {
* Merge the imported-by declarations from the given configuration class into this one.
* @since 4.0.5
*/
void mergeImportedBy(ConfigurationClass otherConfigClass) {
public void mergeImportedBy(ConfigurationClass otherConfigClass) {
this.importedBy.addAll(otherConfigClass.importedBy);
}
@@ -181,35 +181,35 @@ final class ConfigurationClass {
* @since 4.0.5
* @see #isImported()
*/
Set<ConfigurationClass> getImportedBy() {
public Set<ConfigurationClass> getImportedBy() {
return this.importedBy;
}
void addBeanMethod(BeanMethod method) {
public void addBeanMethod(BeanMethod method) {
this.beanMethods.add(method);
}
Set<BeanMethod> getBeanMethods() {
public Set<BeanMethod> getBeanMethods() {
return this.beanMethods;
}
void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
public void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
this.importedResources.put(importedResource, readerClass);
}
void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
public void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
}
Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> getImportBeanDefinitionRegistrars() {
public Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> getImportBeanDefinitionRegistrars() {
return this.importBeanDefinitionRegistrars;
}
Map<String, Class<? extends BeanDefinitionReader>> getImportedResources() {
public Map<String, Class<? extends BeanDefinitionReader>> getImportedResources() {
return this.importedResources;
}
void validate(ProblemReporter problemReporter) {
public void validate(ProblemReporter problemReporter) {
// A configuration class may not be final (CGLIB limitation) unless it declares proxyBeanMethods=false
Map<String, Object> attributes = this.metadata.getAnnotationAttributes(Configuration.class.getName());
if (attributes != null && (Boolean) attributes.get("proxyBeanMethods")) {
@@ -244,7 +244,7 @@ final class ConfigurationClass {
*/
private class FinalConfigurationProblem extends Problem {
FinalConfigurationProblem() {
public FinalConfigurationProblem() {
super(String.format("@Configuration class '%s' may not be final. Remove the final modifier to continue.",
getSimpleName()), new Location(getResource(), getMetadata()));
}
@@ -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.
@@ -51,9 +51,18 @@ abstract class ConfigurationMethod {
return new Location(this.configurationClass.getResource(), this.metadata);
}
void validate(ProblemReporter problemReporter) {
String getFullyQualifiedMethodName() {
return this.metadata.getDeclaringClassName() + "#" + this.metadata.getMethodName();
}
static String getShortMethodName(String fullyQualifiedMethodName) {
return fullyQualifiedMethodName.substring(fullyQualifiedMethodName.indexOf('#') + 1);
}
public void validate(ProblemReporter problemReporter) {
}
@Override
public String toString() {
return String.format("[%s:name=%s,declaringClass=%s]",
@@ -396,7 +396,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
* @param message error message to append the HandlerMethod details to
*/
protected String getDetailedErrorMessage(Object bean, String message) {
StringBuilder sb = new StringBuilder(message).append('\n');
StringBuilder sb = new StringBuilder(message).append("\n");
sb.append("HandlerMethod details: \n");
sb.append("Bean [").append(bean.getClass().getName()).append("]\n");
sb.append("Method [").append(this.method.toGenericString()).append("]\n");
@@ -426,7 +426,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
StringBuilder sb = new StringBuilder(getDetailedErrorMessage(bean, message));
sb.append("Resolved arguments: \n");
for (int i = 0; i < resolvedArgs.length; i++) {
sb.append('[').append(i).append("] ");
sb.append("[").append(i).append("] ");
if (resolvedArgs[i] == null) {
sb.append("[null] \n");
}
@@ -84,7 +84,6 @@ import org.springframework.core.annotation.AliasFor;
* @author Sam Brannen
* @since 4.2
* @see EventListenerMethodProcessor
* @see org.springframework.transaction.event.TransactionalEventListener
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@@ -134,7 +133,7 @@ public @interface EventListener {
* An optional identifier for the listener, defaulting to the fully-qualified
* signature of the declaring method (e.g. "mypackage.MyClass.myMethod()").
* @since 5.3.5
* @see SmartApplicationListener#getListenerId()
* @see org.springframework.context.ApplicationListener#getListenerId()
* @see ApplicationEventMulticaster#removeApplicationListeners(Predicate)
*/
String id() default "";
@@ -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.
@@ -205,12 +205,12 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
}
}
result.append("]\n");
result.append('}');
result.append("}");
if (it.hasNext()) {
result.append(",\n");
}
}
result.append(']');
result.append("]");
return result.toString();
}
@@ -112,10 +112,10 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
*/
public void setCorePoolSize(int corePoolSize) {
synchronized (this.poolSizeMonitor) {
this.corePoolSize = corePoolSize;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setCorePoolSize(corePoolSize);
}
this.corePoolSize = corePoolSize;
}
}
@@ -135,10 +135,10 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
*/
public void setMaxPoolSize(int maxPoolSize) {
synchronized (this.poolSizeMonitor) {
this.maxPoolSize = maxPoolSize;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setMaximumPoolSize(maxPoolSize);
}
this.maxPoolSize = maxPoolSize;
}
}
@@ -158,10 +158,10 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
*/
public void setKeepAliveSeconds(int keepAliveSeconds) {
synchronized (this.poolSizeMonitor) {
this.keepAliveSeconds = keepAliveSeconds;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
}
this.keepAliveSeconds = keepAliveSeconds;
}
}
@@ -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.
@@ -53,8 +53,6 @@ import org.springframework.util.concurrent.ListenableFutureTask;
* @since 3.0
* @see #setPoolSize
* @see #setRemoveOnCancelPolicy
* @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
* @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
* @see #setThreadFactory
* @see #setErrorHandler
*/
@@ -66,10 +64,6 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
private volatile boolean removeOnCancelPolicy;
private volatile boolean continueExistingPeriodicTasksAfterShutdownPolicy;
private volatile boolean executeExistingDelayedTasksAfterShutdownPolicy = true;
@Nullable
private volatile ErrorHandler errorHandler;
@@ -90,54 +84,26 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
*/
public void setPoolSize(int poolSize) {
Assert.isTrue(poolSize > 0, "'poolSize' must be 1 or higher");
this.poolSize = poolSize;
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setCorePoolSize(poolSize);
}
this.poolSize = poolSize;
}
/**
* Set the remove-on-cancel mode on {@link ScheduledThreadPoolExecutor}.
* <p>Default is {@code false}. If set to {@code true}, the target executor will be
* switched into remove-on-cancel mode (if possible).
* switched into remove-on-cancel mode (if possible, with a soft fallback otherwise).
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
* @see ScheduledThreadPoolExecutor#setRemoveOnCancelPolicy
*/
public void setRemoveOnCancelPolicy(boolean flag) {
public void setRemoveOnCancelPolicy(boolean removeOnCancelPolicy) {
this.removeOnCancelPolicy = removeOnCancelPolicy;
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(flag);
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(removeOnCancelPolicy);
}
this.removeOnCancelPolicy = flag;
}
/**
* Set whether to continue existing periodic tasks even when this executor has been shutdown.
* <p>Default is {@code false}. If set to {@code true}, the target executor will be
* switched into continuing periodic tasks (if possible).
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
* @since 5.3.9
* @see ScheduledThreadPoolExecutor#setContinueExistingPeriodicTasksAfterShutdownPolicy
*/
public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean flag) {
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setContinueExistingPeriodicTasksAfterShutdownPolicy(flag);
else if (removeOnCancelPolicy && this.scheduledExecutor != null) {
logger.debug("Could not apply remove-on-cancel policy - not a ScheduledThreadPoolExecutor");
}
this.continueExistingPeriodicTasksAfterShutdownPolicy = flag;
}
/**
* Set whether to execute existing delayed tasks even when this executor has been shutdown.
* <p>Default is {@code true}. If set to {@code false}, the target executor will be
* switched into dropping remaining tasks (if possible).
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
* @since 5.3.9
* @see ScheduledThreadPoolExecutor#setExecuteExistingDelayedTasksAfterShutdownPolicy
*/
public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean flag) {
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setExecuteExistingDelayedTasksAfterShutdownPolicy(flag);
}
this.executeExistingDelayedTasksAfterShutdownPolicy = flag;
}
/**
@@ -169,16 +135,12 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
ScheduledThreadPoolExecutor scheduledPoolExecutor = (ScheduledThreadPoolExecutor) this.scheduledExecutor;
if (this.removeOnCancelPolicy) {
scheduledPoolExecutor.setRemoveOnCancelPolicy(true);
if (this.removeOnCancelPolicy) {
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(true);
}
if (this.continueExistingPeriodicTasksAfterShutdownPolicy) {
scheduledPoolExecutor.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
}
if (!this.executeExistingDelayedTasksAfterShutdownPolicy) {
scheduledPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
else {
logger.debug("Could not apply remove-on-cancel policy - not a ScheduledThreadPoolExecutor");
}
}
@@ -239,6 +201,18 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
return getScheduledThreadPoolExecutor().getPoolSize();
}
/**
* Return the current setting for the remove-on-cancel mode.
* <p>Requires an underlying {@link ScheduledThreadPoolExecutor}.
*/
public boolean isRemoveOnCancelPolicy() {
if (this.scheduledExecutor == null) {
// Not initialized yet: return our setting for the time being.
return this.removeOnCancelPolicy;
}
return getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy();
}
/**
* Return the number of currently active threads.
* <p>Requires an underlying {@link ScheduledThreadPoolExecutor}.
@@ -253,21 +227,6 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
return getScheduledThreadPoolExecutor().getActiveCount();
}
/**
* Return the current setting for the remove-on-cancel mode.
* <p>Requires an underlying {@link ScheduledThreadPoolExecutor}.
* @deprecated as of 5.3.9, in favor of direct
* {@link #getScheduledThreadPoolExecutor()} access
*/
@Deprecated
public boolean isRemoveOnCancelPolicy() {
if (this.scheduledExecutor == null) {
// Not initialized yet: return our setting for the time being.
return this.removeOnCancelPolicy;
}
return getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy();
}
// SchedulingTaskExecutor implementation
@@ -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.
@@ -192,11 +192,6 @@ final class BitsCronField extends CronField {
while (current != next && count++ < CronExpression.MAX_ATTEMPTS) {
temporal = type().elapseUntil(temporal, next);
current = type().get(temporal);
next = nextSetBit(current);
if (next == -1) {
temporal = type().rollForward(temporal);
next = nextSetBit(0);
}
}
if (count >= CronExpression.MAX_ATTEMPTS) {
return null;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,9 +66,8 @@ public final class CronExpression {
CronField daysOfWeek,
String expression) {
// reverse order, to make big changes first
// to make sure we end up at 0 nanos, we add an extra field
this.fields = new CronField[]{daysOfWeek, months, daysOfMonth, hours, minutes, seconds, CronField.zeroNanos()};
this.fields = new CronField[]{CronField.zeroNanos(), seconds, minutes, hours, daysOfMonth, months, daysOfWeek};
this.expression = expression;
}
@@ -203,25 +202,6 @@ public final class CronExpression {
}
}
/**
* Determine whether the given string represents a valid cron expression.
* @param expression the expression to evaluate
* @return {@code true} if the given expression is a valid cron expression
* @since 5.3.8
*/
public static boolean isValidExpression(@Nullable String expression) {
if (expression == null) {
return false;
}
try {
parse(expression);
return true;
}
catch (IllegalArgumentException ex) {
return false;
}
}
private static String resolveMacros(String expression) {
expression = expression.trim();
@@ -230,7 +230,9 @@ abstract class CronField {
* Elapse the given temporal for the difference between the current
* value of this field and the goal value. Typically, the returned
* temporal will have the given goal as the current value for this type,
* but this is not the case for {@link #DAY_OF_MONTH}.
* but this is not the case for {@link #DAY_OF_MONTH}. For instance,
* if {@code goal} is 31, and {@code temporal} is April 16th,
* this method returns May 1st, because April 31st does not exist.
* @param temporal the temporal to elapse
* @param goal the goal value
* @param <T> the type of temporal
@@ -245,9 +247,8 @@ abstract class CronField {
return cast(temporal.with(this.field, goal));
}
else {
// goal is invalid, eg. 29th Feb, so roll forward
long amount = range.getMaximum() - current + 1;
return this.field.getBaseUnit().addTo(temporal, amount);
// goal is invalid, eg. 29th Feb, lets try to get as close as possible
return this.field.getBaseUnit().addTo(temporal, goal - current);
}
}
else {
@@ -334,9 +334,6 @@ final class QuartzCronField extends CronField {
// We ended up before the start, roll forward and try again
temporal = this.rollForwardType.rollForward(temporal);
result = adjust(temporal);
if (result != null) {
result = type().reset(result);
}
}
}
return result;
@@ -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.
@@ -18,7 +18,6 @@ package org.springframework.validation.support;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.ui.ConcurrentModel;
import org.springframework.validation.BindingResult;
@@ -37,19 +36,17 @@ import org.springframework.validation.BindingResult;
* @author Rossen Stoyanchev
* @since 5.0
* @see BindingResult
* @see BindingAwareModelMap
*/
@SuppressWarnings("serial")
public class BindingAwareConcurrentModel extends ConcurrentModel {
@Override
@Nullable
public Object put(String key, @Nullable Object value) {
public Object put(String key, Object value) {
removeBindingResultIfNecessary(key, value);
return super.put(key, value);
}
private void removeBindingResultIfNecessary(String key, @Nullable Object value) {
private void removeBindingResultIfNecessary(String key, Object value) {
if (!key.startsWith(BindingResult.MODEL_KEY_PREFIX)) {
String resultKey = BindingResult.MODEL_KEY_PREFIX + key;
BindingResult result = (BindingResult) get(resultKey);
@@ -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.
@@ -18,7 +18,6 @@ package org.springframework.validation.support;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.validation.BindingResult;
@@ -40,7 +39,7 @@ import org.springframework.validation.BindingResult;
public class BindingAwareModelMap extends ExtendedModelMap {
@Override
public Object put(String key, @Nullable Object value) {
public Object put(String key, Object value) {
removeBindingResultIfNecessary(key, value);
return super.put(key, value);
}
@@ -51,7 +50,7 @@ public class BindingAwareModelMap extends ExtendedModelMap {
super.putAll(map);
}
private void removeBindingResultIfNecessary(Object key, @Nullable Object value) {
private void removeBindingResultIfNecessary(Object key, Object value) {
if (key instanceof String) {
String attributeName = (String) key;
if (!attributeName.startsWith(BindingResult.MODEL_KEY_PREFIX)) {
@@ -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.
@@ -1110,7 +1110,7 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit
}
/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* Return an provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @see org.springframework.beans.factory.BeanFactory.getBeanProvider
*/
@@ -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.
@@ -28,7 +28,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
@@ -220,7 +219,7 @@ public class AutoProxyCreatorTests {
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("proxyFactoryBean", "false");
sac.registerSingleton("testAutoProxyCreator", IntroductionTestAutoProxyCreator.class, pvs);
sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class, pvs);
sac.registerSingleton("noInterfaces", NoInterfaces.class);
sac.registerSingleton("containerCallbackInterfacesOnly", ContainerCallbackInterfacesOnly.class);
@@ -249,9 +248,9 @@ public class AutoProxyCreatorTests {
singletonNoInterceptor.getName();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(0);
singletonToBeProxied.getAge();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(2);
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(1);
prototypeToBeProxied.getSpouse();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(4);
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(2);
}
@Test
@@ -405,7 +404,7 @@ public class AutoProxyCreatorTests {
else if (name.endsWith("ToBeProxied")) {
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
if ((this.proxyFactoryBean && isFactoryBean) || (this.proxyObject && !isFactoryBean)) {
return getAdvicesAndAdvisors();
return new Object[] {this.testInterceptor};
}
else {
return DO_NOT_PROXY;
@@ -415,10 +414,6 @@ public class AutoProxyCreatorTests {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}
protected Object[] getAdvicesAndAdvisors() {
return new Object[] {this.testInterceptor};
}
}
@@ -431,17 +426,6 @@ public class AutoProxyCreatorTests {
}
@SuppressWarnings("serial")
public static class IntroductionTestAutoProxyCreator extends TestAutoProxyCreator {
protected Object[] getAdvicesAndAdvisors() {
DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(this.testInterceptor);
advisor.addInterface(Serializable.class);
return new Object[] {this.testInterceptor, advisor};
}
}
/**
* Interceptor that counts the number of non-finalize method calls.
*/
@@ -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.
@@ -47,9 +47,8 @@ import static org.springframework.util.ClassUtils.convertClassNameToResourcePath
public class QualifierAnnotationTests {
private static final String CLASSNAME = QualifierAnnotationTests.class.getName();
private static final String CONFIG_LOCATION =
format("classpath:%s-context.xml", convertClassNameToResourcePath(CLASSNAME));
format("classpath:%s-context.xml", convertClassNameToResourcePath(CLASSNAME));
@Test
@@ -146,7 +146,7 @@ class XmlBeanFactoryTests {
assertThat(emmasJenks != georgiasJenks).as("Emma and georgia think they have a different boyfriend").isTrue();
assertThat(emmasJenks.getName().equals("Andrew")).as("Emmas jenks has right name").isTrue();
assertThat(emmasJenks != xbf.getBean("jenks")).as("Emmas doesn't equal new ref").isTrue();
assertThat(georgiasJenks.getName().equals("Andrew")).as("Georgias jenks has right name").isTrue();
assertThat(emmasJenks.getName().equals("Andrew")).as("Georgias jenks has right name").isTrue();
assertThat(emmasJenks.equals(georgiasJenks)).as("They are object equal").isTrue();
assertThat(emmasJenks.equals(xbf.getBean("jenks"))).as("They object equal direct ref").isTrue();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests regarding overloading and overriding of bean methods.
* <p>Related to SPR-6618.
* Related to SPR-6618.
*
* @author Chris Beams
* @author Phillip Webb
@@ -41,7 +41,7 @@ public class BeanMethodPolymorphismTests {
@Test
public void beanMethodDetectedOnSuperClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
assertThat(ctx.getBean("testBean", TestBean.class)).isNotNull();
ctx.getBean("testBean", TestBean.class);
}
@Test
@@ -1,202 +0,0 @@
/*
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link ConfigurationClassParser}, {@link ConfigurationClass},
* and {@link BeanMethod}.
*
* @author Sam Brannen
* @since 5.3.9
*/
class ConfigurationClassAndBeanMethodTests {
@Test
void verifyEquals() throws Exception {
ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class);
ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class);
ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class);
assertThat(configurationClass1.equals(null)).isFalse();
assertThat(configurationClass1).isNotSameAs(configurationClass2);
assertThat(configurationClass1.equals(configurationClass1)).isTrue();
assertThat(configurationClass2.equals(configurationClass2)).isTrue();
assertThat(configurationClass1.equals(configurationClass2)).isTrue();
assertThat(configurationClass2.equals(configurationClass1)).isTrue();
assertThat(configurationClass1.equals(configurationClass3)).isFalse();
assertThat(configurationClass3.equals(configurationClass2)).isFalse();
// ---------------------------------------------------------------------
List<BeanMethod> beanMethods1 = getBeanMethods(configurationClass1);
BeanMethod beanMethod_1_0 = beanMethods1.get(0);
BeanMethod beanMethod_1_1 = beanMethods1.get(1);
BeanMethod beanMethod_1_2 = beanMethods1.get(2);
List<BeanMethod> beanMethods2 = getBeanMethods(configurationClass2);
BeanMethod beanMethod_2_0 = beanMethods2.get(0);
BeanMethod beanMethod_2_1 = beanMethods2.get(1);
BeanMethod beanMethod_2_2 = beanMethods2.get(2);
List<BeanMethod> beanMethods3 = getBeanMethods(configurationClass3);
BeanMethod beanMethod_3_0 = beanMethods3.get(0);
BeanMethod beanMethod_3_1 = beanMethods3.get(1);
BeanMethod beanMethod_3_2 = beanMethods3.get(2);
assertThat(beanMethod_1_0.equals(null)).isFalse();
assertThat(beanMethod_1_0).isNotSameAs(beanMethod_2_0);
assertThat(beanMethod_1_0.equals(beanMethod_1_0)).isTrue();
assertThat(beanMethod_1_0.equals(beanMethod_2_0)).isTrue();
assertThat(beanMethod_1_1.equals(beanMethod_2_1)).isTrue();
assertThat(beanMethod_1_2.equals(beanMethod_2_2)).isTrue();
assertThat(beanMethod_1_0.getMetadata().getMethodName()).isEqualTo(beanMethod_3_0.getMetadata().getMethodName());
assertThat(beanMethod_1_0.equals(beanMethod_3_0)).isFalse();
assertThat(beanMethod_1_1.equals(beanMethod_3_1)).isFalse();
assertThat(beanMethod_1_2.equals(beanMethod_3_2)).isFalse();
}
@Test
void verifyHashCode() throws Exception {
ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class);
ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class);
ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class);
assertThat(configurationClass1).hasSameHashCodeAs(configurationClass2);
assertThat(configurationClass1).doesNotHaveSameHashCodeAs(configurationClass3);
// ---------------------------------------------------------------------
List<BeanMethod> beanMethods1 = getBeanMethods(configurationClass1);
BeanMethod beanMethod_1_0 = beanMethods1.get(0);
BeanMethod beanMethod_1_1 = beanMethods1.get(1);
BeanMethod beanMethod_1_2 = beanMethods1.get(2);
List<BeanMethod> beanMethods2 = getBeanMethods(configurationClass2);
BeanMethod beanMethod_2_0 = beanMethods2.get(0);
BeanMethod beanMethod_2_1 = beanMethods2.get(1);
BeanMethod beanMethod_2_2 = beanMethods2.get(2);
List<BeanMethod> beanMethods3 = getBeanMethods(configurationClass3);
BeanMethod beanMethod_3_0 = beanMethods3.get(0);
BeanMethod beanMethod_3_1 = beanMethods3.get(1);
BeanMethod beanMethod_3_2 = beanMethods3.get(2);
assertThat(beanMethod_1_0).hasSameHashCodeAs(beanMethod_2_0);
assertThat(beanMethod_1_1).hasSameHashCodeAs(beanMethod_2_1);
assertThat(beanMethod_1_2).hasSameHashCodeAs(beanMethod_2_2);
assertThat(beanMethod_1_0).doesNotHaveSameHashCodeAs(beanMethod_3_0);
assertThat(beanMethod_1_1).doesNotHaveSameHashCodeAs(beanMethod_3_1);
assertThat(beanMethod_1_2).doesNotHaveSameHashCodeAs(beanMethod_3_2);
}
@Test
void verifyToString() throws Exception {
ConfigurationClass configurationClass = newConfigurationClass(Config1.class);
assertThat(configurationClass.toString())
.startsWith("ConfigurationClass: beanName 'Config1', class path resource");
List<BeanMethod> beanMethods = getBeanMethods(configurationClass);
String prefix = "BeanMethod: " + Config1.class.getName();
assertThat(beanMethods.get(0).toString()).isEqualTo(prefix + ".bean0()");
assertThat(beanMethods.get(1).toString()).isEqualTo(prefix + ".bean1(java.lang.String)");
assertThat(beanMethods.get(2).toString()).isEqualTo(prefix + ".bean2(java.lang.String,java.lang.Integer)");
}
private static ConfigurationClass newConfigurationClass(Class<?> clazz) throws Exception {
ConfigurationClassParser parser = newParser();
parser.parse(clazz.getName(), clazz.getSimpleName());
assertThat(parser.getConfigurationClasses()).hasSize(1);
return parser.getConfigurationClasses().iterator().next();
}
private static ConfigurationClassParser newParser() {
return new ConfigurationClassParser(
new CachingMetadataReaderFactory(),
new FailFastProblemReporter(),
new StandardEnvironment(),
new DefaultResourceLoader(),
new AnnotationBeanNameGenerator(),
new DefaultListableBeanFactory());
}
private static List<BeanMethod> getBeanMethods(ConfigurationClass configurationClass) {
List<BeanMethod> beanMethods = configurationClass.getBeanMethods().stream()
.sorted(Comparator.comparing(beanMethod -> beanMethod.getMetadata().getMethodName()))
.collect(Collectors.toList());
assertThat(beanMethods).hasSize(3);
return beanMethods;
}
static class Config1 {
@Bean
String bean0() {
return "";
}
@Bean
String bean1(String text) {
return "";
}
@Bean
String bean2(String text, Integer num) {
return "";
}
}
static class Config2 {
@Bean
String bean0() {
return "";
}
@Bean
String bean1(String text) {
return "";
}
@Bean
String bean2(String text, Integer num) {
return "";
}
}
}
@@ -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,100 +16,21 @@
package org.springframework.scheduling.concurrent;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* @author Juergen Hoeller
* @since 5.0.5
*/
class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
private final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
@Override
protected AsyncListenableTaskExecutor buildExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix(this.threadNamePrefix);
executor.setMaxPoolSize(1);
executor.afterPropertiesSet();
return executor;
}
@Test
void modifyCorePoolSizeWhileRunning() {
assertThat(executor.getCorePoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(1);
executor.setCorePoolSize(0);
assertThat(executor.getCorePoolSize()).isEqualTo(0);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(0);
}
@Test
void modifyCorePoolSizeWithInvalidValueWhileRunning() {
assertThat(executor.getCorePoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(1);
assertThatThrownBy(() -> executor.setCorePoolSize(-1))
.isInstanceOf(IllegalArgumentException.class);
assertThat(executor.getCorePoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(1);
}
@Test
void modifyMaxPoolSizeWhileRunning() {
assertThat(executor.getMaxPoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(1);
executor.setMaxPoolSize(5);
assertThat(executor.getMaxPoolSize()).isEqualTo(5);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(5);
}
@Test
void modifyMaxPoolSizeWithInvalidValueWhileRunning() {
assertThat(executor.getMaxPoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(1);
assertThatThrownBy(() -> executor.setMaxPoolSize(0))
.isInstanceOf(IllegalArgumentException.class);
assertThat(executor.getMaxPoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(1);
}
@Test
void modifyKeepAliveSecondsWhileRunning() {
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(60);
executor.setKeepAliveSeconds(10);
assertThat(executor.getKeepAliveSeconds()).isEqualTo(10);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(10);
}
@Test
void modifyKeepAliveSecondsWithInvalidValueWhileRunning() {
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(60);
assertThatThrownBy(() -> executor.setKeepAliveSeconds(-10))
.isInstanceOf(IllegalArgumentException.class);
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(60);
}
}
@@ -51,16 +51,6 @@ class CronExpressionTests {
}
};
@Test
public void isValidExpression() {
assertThat(CronExpression.isValidExpression(null)).isFalse();
assertThat(CronExpression.isValidExpression("")).isFalse();
assertThat(CronExpression.isValidExpression("*")).isFalse();
assertThat(CronExpression.isValidExpression("* * * * *")).isFalse();
assertThat(CronExpression.isValidExpression("* * * * * * *")).isFalse();
assertThat(CronExpression.isValidExpression("* * * * * *")).isTrue();
}
@Test
void matchAll() {
@@ -507,29 +497,6 @@ class CronExpressionTests {
assertThat(actual.getDayOfMonth()).isEqualTo(13);
}
@Test
public void everyTenDays() {
CronExpression cronExpression = CronExpression.parse("0 15 12 */10 1-8 5");
LocalDateTime last = LocalDateTime.parse("2021-04-30T12:14:59");
LocalDateTime expected = LocalDateTime.parse("2021-05-21T12:15");
LocalDateTime actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.parse("2021-06-11T12:15");
actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
last = actual;
expected = LocalDateTime.parse("2022-01-21T12:15");
actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
@Test
void yearly() {
CronExpression expression = CronExpression.parse("@yearly");
@@ -1319,21 +1286,6 @@ class CronExpressionTests {
assertThat(actual).isEqualTo(expected);
}
@Test
public void various() {
CronExpression cronExpression = CronExpression.parse("3-57 13-28 17,18 1,15 3-12 6#1");
LocalDateTime last = LocalDateTime.of(2022, 9, 15, 17, 44, 11);
LocalDateTime expected = LocalDateTime.of(2022, 10, 1, 17, 13, 3);
LocalDateTime actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
cronExpression = CronExpression.parse("*/28 56 22 */6 * *");
last = LocalDateTime.of(2022, 2, 27, 8, 0, 42);
expected = LocalDateTime.of(2022, 3, 1, 22, 56, 0);
actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,10 @@
@file:JvmName("CoroutinesUtils")
package org.springframework.core
import kotlinx.coroutines.*
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.reactive.awaitSingleOrNull
import kotlinx.coroutines.reactor.asFlux
@@ -45,8 +48,6 @@ internal fun <T: Any> deferredToMono(source: Deferred<T>) =
* @author Sebastien Deleuze
* @since 5.2
*/
@Suppress("DEPRECATION")
@OptIn(DelicateCoroutinesApi::class)
internal fun <T: Any> monoToDeferred(source: Mono<T>) =
GlobalScope.async(Dispatchers.Unconfined) { source.awaitSingleOrNull() }
@@ -88,9 +88,6 @@ public class ClassReader {
*/
static final int EXPAND_ASM_INSNS = 256;
/** The maximum size of array to allocate. */
private static final int MAX_BUFFER_SIZE = 1024 * 1024;
/** The size of the temporary byte array used to read class input streams chunk by chunk. */
private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
@@ -194,7 +191,7 @@ public class ClassReader {
this.b = classFileBuffer;
// Check the class' major_version. This field is after the magic and minor_version fields, which
// use 4 and 2 bytes respectively.
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V18) {
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V17) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
@@ -313,19 +310,13 @@ public class ClassReader {
if (inputStream == null) {
throw new IOException("Class not found");
}
int bufferSize = calculateBufferSize(inputStream);
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] data = new byte[bufferSize];
byte[] data = new byte[INPUT_STREAM_DATA_CHUNK_SIZE];
int bytesRead;
int readCount = 0;
while ((bytesRead = inputStream.read(data, 0, bufferSize)) != -1) {
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, bytesRead);
readCount++;
}
outputStream.flush();
if (readCount == 1) {
return data;
}
return outputStream.toByteArray();
} finally {
if (close) {
@@ -334,20 +325,6 @@ public class ClassReader {
}
}
private static int calculateBufferSize(final InputStream inputStream) throws IOException {
int expectedLength = inputStream.available();
/*
* Some implementations can return 0 while holding available data
* (e.g. new FileInputStream("/proc/a_file"))
* Also in some pathological cases a very small number might be returned,
* and in this case we use default size
*/
if (expectedLength < 256) {
return INPUT_STREAM_DATA_CHUNK_SIZE;
}
return Math.min(expectedLength, MAX_BUFFER_SIZE);
}
// -----------------------------------------------------------------------------------------------
// Accessors
// -----------------------------------------------------------------------------------------------
@@ -3479,6 +3456,7 @@ public class ClassReader {
private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
char[] charBuffer = new char[maxStringLength];
int currentAttributeOffset = getFirstAttributeOffset();
int[] currentBootstrapMethodOffsets = null;
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
// Read the attribute_info's attribute_name and attribute_length fields.
String attributeName = readUTF8(currentAttributeOffset, charBuffer);
@@ -3486,17 +3464,17 @@ public class ClassReader {
currentAttributeOffset += 6;
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
// Read the num_bootstrap_methods field and create an array of this size.
int[] result = new int[readUnsignedShort(currentAttributeOffset)];
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
// Compute and store the offset of each 'bootstrap_methods' array field entry.
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
for (int j = 0; j < result.length; ++j) {
result[j] = currentBootstrapMethodOffset;
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
currentBootstrapMethodOffset +=
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
}
return result;
return currentBootstrapMethodOffsets;
}
currentAttributeOffset += attributeLength;
}
@@ -30,8 +30,8 @@ package org.springframework.asm;
/**
* A visitor to visit a Java class. The methods of this class must be called in the following order:
* {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code
* visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code
* visitAttribute} )* ( {@code visitNestMember} | [ {@code * visitPermittedSubclass} ] | {@code
* visitPermittedSubclass} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code
* visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code
* visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )*
* {@code visitEnd}.
*
@@ -79,7 +79,7 @@ public class ClassWriter extends ClassVisitor {
/**
* The access_flags field of the JVMS ClassFile structure. This field can contain ASM specific
* access flags, such as {@link Opcodes#ACC_DEPRECATED} or {@link Opcodes#ACC_RECORD}, which are
* access flags, such as {@link Opcodes#ACC_DEPRECATED} or {}@link Opcodes#ACC_RECORD}, which are
* removed when generating the ClassFile structure.
*/
private int accessFlags;
@@ -282,7 +282,6 @@ public interface Opcodes {
int V15 = 0 << 16 | 59;
int V16 = 0 << 16 | 60;
int V17 = 0 << 16 | 61;
int V18 = 0 << 16 | 62;
/**
* Version flag indicating that the class is using 'preview' features.
@@ -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.
@@ -324,7 +324,7 @@ public class Constants {
for (int i = 0; i < propertyName.length(); i++) {
char c = propertyName.charAt(i);
if (Character.isUpperCase(c)) {
parsedPrefix.append('_');
parsedPrefix.append("_");
parsedPrefix.append(c);
}
else {
@@ -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.
@@ -394,11 +394,9 @@ public class AnnotationAttributes extends LinkedHashMap<String, Object> {
sb.append(entry.getKey());
sb.append('=');
sb.append(valueToString(entry.getValue()));
if (entries.hasNext()) {
sb.append(", ");
}
sb.append(entries.hasNext() ? ", " : "");
}
sb.append('}');
sb.append("}");
return sb.toString();
}
@@ -177,17 +177,17 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
private String annotationToString() {
String string = this.string;
if (string == null) {
StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append('(');
StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append("(");
for (int i = 0; i < this.attributes.size(); i++) {
Method attribute = this.attributes.get(i);
if (i > 0) {
builder.append(", ");
}
builder.append(attribute.getName());
builder.append('=');
builder.append("=");
builder.append(toString(getAttributeValue(attribute)));
}
builder.append(')');
builder.append(")");
string = builder.toString();
this.string = string;
}
@@ -206,7 +206,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
}
builder.append(toString(Array.get(value, i)));
}
builder.append(']');
builder.append("]");
return builder.toString();
}
return String.valueOf(value);
@@ -513,7 +513,7 @@ public class TypeDescriptor implements Serializable {
public String toString() {
StringBuilder builder = new StringBuilder();
for (Annotation ann : getAnnotations()) {
builder.append('@').append(ann.annotationType().getName()).append(' ');
builder.append("@").append(ann.annotationType().getName()).append(' ');
}
builder.append(getResolvableType());
return builder.toString();
@@ -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.
@@ -71,7 +71,7 @@ public abstract class DataBufferUtils {
//---------------------------------------------------------------------
/**
* Obtain an {@link InputStream} from the given supplier, and read it into a
* Obtain a {@link InputStream} from the given supplier, and read it into a
* {@code Flux} of {@code DataBuffer}s. Closes the input stream when the
* Flux is terminated.
* @param inputStreamSupplier the supplier for the input stream to read from
@@ -125,7 +125,7 @@ public abstract class DataBufferUtils {
}
/**
* Obtain an {@code AsynchronousFileChannel} from the given supplier, and
* Obtain a {@code AsynchronousFileChannel} from the given supplier, and
* read it into a {@code Flux} of {@code DataBuffer}s, starting at the given
* position. Closes the channel when the Flux is terminated.
* @param channelSupplier the supplier for the channel to read from
@@ -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.
@@ -29,16 +29,16 @@ import java.util.function.Supplier;
*/
class DefaultApplicationStartup implements ApplicationStartup {
private static final DefaultStartupStep DEFAULT_STARTUP_STEP = new DefaultStartupStep();
@Override
public DefaultStartupStep start(String name) {
return DEFAULT_STARTUP_STEP;
return new DefaultStartupStep();
}
static class DefaultStartupStep implements StartupStep {
boolean recorded = false;
private final DefaultTags TAGS = new DefaultTags();
@Override
@@ -63,17 +63,23 @@ class DefaultApplicationStartup implements ApplicationStartup {
@Override
public StartupStep tag(String key, String value) {
if (this.recorded) {
throw new IllegalArgumentException();
}
return this;
}
@Override
public StartupStep tag(String key, Supplier<String> value) {
if (this.recorded) {
throw new IllegalArgumentException();
}
return this;
}
@Override
public void end() {
this.recorded = true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,8 @@
package org.springframework.core.metrics.jfr;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
@@ -38,23 +37,24 @@ import org.springframework.core.metrics.StartupStep;
*/
public class FlightRecorderApplicationStartup implements ApplicationStartup {
private final AtomicLong currentSequenceId = new AtomicLong(0);
private long currentSequenceId;
private final Deque<Long> currentSteps;
public FlightRecorderApplicationStartup() {
this.currentSteps = new ConcurrentLinkedDeque<>();
this.currentSteps.offerFirst(this.currentSequenceId.get());
this.currentSequenceId = 0;
this.currentSteps = new ArrayDeque<>();
this.currentSteps.offerFirst(0L);
}
@Override
public StartupStep start(String name) {
long sequenceId = this.currentSequenceId.incrementAndGet();
this.currentSteps.offerFirst(sequenceId);
return new FlightRecorderStartupStep(sequenceId, name,
this.currentSteps.getFirst(), committedStep -> this.currentSteps.removeFirstOccurrence(sequenceId));
FlightRecorderStartupStep step = new FlightRecorderStartupStep(++this.currentSequenceId, name,
this.currentSteps.getFirst(), committedStep -> this.currentSteps.removeFirst());
this.currentSteps.offerFirst(this.currentSequenceId);
return step;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.springframework.core.type;
/**
* Interface that defines abstract access to the annotations of a specific
* method, in a form that does not require that method's class to be loaded yet.
* class, in a form that does not require that class to be loaded yet.
*
* @author Juergen Hoeller
* @author Mark Pollack
@@ -32,42 +32,42 @@ package org.springframework.core.type;
public interface MethodMetadata extends AnnotatedTypeMetadata {
/**
* Get the name of the underlying method.
* Return the name of the method.
*/
String getMethodName();
/**
* Get the fully-qualified name of the class that declares the underlying method.
* Return the fully-qualified name of the class that declares this method.
*/
String getDeclaringClassName();
/**
* Get the fully-qualified name of the underlying method's declared return type.
* Return the fully-qualified name of this method's declared return type.
* @since 4.2
*/
String getReturnTypeName();
/**
* Determine whether the underlying method is effectively abstract:
* i.e. marked as abstract in a class or declared as a regular,
* Return whether the underlying method is effectively abstract:
* i.e. marked as abstract on a class or declared as a regular,
* non-default method in an interface.
* @since 4.2
*/
boolean isAbstract();
/**
* Determine whether the underlying method is declared as 'static'.
* Return whether the underlying method is declared as 'static'.
*/
boolean isStatic();
/**
* Determine whether the underlying method is marked as 'final'.
* Return whether the underlying method is marked as 'final'.
*/
boolean isFinal();
/**
* Determine whether the underlying method is overridable,
* i.e. not marked as static, final, or private.
* Return whether the underlying method is overridable,
* i.e. not marked as static, final or private.
*/
boolean isOverridable();
@@ -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.
@@ -165,12 +165,12 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
return annotatedMethods != null ? annotatedMethods : Collections.emptySet();
}
private static boolean isAnnotatedMethod(Method method, String annotationName) {
private boolean isAnnotatedMethod(Method method, String annotationName) {
return !method.isBridge() && method.getAnnotations().length > 0 &&
AnnotatedElementUtils.isAnnotated(method, annotationName);
}
static AnnotationMetadata from(Class<?> introspectedClass) {
return new StandardAnnotationMetadata(introspectedClass, true);
}
@@ -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.
@@ -28,7 +28,6 @@ import org.springframework.util.StringUtils;
* to introspect a given {@code Class}.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.5
*/
public class StandardClassMetadata implements ClassMetadata {
@@ -120,20 +119,4 @@ public class StandardClassMetadata implements ClassMetadata {
return StringUtils.toStringArray(memberClassNames);
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof StandardClassMetadata) &&
getIntrospectedClass().equals(((StandardClassMetadata) obj).getIntrospectedClass())));
}
@Override
public int hashCode() {
return getIntrospectedClass().hashCode();
}
@Override
public String toString() {
return getClassName();
}
}
@@ -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.
@@ -36,7 +36,6 @@ import org.springframework.util.MultiValueMap;
* @author Mark Pollack
* @author Chris Beams
* @author Phillip Webb
* @author Sam Brannen
* @since 3.0
*/
public class StandardMethodMetadata implements MethodMetadata {
@@ -151,20 +150,4 @@ public class StandardMethodMetadata implements MethodMetadata {
annotationName, classValuesAsString, false);
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof StandardMethodMetadata) &&
this.introspectedMethod.equals(((StandardMethodMetadata) obj).introspectedMethod)));
}
@Override
public int hashCode() {
return this.introspectedMethod.hashCode();
}
@Override
public String toString() {
return this.introspectedMethod.toString();
}
}
@@ -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.
@@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.SpringAsmInfo;
@@ -120,7 +121,7 @@ class MergedAnnotationReadingVisitor<A extends Annotation> extends AnnotationVis
@SuppressWarnings("unchecked")
@Nullable
static <A extends Annotation> AnnotationVisitor get(@Nullable ClassLoader classLoader,
@Nullable Object source, String descriptor, boolean visible,
@Nullable Supplier<Object> sourceSupplier, String descriptor, boolean visible,
Consumer<MergedAnnotation<A>> consumer) {
if (!visible) {
@@ -132,6 +133,7 @@ class MergedAnnotationReadingVisitor<A extends Annotation> extends AnnotationVis
return null;
}
Object source = (sourceSupplier != null ? sourceSupplier.get() : null);
try {
Class<A> annotationType = (Class<A>) ClassUtils.forName(typeName, classLoader);
return new MergedAnnotationReadingVisitor<>(classLoader, source, annotationType, consumer);
@@ -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.
@@ -31,7 +31,6 @@ import org.springframework.lang.Nullable;
* {@link SimpleAnnotationMetadataReadingVisitor}.
*
* @author Phillip Webb
* @author Sam Brannen
* @since 5.2
*/
final class SimpleAnnotationMetadata implements AnnotationMetadata {
@@ -157,20 +156,4 @@ final class SimpleAnnotationMetadata implements AnnotationMetadata {
return this.annotations;
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof SimpleAnnotationMetadata) &&
this.className.equals(((SimpleAnnotationMetadata) obj).className)));
}
@Override
public int hashCode() {
return this.className.hashCode();
}
@Override
public String toString() {
return this.className;
}
}
@@ -117,7 +117,7 @@ final class SimpleAnnotationMetadataReadingVisitor extends ClassVisitor {
@Override
@Nullable
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return MergedAnnotationReadingVisitor.get(this.classLoader, getSource(),
return MergedAnnotationReadingVisitor.get(this.classLoader, this::getSource,
descriptor, visible, this.annotations::add);
}
@@ -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,13 +19,12 @@ package org.springframework.core.type.classreading;
import org.springframework.asm.Opcodes;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
/**
* {@link MethodMetadata} created from a {@link SimpleMethodMetadataReadingVisitor}.
* {@link MethodMetadata} created from a
* {@link SimpleMethodMetadataReadingVisitor}.
*
* @author Phillip Webb
* @author Sam Brannen
* @since 5.2
*/
final class SimpleMethodMetadata implements MethodMetadata {
@@ -38,20 +37,16 @@ final class SimpleMethodMetadata implements MethodMetadata {
private final String returnTypeName;
// The source implements equals(), hashCode(), and toString() for the underlying method.
private final Object source;
private final MergedAnnotations annotations;
SimpleMethodMetadata(String methodName, int access, String declaringClassName,
String returnTypeName, Object source, MergedAnnotations annotations) {
public SimpleMethodMetadata(String methodName, int access, String declaringClassName,
String returnTypeName, MergedAnnotations annotations) {
this.methodName = methodName;
this.access = access;
this.declaringClassName = declaringClassName;
this.returnTypeName = returnTypeName;
this.source = source;
this.annotations = annotations;
}
@@ -91,7 +86,7 @@ final class SimpleMethodMetadata implements MethodMetadata {
return !isStatic() && !isFinal() && !isPrivate();
}
private boolean isPrivate() {
public boolean isPrivate() {
return (this.access & Opcodes.ACC_PRIVATE) != 0;
}
@@ -100,20 +95,4 @@ final class SimpleMethodMetadata implements MethodMetadata {
return this.annotations;
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof SimpleMethodMetadata) &&
this.source.equals(((SimpleMethodMetadata) obj).source)));
}
@Override
public int hashCode() {
return this.source.hashCode();
}
@Override
public String toString() {
return this.source.toString();
}
}
@@ -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.
@@ -32,7 +32,6 @@ import org.springframework.lang.Nullable;
* ASM method visitor that creates {@link SimpleMethodMetadata}.
*
* @author Phillip Webb
* @author Sam Brannen
* @since 5.2
*/
final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
@@ -44,7 +43,7 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
private final int access;
private final String methodName;
private final String name;
private final String descriptor;
@@ -57,13 +56,13 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
SimpleMethodMetadataReadingVisitor(@Nullable ClassLoader classLoader, String declaringClassName,
int access, String methodName, String descriptor, Consumer<SimpleMethodMetadata> consumer) {
int access, String name, String descriptor, Consumer<SimpleMethodMetadata> consumer) {
super(SpringAsmInfo.ASM_VERSION);
this.classLoader = classLoader;
this.declaringClassName = declaringClassName;
this.access = access;
this.methodName = methodName;
this.name = name;
this.descriptor = descriptor;
this.consumer = consumer;
}
@@ -72,7 +71,7 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
@Override
@Nullable
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return MergedAnnotationReadingVisitor.get(this.classLoader, getSource(),
return MergedAnnotationReadingVisitor.get(this.classLoader, this::getSource,
descriptor, visible, this.annotations::add);
}
@@ -81,8 +80,8 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
if (!this.annotations.isEmpty()) {
String returnTypeName = Type.getReturnType(this.descriptor).getClassName();
MergedAnnotations annotations = MergedAnnotations.of(this.annotations);
SimpleMethodMetadata metadata = new SimpleMethodMetadata(this.methodName, this.access,
this.declaringClassName, returnTypeName, getSource(), annotations);
SimpleMethodMetadata metadata = new SimpleMethodMetadata(this.name,
this.access, this.declaringClassName, returnTypeName, annotations);
this.consumer.accept(metadata);
}
}
@@ -90,7 +89,7 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
private Object getSource() {
Source source = this.source;
if (source == null) {
source = new Source(this.declaringClassName, this.methodName, this.descriptor);
source = new Source(this.declaringClassName, this.name, this.descriptor);
this.source = source;
}
return source;
@@ -104,16 +103,16 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
private final String declaringClassName;
private final String methodName;
private final String name;
private final String descriptor;
@Nullable
private String toStringValue;
Source(String declaringClassName, String methodName, String descriptor) {
Source(String declaringClassName, String name, String descriptor) {
this.declaringClassName = declaringClassName;
this.methodName = methodName;
this.name = name;
this.descriptor = descriptor;
}
@@ -121,7 +120,7 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
public int hashCode() {
int result = 1;
result = 31 * result + this.declaringClassName.hashCode();
result = 31 * result + this.methodName.hashCode();
result = 31 * result + this.name.hashCode();
result = 31 * result + this.descriptor.hashCode();
return result;
}
@@ -136,7 +135,7 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
}
Source otherSource = (Source) other;
return (this.declaringClassName.equals(otherSource.declaringClassName) &&
this.methodName.equals(otherSource.methodName) && this.descriptor.equals(otherSource.descriptor));
this.name.equals(otherSource.name) && this.descriptor.equals(otherSource.descriptor));
}
@Override
@@ -145,17 +144,14 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor {
if (value == null) {
StringBuilder builder = new StringBuilder();
builder.append(this.declaringClassName);
builder.append('.');
builder.append(this.methodName);
builder.append(".");
builder.append(this.name);
Type[] argumentTypes = Type.getArgumentTypes(this.descriptor);
builder.append('(');
for (int i = 0; i < argumentTypes.length; i++) {
if (i != 0) {
builder.append(',');
}
builder.append(argumentTypes[i].getClassName());
builder.append("(");
for (Type type : argumentTypes) {
builder.append(type.getClassName());
}
builder.append(')');
builder.append(")");
value = builder.toString();
this.toStringValue = value;
}
@@ -88,13 +88,13 @@ public abstract class ClassUtils {
* Map with primitive wrapper type as key and corresponding primitive
* type as value, for example: Integer.class -> int.class.
*/
private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new IdentityHashMap<>(9);
private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new IdentityHashMap<>(8);
/**
* Map with primitive type as key and corresponding wrapper
* type as value, for example: int.class -> Integer.class.
*/
private static final Map<Class<?>, Class<?>> primitiveTypeToWrapperMap = new IdentityHashMap<>(9);
private static final Map<Class<?>, Class<?>> primitiveTypeToWrapperMap = new IdentityHashMap<>(8);
/**
* Map with primitive type name as key and corresponding primitive
@@ -1322,7 +1322,7 @@ public abstract class ClassUtils {
* Note that, despite being synthetic, bridge methods ({@link Method#isBridge()}) are considered
* as user-level methods since they are eventually pointing to a user-declared generic method.
* @param method the method to check
* @return {@code true} if the method can be considered as user-declared; {@code false} otherwise
* @return {@code true} if the method can be considered as user-declared; [@code false} otherwise
*/
public static boolean isUserLevelMethod(Method method) {
Assert.notNull(method, "Method must not be null");
@@ -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.
@@ -302,7 +302,7 @@ public class StopWatch {
for (TaskInfo task : getTaskInfo()) {
sb.append(nf.format(task.getTimeNanos())).append(" ");
sb.append(pf.format((double) task.getTimeNanos() / getTotalTimeNanos())).append(" ");
sb.append(task.getTaskName()).append('\n');
sb.append(task.getTaskName()).append("\n");
}
}
return sb.toString();
@@ -320,7 +320,7 @@ public class StopWatch {
for (TaskInfo task : getTaskInfo()) {
sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeNanos()).append(" ns");
long percent = Math.round(100.0 * task.getTimeNanos() / getTotalTimeNanos());
sb.append(" = ").append(percent).append('%');
sb.append(" = ").append(percent).append("%");
}
}
else {
@@ -566,7 +566,7 @@ public abstract class StringUtils {
char[] chars = str.toCharArray();
chars[0] = updatedChar;
return new String(chars);
return new String(chars, 0, chars.length);
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,18 +21,13 @@ import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link SimpleAliasRegistry}.
*
* @author Juergen Hoeller
* @author Nha Vuong
* @author Sam Brannen
*/
class SimpleAliasRegistryTests {
private final SimpleAliasRegistry registry = new SimpleAliasRegistry();
@Test
void aliasChaining() {
SimpleAliasRegistry registry = new SimpleAliasRegistry();
registry.registerAlias("test", "testAlias");
registry.registerAlias("testAlias", "testAlias2");
registry.registerAlias("testAlias2", "testAlias3");
@@ -47,6 +42,7 @@ class SimpleAliasRegistryTests {
@Test // SPR-17191
void aliasChainingWithMultipleAliases() {
SimpleAliasRegistry registry = new SimpleAliasRegistry();
registry.registerAlias("name", "alias_a");
registry.registerAlias("name", "alias_b");
assertThat(registry.hasAlias("name", "alias_a")).isTrue();
@@ -64,35 +60,4 @@ class SimpleAliasRegistryTests {
assertThat(registry.hasAlias("real_name", "alias_c")).isTrue();
}
@Test
void removeAlias() {
registry.registerAlias("real_name", "nickname");
assertThat(registry.hasAlias("real_name", "nickname")).isTrue();
registry.removeAlias("nickname");
assertThat(registry.hasAlias("real_name", "nickname")).isFalse();
}
@Test
void isAlias() {
registry.registerAlias("real_name", "nickname");
assertThat(registry.isAlias("nickname")).isTrue();
assertThat(registry.isAlias("real_name")).isFalse();
assertThat(registry.isAlias("fake")).isFalse();
}
@Test
void getAliases() {
registry.registerAlias("test", "testAlias1");
assertThat(registry.getAliases("test")).containsExactly("testAlias1");
registry.registerAlias("testAlias1", "testAlias2");
registry.registerAlias("testAlias2", "testAlias3");
assertThat(registry.getAliases("test")).containsExactlyInAnyOrder("testAlias1", "testAlias2", "testAlias3");
assertThat(registry.getAliases("testAlias1")).containsExactlyInAnyOrder("testAlias2", "testAlias3");
assertThat(registry.getAliases("testAlias2")).containsExactly("testAlias3");
assertThat(registry.getAliases("testAlias3")).isEmpty();
}
}
@@ -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.
@@ -33,51 +33,9 @@ import static org.assertj.core.api.Assertions.entry;
* Base class for {@link AnnotationMetadata} tests.
*
* @author Phillip Webb
* @author Sam Brannen
*/
public abstract class AbstractAnnotationMetadataTests {
@Test
public void verifyEquals() throws Exception {
AnnotationMetadata testClass1 = get(TestClass.class);
AnnotationMetadata testClass2 = get(TestClass.class);
AnnotationMetadata testMemberClass1 = get(TestMemberClass.class);
AnnotationMetadata testMemberClass2 = get(TestMemberClass.class);
assertThat(testClass1.equals(null)).isFalse();
assertThat(testClass1.equals(testClass1)).isTrue();
assertThat(testClass2.equals(testClass2)).isTrue();
assertThat(testClass1.equals(testClass2)).isTrue();
assertThat(testClass2.equals(testClass1)).isTrue();
assertThat(testMemberClass1.equals(testMemberClass1)).isTrue();
assertThat(testMemberClass2.equals(testMemberClass2)).isTrue();
assertThat(testMemberClass1.equals(testMemberClass2)).isTrue();
assertThat(testMemberClass2.equals(testMemberClass1)).isTrue();
assertThat(testClass1.equals(testMemberClass1)).isFalse();
assertThat(testMemberClass1.equals(testClass1)).isFalse();
}
@Test
public void verifyHashCode() throws Exception {
AnnotationMetadata testClass1 = get(TestClass.class);
AnnotationMetadata testClass2 = get(TestClass.class);
AnnotationMetadata testMemberClass1 = get(TestMemberClass.class);
AnnotationMetadata testMemberClass2 = get(TestMemberClass.class);
assertThat(testClass1).hasSameHashCodeAs(testClass2);
assertThat(testMemberClass1).hasSameHashCodeAs(testMemberClass2);
assertThat(testClass1).doesNotHaveSameHashCodeAs(testMemberClass1);
}
@Test
public void verifyToString() throws Exception {
assertThat(get(TestClass.class).toString()).isEqualTo(TestClass.class.getName());
}
@Test
public void getClassNameReturnsClassName() {
assertThat(get(TestClass.class).getClassName()).isEqualTo(TestClass.class.getName());
@@ -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.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Abstract base class for testing implementations of
* {@link ClassMetadata#getMemberClassNames()}.
@@ -29,45 +30,48 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public abstract class AbstractClassMetadataMemberClassTests {
protected abstract ClassMetadata getClassMetadataFor(Class<?> clazz);
public abstract ClassMetadata getClassMetadataFor(Class<?> clazz);
@Test
void withNoMemberClasses() {
ClassMetadata metadata = getClassMetadataFor(L0_a.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).isEmpty();
assertThat(nestedClasses).isEqualTo(new String[]{});
}
public static class L0_a {
}
@Test
void withPublicMemberClasses() {
ClassMetadata metadata = getClassMetadataFor(L0_b.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).containsOnly(L0_b.L1.class.getName());
}
@Test
void withNonPublicMemberClasses() {
ClassMetadata metadata = getClassMetadataFor(L0_c.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).containsOnly(L0_c.L1.class.getName());
}
@Test
void againstMemberClass() {
ClassMetadata metadata = getClassMetadataFor(L0_b.L1.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).isEmpty();
}
public static class L0_a {
assertThat(nestedClasses).isEqualTo(new String[]{L0_b.L1.class.getName()});
}
public static class L0_b {
public static class L1 { }
}
@Test
void withNonPublicMemberClasses() {
ClassMetadata metadata = getClassMetadataFor(L0_c.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).isEqualTo(new String[]{L0_c.L1.class.getName()});
}
public static class L0_c {
private static class L1 { }
}
@Test
void againstMemberClass() {
ClassMetadata metadata = getClassMetadataFor(L0_b.L1.class);
String[] nestedClasses = metadata.getMemberClassNames();
assertThat(nestedClasses).isEqualTo(new String[]{});
}
}
@@ -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.
@@ -37,54 +37,6 @@ import static org.assertj.core.api.Assertions.entry;
*/
public abstract class AbstractMethodMetadataTests {
@Test
public void verifyEquals() throws Exception {
MethodMetadata withMethod1 = getTagged(WithMethod.class);
MethodMetadata withMethod2 = getTagged(WithMethod.class);
MethodMetadata withMethodWithTwoArguments1 = getTagged(WithMethodWithTwoArguments.class);
MethodMetadata withMethodWithTwoArguments2 = getTagged(WithMethodWithTwoArguments.class);
assertThat(withMethod1.equals(null)).isFalse();
assertThat(withMethod1.equals(withMethod1)).isTrue();
assertThat(withMethod2.equals(withMethod2)).isTrue();
assertThat(withMethod1.equals(withMethod2)).isTrue();
assertThat(withMethod2.equals(withMethod1)).isTrue();
assertThat(withMethodWithTwoArguments1.equals(withMethodWithTwoArguments1)).isTrue();
assertThat(withMethodWithTwoArguments2.equals(withMethodWithTwoArguments2)).isTrue();
assertThat(withMethodWithTwoArguments1.equals(withMethodWithTwoArguments2)).isTrue();
assertThat(withMethodWithTwoArguments2.equals(withMethodWithTwoArguments1)).isTrue();
assertThat(withMethod1.equals(withMethodWithTwoArguments1)).isFalse();
assertThat(withMethodWithTwoArguments1.equals(withMethod1)).isFalse();
}
@Test
public void verifyHashCode() throws Exception {
MethodMetadata withMethod1 = getTagged(WithMethod.class);
MethodMetadata withMethod2 = getTagged(WithMethod.class);
MethodMetadata withMethodWithTwoArguments1 = getTagged(WithMethodWithTwoArguments.class);
MethodMetadata withMethodWithTwoArguments2 = getTagged(WithMethodWithTwoArguments.class);
assertThat(withMethod1).hasSameHashCodeAs(withMethod2);
assertThat(withMethodWithTwoArguments1).hasSameHashCodeAs(withMethodWithTwoArguments2);
assertThat(withMethod1).doesNotHaveSameHashCodeAs(withMethodWithTwoArguments1);
}
@Test
public void verifyToString() throws Exception {
assertThat(getTagged(WithMethod.class).toString())
.endsWith(WithMethod.class.getName() + ".test()");
assertThat(getTagged(WithMethodWithOneArgument.class).toString())
.endsWith(WithMethodWithOneArgument.class.getName() + ".test(java.lang.String)");
assertThat(getTagged(WithMethodWithTwoArguments.class).toString())
.endsWith(WithMethodWithTwoArguments.class.getName() + ".test(java.lang.String,java.lang.Integer)");
}
@Test
public void getMethodNameReturnsMethodName() {
assertThat(getTagged(WithMethod.class).getMethodName()).isEqualTo("test");
@@ -219,24 +171,6 @@ public abstract class AbstractMethodMetadataTests {
}
public static class WithMethodWithOneArgument {
@Tag
public String test(String text) {
return "";
}
}
public static class WithMethodWithTwoArguments {
@Tag
public String test(String text, Integer num) {
return "";
}
}
public abstract static class WithAbstractMethod {
@Tag
@@ -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.core.type.classreading;
import java.io.BufferedInputStream;
import java.io.InputStream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.asm.ClassReader;
@@ -36,7 +35,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Tests for {@link AnnotationMetadataReadingVisitor}.
*
* @author Phillip Webb
* @author Sam Brannen
*/
@SuppressWarnings("deprecation")
class AnnotationMetadataReadingVisitorTests extends AbstractAnnotationMetadataTests {
@@ -64,29 +62,11 @@ class AnnotationMetadataReadingVisitorTests extends AbstractAnnotationMetadataTe
}
}
@Test
@Disabled("equals() not implemented in deprecated AnnotationMetadataReadingVisitor")
@Override
public void verifyEquals() throws Exception {
}
@Test
@Disabled("hashCode() not implemented in deprecated AnnotationMetadataReadingVisitor")
@Override
public void verifyHashCode() throws Exception {
}
@Test
@Disabled("toString() not implemented in deprecated AnnotationMetadataReadingVisitor")
@Override
public void verifyToString() {
}
@Override
@Test
public void getAnnotationsReturnsDirectAnnotations() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::getAnnotationsReturnsDirectAnnotations);
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
super::getAnnotationsReturnsDirectAnnotations);
}
}
@@ -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.core.type.classreading;
import java.io.BufferedInputStream;
import java.io.InputStream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.asm.ClassReader;
@@ -36,7 +35,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Tests for {@link MethodMetadataReadingVisitor}.
*
* @author Phillip Webb
* @author Sam Brannen
*/
@SuppressWarnings("deprecation")
class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests {
@@ -64,26 +62,8 @@ class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests {
}
}
@Test
@Disabled("equals() not implemented in deprecated MethodMetadataReadingVisitor")
@Override
public void verifyEquals() throws Exception {
}
@Test
@Disabled("hashCode() not implemented in deprecated MethodMetadataReadingVisitor")
@Override
public void verifyHashCode() throws Exception {
}
@Test
@Disabled("toString() not implemented in deprecated MethodMetadataReadingVisitor")
@Override
public void verifyToString() {
}
@Test
@Override
public void getAnnotationsReturnsDirectAnnotations() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
super::getAnnotationsReturnsDirectAnnotations);
@@ -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.
@@ -194,7 +194,7 @@ class FastByteArrayOutputStreamTests {
this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream();
DigestUtils.appendMd5DigestAsHex(inputStream, builder);
builder.append('"');
builder.append("\"");
String actual = builder.toString();
assertThat(actual).isEqualTo("\"0b10a8db164e0754105b7a99be72e3fe5\"");
}
@@ -208,7 +208,7 @@ class FastByteArrayOutputStreamTests {
}
InputStream inputStream = this.os.getInputStream();
DigestUtils.appendMd5DigestAsHex(inputStream, builder);
builder.append('"');
builder.append("\"");
String actual = builder.toString();
assertThat(actual).isEqualTo("\"06225ca1e4533354c516e74512065331d\"");
}
@@ -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.
@@ -41,7 +41,7 @@ class StopWatchTests {
private static final long duration1 = 200;
private static final long duration2 = 100;
private static final long fudgeFactor = 100;
private static final long fudgeFactor = 50;
private final StopWatch stopWatch = new StopWatch(ID);
@@ -107,7 +107,7 @@ class StopWatchTests {
.isLessThanOrEqualTo(duration1 + duration2 + fudgeFactor);
assertThat(stopWatch.getTotalTimeSeconds())
.as("total time in seconds for task #2")
.isGreaterThanOrEqualTo((duration1 + duration2 - fudgeFactor) / 1000.0)
.isGreaterThanOrEqualTo((duration1 + duration2 - fudgeFactor) / 1000.0)
.isLessThanOrEqualTo((duration1 + duration2 + fudgeFactor) / 1000.0);
assertThat(stopWatch.getTaskCount()).isEqualTo(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.
@@ -612,7 +612,7 @@ class StringUtilsTests {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < components.length; i++) {
if (i != 0) {
sb.append(',');
sb.append(",");
}
sb.append(components[i]);
}
@@ -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.
@@ -137,7 +137,7 @@ public class ExpressionException extends RuntimeException {
StringBuilder output = new StringBuilder();
output.append("Expression [");
output.append(this.expressionString);
output.append(']');
output.append("]");
if (this.position >= 0) {
output.append(" @");
output.append(this.position);

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