mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
112 Commits
v4.3.24.RELEASE
...
4.3.x
| Author | SHA1 | Date | |
|---|---|---|---|
| 21648426e9 | |||
| 0b076b28f1 | |||
| 0abb17af9d | |||
| d5a80d2777 | |||
| 07455c8a27 | |||
| c45c67203c | |||
| aeb83fe1a3 | |||
| 0bf002dbe1 | |||
| 4ff521d769 | |||
| 9107aed878 | |||
| 4ba174311b | |||
| 09c8586ee4 | |||
| 8212151f16 | |||
| 65577671bc | |||
| d1d37534bf | |||
| 45322a72a5 | |||
| 678ea4ece7 | |||
| bacf6ca37b | |||
| 95c0f1108f | |||
| 06c76d8075 | |||
| 7056dd599f | |||
| bb5b12af3b | |||
| 2f75212eb6 | |||
| bdcb189e50 | |||
| caa22b7291 | |||
| 586677341c | |||
| 2d632eff0f | |||
| eec4a6d521 | |||
| a577f633ff | |||
| b6677ccbff | |||
| 6c977e9c2a | |||
| 265bc6cd65 | |||
| 3d2de9a378 | |||
| cc1f0e1186 | |||
| 17a47b30e9 | |||
| 5e5723c8ba | |||
| 9fcdaa7308 | |||
| ef6494584c | |||
| 88f792a5d7 | |||
| d8654607a4 | |||
| 93e42b8e4f | |||
| 70773468c2 | |||
| 6d524e1da5 | |||
| f38ab3863f | |||
| 94d459ebcf | |||
| b5887bfd83 | |||
| 299e2c8c46 | |||
| 3aae8b2dc8 | |||
| 85e3f23863 | |||
| 323977be2c | |||
| 2c1cca69e7 | |||
| 00c9875122 | |||
| 2010956076 | |||
| 9c73023e5a | |||
| 700fedef3e | |||
| 31cda09c93 | |||
| 16d4e0e6c4 | |||
| 6893207998 | |||
| 85c5a0c1a9 | |||
| f60bb825b0 | |||
| f929109415 | |||
| eb81337e69 | |||
| 01ec5d83e6 | |||
| 6e579b0474 | |||
| 322d7bed8a | |||
| ef1be1723e | |||
| 2dcce8ca31 | |||
| 032100ce55 | |||
| 444338160e | |||
| 58d11989ce | |||
| 2e132bd62b | |||
| 3cbd4a94ce | |||
| 71cd792e2a | |||
| 33dc3b0e50 | |||
| a10f9f280f | |||
| dcedd29deb | |||
| 9404a8a108 | |||
| ee2fe1deb1 | |||
| f190168095 | |||
| e1f950764e | |||
| 9cad93093a | |||
| b3fb79ea99 | |||
| f69440151d | |||
| d0506bc110 | |||
| 5c741a7cc7 | |||
| 8abe714687 | |||
| d1a34b9a7e | |||
| ace2e623d1 | |||
| 5d5867603a | |||
| 18ae3790e1 | |||
| 13b9f58c4a | |||
| f99b2f11da | |||
| 379e919b64 | |||
| 87152d7ccf | |||
| 5b9129724b | |||
| c14d2d37d4 | |||
| b7304651de | |||
| a8623dbbd7 | |||
| 4f0104231a | |||
| 34f8ec3c77 | |||
| 6e20f8d0a5 | |||
| e5a28f81c3 | |||
| 92abe2927e | |||
| 3f6ab6467a | |||
| e0883f5eaa | |||
| 5900639135 | |||
| 1345ec902e | |||
| 6eeb065036 | |||
| c096dc45e7 | |||
| 4b999cfe95 | |||
| ed3df72d67 | |||
| 9ad9025619 |
+17
-50
@@ -1,19 +1,16 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
||||
classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.2")
|
||||
classpath("io.spring.gradle:propdeps-plugin:0.0.9.RELEASE")
|
||||
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
|
||||
classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.2")
|
||||
classpath("ws.antonov.gradle.plugins:gradle-plugin-protobuf:0.9.1")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.sonarqube" version "1.1"
|
||||
}
|
||||
|
||||
ext {
|
||||
linkHomepage = 'https://projects.spring.io/spring-framework'
|
||||
linkCi = 'https://build.spring.io/browse/SPR'
|
||||
@@ -40,7 +37,7 @@ configure(allprojects) { project ->
|
||||
ext.ejbVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.3"
|
||||
ext.freemarkerVersion = "2.3.23"
|
||||
ext.groovyVersion = "2.4.15"
|
||||
ext.groovyVersion = "2.4.17"
|
||||
ext.gsonVersion = "2.8.5"
|
||||
ext.guavaVersion = "20.0"
|
||||
ext.hamcrestVersion = "1.3"
|
||||
@@ -62,7 +59,7 @@ configure(allprojects) { project ->
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.log4jVersion = "1.2.17"
|
||||
ext.nettyVersion = "4.1.36.Final"
|
||||
ext.nettyVersion = "4.1.39.Final"
|
||||
ext.okhttpVersion = "2.7.5"
|
||||
ext.okhttp3Version = "3.8.1"
|
||||
ext.openjpaVersion = "2.4.2"
|
||||
@@ -71,11 +68,11 @@ configure(allprojects) { project ->
|
||||
ext.romeVersion = "1.7.4"
|
||||
ext.slf4jVersion = "1.7.25"
|
||||
ext.snakeyamlVersion = "1.17"
|
||||
ext.snifferVersion = "1.17"
|
||||
ext.snifferVersion = "1.18"
|
||||
ext.testngVersion = "6.9.10"
|
||||
ext.tiles2Version = "2.2.2"
|
||||
ext.tiles3Version = "3.0.8"
|
||||
ext.tomcatVersion = "8.5.40"
|
||||
ext.tomcatVersion = "8.5.45"
|
||||
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
|
||||
ext.undertowVersion = "1.3.33.Final"
|
||||
ext.xmlunitVersion = "1.6"
|
||||
@@ -133,7 +130,8 @@ configure(allprojects) { project ->
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spring.io/libs-spring-framework-build" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -222,12 +220,6 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
|
||||
jacoco("org.jacoco:org.jacoco.agent:0.7.5.201505241946:runtime")
|
||||
}
|
||||
|
||||
gradle.taskGraph.whenReady {taskGraph ->
|
||||
if (taskGraph.hasTask(':sonarqube')) {
|
||||
test.jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=org.springframework.*"
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest.attributes["Created-By"] =
|
||||
"${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})"
|
||||
@@ -983,6 +975,10 @@ project("spring-websocket") {
|
||||
project("spring-test") {
|
||||
description = "Spring TestContext Framework"
|
||||
|
||||
// Disable warning for annotation processing in order to get the
|
||||
// build passing again after it mysteriously started failing in 2020.
|
||||
compileJava.options.compilerArgs -= "-Xlint:processing"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
optional(project(":spring-aop"))
|
||||
@@ -1130,20 +1126,6 @@ project("spring-framework-bom") {
|
||||
}
|
||||
}
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.projectName", "Spring Framework"
|
||||
property "sonar.profile", "Spring Framework"
|
||||
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
|
||||
property "sonar.links.homepage", linkHomepage
|
||||
property "sonar.links.ci", linkCi
|
||||
property "sonar.links.issue", linkIssue
|
||||
property "sonar.links.scm", linkScmUrl
|
||||
property "sonar.links.scm_dev", linkScmDevConnection
|
||||
property "sonar.java.coveragePlugin", "jacoco"
|
||||
}
|
||||
}
|
||||
|
||||
configure(rootProject) {
|
||||
description = "Spring Framework"
|
||||
|
||||
@@ -1273,14 +1255,14 @@ configure(rootProject) {
|
||||
def Properties schemas = new Properties();
|
||||
|
||||
subproject.sourceSets.main.resources.find {
|
||||
it.path.endsWith("META-INF/spring.schemas")
|
||||
(it.path.endsWith("META-INF/spring.schemas") || it.path.endsWith("META-INF\\spring.schemas"))
|
||||
}?.withInputStream { schemas.load(it) }
|
||||
|
||||
for (def key : schemas.keySet()) {
|
||||
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
|
||||
assert shortName != key
|
||||
File xsdFile = subproject.sourceSets.main.resources.find {
|
||||
it.path.endsWith(schemas.get(key))
|
||||
(it.path.endsWith(schemas.get(key)) || it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')))
|
||||
}
|
||||
assert xsdFile != null
|
||||
into (shortName) {
|
||||
@@ -1366,9 +1348,9 @@ configure(rootProject) {
|
||||
archives distZip
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
wrapper {
|
||||
description = "Generates gradlew[.bat] scripts"
|
||||
gradleVersion = "2.14.1"
|
||||
gradleVersion = "4.10.2"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
|
||||
@@ -1384,21 +1366,6 @@ configure(rootProject) {
|
||||
|
||||
}
|
||||
|
||||
configure([project(':spring-build-src'), project(':spring-framework-bom')]) {
|
||||
sonarqube {
|
||||
skipProject = true
|
||||
}
|
||||
}
|
||||
|
||||
configure(project(':spring-core')) {
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.exclusions",
|
||||
"src/main/java/org/springframework/cglib/**/*,src/main/java/org/springframework/asm/**/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Support publication of artifacts versioned by topic branch.
|
||||
* CI builds supply `-P BRANCH_NAME=<TOPIC>` to gradle at build time.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.3.24.BUILD-SNAPSHOT
|
||||
version=4.3.31.BUILD-SNAPSHOT
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
def projectName = matcher[0][1]
|
||||
def path = "/${projectName}"
|
||||
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
|
||||
def dependency = new ProjectDependency(path, project(":${projectName}").path)
|
||||
def dependency = new ProjectDependency(path)
|
||||
dependency.exported = true
|
||||
classpath.entries.add(dependency)
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,6 +1,5 @@
|
||||
#Wed Aug 17 21:21:18 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -34,11 +34,11 @@ DEFAULT_JVM_OPTS=""
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
@@ -155,11 +155,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
Vendored
-6
@@ -50,7 +50,6 @@ goto fail
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@@ -61,11 +60,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
+1
-1
@@ -649,7 +649,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
|
||||
if (tokens[currentIndex].endsWith(")")) {
|
||||
sb.append(tokens[currentIndex].substring(0, tokens[currentIndex].length() - 1));
|
||||
sb.append(tokens[currentIndex], 0, tokens[currentIndex].length() - 1);
|
||||
return new PointcutBody(numTokensConsumed, sb.toString().trim());
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -212,10 +212,12 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
|
||||
@Override
|
||||
public String[] getParameterNames() {
|
||||
if (this.parameterNames == null) {
|
||||
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
String[] parameterNames = this.parameterNames;
|
||||
if (parameterNames == null) {
|
||||
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
this.parameterNames = parameterNames;
|
||||
}
|
||||
return this.parameterNames;
|
||||
return parameterNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -80,9 +80,8 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new Converter<Method, Annotation>() {
|
||||
@Override
|
||||
public Annotation convert(Method method) {
|
||||
AspectJAnnotation<?> annotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (annotation != null ? annotation.getAnnotation() : null);
|
||||
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (ann != null ? ann.getAnnotation() : null);
|
||||
}
|
||||
}));
|
||||
comparator.addComparator(new ConvertingComparator<Method, String>(
|
||||
|
||||
+3
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -136,14 +136,8 @@ class AspectJPrecedenceComparator implements Comparator<Advisor> {
|
||||
}
|
||||
|
||||
private int getAspectDeclarationOrder(Advisor anAdvisor) {
|
||||
AspectJPrecedenceInformation precedenceInfo =
|
||||
AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
|
||||
if (precedenceInfo != null) {
|
||||
return precedenceInfo.getDeclarationOrder();
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
AspectJPrecedenceInformation precedenceInfo = AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
|
||||
return (precedenceInfo != null ? precedenceInfo.getDeclarationOrder() : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -30,13 +30,14 @@ public class AdviceEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link AdviceEntry} class.
|
||||
* @param kind the kind of advice represented by this entry (before, after, around, etc.)
|
||||
* Create a new {@code AdviceEntry} instance.
|
||||
* @param kind the kind of advice represented by this entry (before, after, around)
|
||||
*/
|
||||
public AdviceEntry(String kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Advice (" + this.kind + ")";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -30,13 +30,14 @@ public class AdvisorEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link AdvisorEntry} class.
|
||||
* Create a new {@code AdvisorEntry} instance.
|
||||
* @param name the bean name of the advisor
|
||||
*/
|
||||
public AdvisorEntry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Advisor '" + this.name + "'";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -61,12 +61,12 @@ public class AopNamespaceHandler extends NamespaceHandlerSupport {
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
// In 2.0 XSD as well as in 2.1 XSD.
|
||||
// In 2.0 XSD as well as in 2.5+ XSDs
|
||||
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
|
||||
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
|
||||
|
||||
// Only in 2.0 XSD: moved to context namespace as of 2.1
|
||||
// Only in 2.0 XSD: moved to context namespace in 2.5+
|
||||
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 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.
|
||||
@@ -34,7 +34,7 @@ public class AspectEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AspectEntry.
|
||||
* Create a new {@code AspectEntry} instance.
|
||||
* @param id the id of the aspect element
|
||||
* @param ref the bean name referenced by this aspect element
|
||||
*/
|
||||
@@ -43,6 +43,7 @@ public class AspectEntry implements ParseState.Entry {
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" : "ref='" + this.ref + "'");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,14 +28,16 @@ public class PointcutEntry implements ParseState.Entry {
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link PointcutEntry} class.
|
||||
* Create a new {@code PointcutEntry} instance.
|
||||
* @param name the bean name of the pointcut
|
||||
*/
|
||||
public PointcutEntry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pointcut '" + this.name + "'";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -328,10 +328,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
// TODO: small memory optimization here (can skip creation for methods with no advice)
|
||||
for (int x = 0; x < methods.length; x++) {
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
|
||||
Method method = methods[x];
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
|
||||
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
|
||||
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
|
||||
this.fixedInterceptorMap.put(methods[x].toString(), x);
|
||||
this.fixedInterceptorMap.put(methods.toString(), x);
|
||||
}
|
||||
|
||||
// Now copy both the callbacks from mainCallbacks
|
||||
@@ -614,8 +615,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args,
|
||||
this.targetClass, this.adviceChain, methodProxy);
|
||||
MethodInvocation invocation = new CglibMethodInvocation(
|
||||
proxy, this.target, method, args, this.targetClass, this.adviceChain, methodProxy);
|
||||
// If we get here, we need to create a MethodInvocation.
|
||||
Object retVal = invocation.proceed();
|
||||
retVal = processReturnType(proxy, this.target, method, retVal);
|
||||
@@ -783,7 +784,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* <dt>For advised methods:</dt>
|
||||
* <dd>If the target is static and the advice chain is frozen then a
|
||||
* FixedChainStaticTargetInterceptor specific to the method is used to
|
||||
* invoke the advice chain. Otherwise a DyanmicAdvisedInterceptor is
|
||||
* invoke the advice chain. Otherwise a DynamicAdvisedInterceptor is
|
||||
* used.</dd>
|
||||
* <dt>For non-advised methods:</dt>
|
||||
* <dd>Where it can be determined that the method will not return {@code this}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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,9 +21,7 @@ import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.Interceptor;
|
||||
@@ -334,11 +332,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
// an independent instance of the configuration.
|
||||
// In this case, no proxy will have an instance of this object's configuration,
|
||||
// but will have an independent copy.
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
|
||||
}
|
||||
|
||||
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
|
||||
|
||||
// The copy needs a fresh advisor chain, and a fresh TargetSource.
|
||||
TargetSource targetSource = freshTargetSource();
|
||||
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
|
||||
@@ -349,9 +344,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
}
|
||||
copy.setFrozen(this.freezeProxy);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Using ProxyCreatorSupport copy: " + copy);
|
||||
}
|
||||
return getProxy(copy.createAopProxy());
|
||||
}
|
||||
|
||||
@@ -438,16 +430,12 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
|
||||
// Materialize interceptor chain from bean names.
|
||||
for (String name : this.interceptorNames) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Configuring advisor or advice '" + name + "'");
|
||||
}
|
||||
|
||||
if (name.endsWith(GLOBAL_SUFFIX)) {
|
||||
if (!(this.beanFactory instanceof ListableBeanFactory)) {
|
||||
throw new AopConfigException(
|
||||
"Can only use global advisors or interceptors with a ListableBeanFactory");
|
||||
}
|
||||
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
|
||||
addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
|
||||
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
|
||||
}
|
||||
|
||||
@@ -464,7 +452,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
|
||||
advice = new PrototypePlaceholderAdvisor(name);
|
||||
}
|
||||
addAdvisorOnChainCreation(advice, name);
|
||||
addAdvisorOnChainCreation(advice);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,11 +475,10 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Refreshing bean named '" + pa.getBeanName() + "'");
|
||||
}
|
||||
// Replace the placeholder with a fresh prototype instance resulting
|
||||
// from a getBean() lookup
|
||||
// Replace the placeholder with a fresh prototype instance resulting from a getBean lookup
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
|
||||
"- cannot resolve prototype advisor '" + pa.getBeanName() + "'");
|
||||
throw new IllegalStateException("No BeanFactory available anymore (probably due to " +
|
||||
"serialization) - cannot resolve prototype advisor '" + pa.getBeanName() + "'");
|
||||
}
|
||||
Object bean = this.beanFactory.getBean(pa.getBeanName());
|
||||
Advisor refreshedAdvisor = namedBeanToAdvisor(bean);
|
||||
@@ -508,28 +495,26 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
/**
|
||||
* Add all global interceptors and pointcuts.
|
||||
*/
|
||||
private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
|
||||
private void addGlobalAdvisors(ListableBeanFactory beanFactory, String prefix) {
|
||||
String[] globalAdvisorNames =
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class);
|
||||
String[] globalInterceptorNames =
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class);
|
||||
List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
|
||||
Map<Object, String> names = new HashMap<Object, String>(beans.size());
|
||||
for (String name : globalAdvisorNames) {
|
||||
Object bean = beanFactory.getBean(name);
|
||||
beans.add(bean);
|
||||
names.put(bean, name);
|
||||
}
|
||||
for (String name : globalInterceptorNames) {
|
||||
Object bean = beanFactory.getBean(name);
|
||||
beans.add(bean);
|
||||
names.put(bean, name);
|
||||
}
|
||||
AnnotationAwareOrderComparator.sort(beans);
|
||||
for (Object bean : beans) {
|
||||
String name = names.get(bean);
|
||||
if (name.startsWith(prefix)) {
|
||||
addAdvisorOnChainCreation(bean, name);
|
||||
if (globalAdvisorNames.length > 0 || globalInterceptorNames.length > 0) {
|
||||
List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
|
||||
for (String name : globalAdvisorNames) {
|
||||
if (name.startsWith(prefix)) {
|
||||
beans.add(beanFactory.getBean(name));
|
||||
}
|
||||
}
|
||||
for (String name : globalInterceptorNames) {
|
||||
if (name.startsWith(prefix)) {
|
||||
beans.add(beanFactory.getBean(name));
|
||||
}
|
||||
}
|
||||
AnnotationAwareOrderComparator.sort(beans);
|
||||
for (Object bean : beans) {
|
||||
addAdvisorOnChainCreation(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -540,17 +525,11 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* Because of these three possibilities, we can't type the signature
|
||||
* more strongly.
|
||||
* @param next advice, advisor or target object
|
||||
* @param name bean name from which we obtained this object in our owning
|
||||
* bean factory
|
||||
*/
|
||||
private void addAdvisorOnChainCreation(Object next, String name) {
|
||||
private void addAdvisorOnChainCreation(Object next) {
|
||||
// We need to convert to an Advisor if necessary so that our source reference
|
||||
// matches what we find from superclass interceptors.
|
||||
Advisor advisor = namedBeanToAdvisor(next);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Adding advisor with name '" + name + "'");
|
||||
}
|
||||
addAdvisor(advisor);
|
||||
addAdvisor(namedBeanToAdvisor(next));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -561,9 +540,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
*/
|
||||
private TargetSource freshTargetSource() {
|
||||
if (this.targetName == null) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'.");
|
||||
}
|
||||
// Not refreshing target: bean name not specified in 'interceptorNames'
|
||||
return this.targetSource;
|
||||
}
|
||||
else {
|
||||
@@ -591,8 +568,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
// We expected this to be an Advisor or Advice,
|
||||
// but it wasn't. This is a configuration error.
|
||||
throw new AopConfigException("Unknown advisor type " + next.getClass() +
|
||||
"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
|
||||
"which may also be target or TargetSource", ex);
|
||||
"; can only include Advisor or Advice type beans in interceptorNames chain " +
|
||||
"except for last entry which may also be target instance or TargetSource", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,7 +580,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
protected void adviceChanged() {
|
||||
super.adviceChanged();
|
||||
if (this.singleton) {
|
||||
logger.debug("Advice has changed; recaching singleton instance");
|
||||
logger.debug("Advice has changed; re-caching singleton instance");
|
||||
synchronized (this) {
|
||||
this.singletonInstance = null;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -152,7 +152,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
|
||||
@Override
|
||||
public Object proceed() throws Throwable {
|
||||
// We start with an index of -1 and increment early.
|
||||
// We start with an index of -1 and increment early.
|
||||
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
|
||||
return invokeJoinpoint();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -24,12 +24,15 @@ import org.springframework.aop.Pointcut;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient class for building up pointcuts. All methods return
|
||||
* ComposablePointcut, so we can use a concise idiom like:
|
||||
* Convenient class for building up pointcuts.
|
||||
*
|
||||
* {@code
|
||||
* Pointcut pc = new ComposablePointcut().union(classFilter).intersection(methodMatcher).intersection(pointcut);
|
||||
* }
|
||||
* <p>All methods return {@code ComposablePointcut}, so we can use concise idioms
|
||||
* like in the following example.
|
||||
*
|
||||
* <pre class="code">Pointcut pc = new ComposablePointcut()
|
||||
* .union(classFilter)
|
||||
* .intersection(methodMatcher)
|
||||
* .intersection(pointcut);</pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -199,7 +202,7 @@ public class ComposablePointcut implements Pointcut, Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComposablePointcut: " + this.classFilter + ", " +this.methodMatcher;
|
||||
return "ComposablePointcut: " + this.classFilter + ", " + this.methodMatcher;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @since 11.11.2003
|
||||
*/
|
||||
@SuppressWarnings({"serial" })
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFilter, Ordered, Serializable {
|
||||
|
||||
private final Advice advice;
|
||||
@@ -81,25 +81,25 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
/**
|
||||
* Create a DefaultIntroductionAdvisor for the given advice.
|
||||
* @param advice the Advice to apply
|
||||
* @param intf the interface to introduce
|
||||
* @param ifc the interface to introduce
|
||||
*/
|
||||
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) {
|
||||
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {
|
||||
Assert.notNull(advice, "Advice must not be null");
|
||||
this.advice = advice;
|
||||
addInterface(intf);
|
||||
addInterface(ifc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the specified interface to the list of interfaces to introduce.
|
||||
* @param intf the interface to introduce
|
||||
* @param ifc the interface to introduce
|
||||
*/
|
||||
public void addInterface(Class<?> intf) {
|
||||
Assert.notNull(intf, "Interface must not be null");
|
||||
if (!intf.isInterface()) {
|
||||
throw new IllegalArgumentException("Specified class [" + intf.getName() + "] must be an interface");
|
||||
public void addInterface(Class<?> ifc) {
|
||||
Assert.notNull(ifc, "Interface must not be null");
|
||||
if (!ifc.isInterface()) {
|
||||
throw new IllegalArgumentException("Specified class [" + ifc.getName() + "] must be an interface");
|
||||
}
|
||||
this.interfaces.add(intf);
|
||||
this.interfaces.add(ifc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,8 +112,8 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
for (Class<?> ifc : this.interfaces) {
|
||||
if (this.advice instanceof DynamicIntroductionAdvice &&
|
||||
!((DynamicIntroductionAdvice) this.advice).implementsInterface(ifc)) {
|
||||
throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
|
||||
"does not implement interface [" + ifc.getName() + "] specified for introduction");
|
||||
throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
|
||||
"does not implement interface [" + ifc.getName() + "] specified for introduction");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,8 +26,9 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
/**
|
||||
* Pointcut bean for simple method name matches, as alternative to regexp patterns.
|
||||
* Does not handle overloaded methods: all methods with a given name will be eligible.
|
||||
* Pointcut bean for simple method name matches, as an alternative to regexp patterns.
|
||||
*
|
||||
* <p>Does not handle overloaded methods: all methods with a given name will be eligible.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,8 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Pointcut constants for matching getters and setters,
|
||||
* and static methods useful for manipulating and evaluating pointcuts.
|
||||
* These methods are particularly useful for composing pointcuts
|
||||
*
|
||||
* <p>These methods are particularly useful for composing pointcuts
|
||||
* using the union and intersection methods.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -61,7 +61,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AnnotationMatchingPointcut for the given annotation type.
|
||||
* Create a new AnnotationMatchingPointcut for the given annotation types.
|
||||
* @param classAnnotationType the annotation type to look for at the class level
|
||||
* (can be {@code null})
|
||||
* @param methodAnnotationType the annotation type to look for at the method level
|
||||
@@ -119,7 +119,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AnnotationMatchingPointcut: " + this.classFilter + ", " +this.methodMatcher;
|
||||
return "AnnotationMatchingPointcut: " + this.classFilter + ", " + this.methodMatcher;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -67,6 +67,7 @@ import java.io.Serializable;
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends AbstractDependencyInjectionAspect {
|
||||
|
||||
/**
|
||||
* Select initialization join point as object construction
|
||||
*/
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -32,8 +32,8 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
|
||||
* Concrete aspect that uses the {@link Configurable} annotation to identify
|
||||
* which classes need autowiring.
|
||||
*
|
||||
* <p>The bean name to look up will be taken from the {@code @Configurable}
|
||||
* annotation if specified, otherwise the default bean name to look up will be
|
||||
* <p>The bean name to look up will be taken from the {@code @Configurable}
|
||||
* annotation if specified; otherwise, the default bean name to look up will be
|
||||
* the fully qualified name of the class being configured.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
@@ -47,22 +47,26 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
|
||||
public aspect AnnotationBeanConfigurerAspect extends AbstractInterfaceDrivenDependencyInjectionAspect
|
||||
implements BeanFactoryAware, InitializingBean, DisposableBean {
|
||||
|
||||
private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
|
||||
private final BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
|
||||
this.beanConfigurerSupport.setBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
this.beanConfigurerSupport.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureBean(Object bean) {
|
||||
this.beanConfigurerSupport.configureBean(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
this.beanConfigurerSupport.destroy();
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.scheduling.config.TaskManagementConfigUtils;
|
||||
* @see org.springframework.scheduling.annotation.ProxyAsyncConfiguration
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJAsyncConfiguration extends AbstractAsyncConfiguration {
|
||||
|
||||
@Bean(name = TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,6 +35,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
* @see TransactionManagementConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
|
||||
|
||||
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
|
||||
|
||||
+9
-10
@@ -318,7 +318,6 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
callable.call(this.currentBeanDefinition);
|
||||
}
|
||||
return this.currentBeanDefinition.getBeanDefinition();
|
||||
|
||||
}
|
||||
finally {
|
||||
this.currentBeanDefinition = current;
|
||||
@@ -371,9 +370,9 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
else if ("ref".equals(name)) {
|
||||
String refName;
|
||||
if (args[0] == null)
|
||||
if (args[0] == null) {
|
||||
throw new IllegalArgumentException("Argument to ref() is not a valid bean or was not found");
|
||||
|
||||
}
|
||||
if (args[0] instanceof RuntimeBeanReference) {
|
||||
refName = ((RuntimeBeanReference) args[0]).getBeanName();
|
||||
}
|
||||
@@ -492,11 +491,11 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
Map.Entry factoryBeanEntry = (Map.Entry) ((Map) args[0]).entrySet().iterator().next();
|
||||
// If we have a closure body, that will be the last argument.
|
||||
// In between are the constructor args
|
||||
int constructorArgsTest = hasClosureArgument?2:1;
|
||||
int constructorArgsTest = (hasClosureArgument ? 2 : 1);
|
||||
// If we have more than this number of args, we have constructor args
|
||||
if (args.length > constructorArgsTest){
|
||||
// factory-method requires args
|
||||
int endOfConstructArgs = (hasClosureArgument? args.length - 1 : args.length);
|
||||
int endOfConstructArgs = (hasClosureArgument ? args.length - 1 : args.length);
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null,
|
||||
resolveConstructorArguments(args, 1, endOfConstructArgs));
|
||||
}
|
||||
@@ -514,7 +513,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
else {
|
||||
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length);
|
||||
currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
|
||||
}
|
||||
|
||||
if (hasClosureArgument) {
|
||||
@@ -633,7 +632,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
|
||||
/**
|
||||
* This method overrides property retrieval in the scope of the
|
||||
* {@code GroovyBeanDefinitionReader} to either:
|
||||
* {@code GroovyBeanDefinitionReader}. A property retrieval will either:
|
||||
* <ul>
|
||||
* <li>Retrieve a variable from the bean builder's binding if it exists
|
||||
* <li>Retrieve a RuntimeBeanReference for a specific bean if it exists
|
||||
@@ -684,8 +683,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
|
||||
private GroovyDynamicElementReader createDynamicElementReader(String namespace) {
|
||||
XmlReaderContext readerContext = this.groovyDslXmlBeanDefinitionReader.createReaderContext(new DescriptiveResource(
|
||||
"Groovy"));
|
||||
XmlReaderContext readerContext = this.groovyDslXmlBeanDefinitionReader.createReaderContext(
|
||||
new DescriptiveResource("Groovy"));
|
||||
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
|
||||
boolean decorating = (this.currentBeanDefinition != null);
|
||||
if (!decorating) {
|
||||
@@ -779,7 +778,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a bean definition property an ensures that any RuntimeBeanReference
|
||||
* Wraps a bean definition property and ensures that any RuntimeBeanReference
|
||||
* additions to it are deferred for resolution later.
|
||||
*/
|
||||
private class GroovyPropertyValue extends GroovyObjectSupport {
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -431,9 +431,12 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw createNotWritablePropertyException(tokens.canonicalName);
|
||||
if (this.suppressNotWritablePropertyException) {
|
||||
// Optimization for common ignoreUnknown=true scenario since the
|
||||
// exception would be caught and swallowed higher up anyway...
|
||||
return;
|
||||
}
|
||||
throw createNotWritablePropertyException(tokens.canonicalName);
|
||||
}
|
||||
|
||||
Object oldValue = null;
|
||||
@@ -815,7 +818,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
* @param propertyPath property path, which may be nested
|
||||
* @return a property accessor for the target bean
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
|
||||
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
|
||||
// Handle nested properties recursively.
|
||||
|
||||
+33
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -38,6 +38,8 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
|
||||
private boolean autoGrowNestedPaths = false;
|
||||
|
||||
boolean suppressNotWritablePropertyException = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void setExtractOldValueForEditor(boolean extractOldValueForEditor) {
|
||||
@@ -87,30 +89,41 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
List<PropertyAccessException> propertyAccessExceptions = null;
|
||||
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
|
||||
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
|
||||
for (PropertyValue pv : propertyValues) {
|
||||
try {
|
||||
// This method may throw any BeansException, which won't be caught
|
||||
|
||||
if (ignoreUnknown) {
|
||||
this.suppressNotWritablePropertyException = true;
|
||||
}
|
||||
try {
|
||||
for (PropertyValue pv : propertyValues) {
|
||||
// setPropertyValue may throw any BeansException, which won't be caught
|
||||
// here, if there is a critical failure such as no matching field.
|
||||
// We can attempt to deal only with less serious exceptions.
|
||||
setPropertyValue(pv);
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
if (!ignoreUnknown) {
|
||||
throw ex;
|
||||
try {
|
||||
setPropertyValue(pv);
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
catch (NullValueInNestedPathException ex) {
|
||||
if (!ignoreInvalid) {
|
||||
throw ex;
|
||||
catch (NotWritablePropertyException ex) {
|
||||
if (!ignoreUnknown) {
|
||||
throw ex;
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
catch (PropertyAccessException ex) {
|
||||
if (propertyAccessExceptions == null) {
|
||||
propertyAccessExceptions = new LinkedList<PropertyAccessException>();
|
||||
catch (NullValueInNestedPathException ex) {
|
||||
if (!ignoreInvalid) {
|
||||
throw ex;
|
||||
}
|
||||
// Otherwise, just ignore it and continue...
|
||||
}
|
||||
propertyAccessExceptions.add(ex);
|
||||
catch (PropertyAccessException ex) {
|
||||
if (propertyAccessExceptions == null) {
|
||||
propertyAccessExceptions = new LinkedList<PropertyAccessException>();
|
||||
}
|
||||
propertyAccessExceptions.add(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (ignoreUnknown) {
|
||||
this.suppressNotWritablePropertyException = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -45,8 +45,11 @@ import org.springframework.util.StringUtils;
|
||||
* Static convenience methods for JavaBeans: for instantiating beans,
|
||||
* checking bean property types, copying bean properties, etc.
|
||||
*
|
||||
* <p>Mainly for use within the framework, but to some degree also
|
||||
* useful for application classes.
|
||||
* <p>Mainly for internal use within the framework, but to some degree also
|
||||
* useful for application classes. Consider
|
||||
* <a href="https://commons.apache.org/proper/commons-beanutils/">Apache Commons BeanUtils</a>,
|
||||
* <a href="https://hotelsdotcom.github.io/bull/">BULL - Bean Utils Light Library</a>,
|
||||
* or similar third-party frameworks for more comprehensive bean utilities.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -432,7 +435,8 @@ public abstract class BeanUtils {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
String editorName = targetType.getName() + "Editor";
|
||||
String targetTypeName = targetType.getName();
|
||||
String editorName = targetTypeName + "Editor";
|
||||
try {
|
||||
Class<?> editorClass = cl.loadClass(editorName);
|
||||
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
|
||||
@@ -448,7 +452,7 @@ public abstract class BeanUtils {
|
||||
catch (ClassNotFoundException ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No property editor [" + editorName + "] found for type " +
|
||||
targetType.getName() + " according to 'Editor' suffix convention");
|
||||
targetTypeName + " according to 'Editor' suffix convention");
|
||||
}
|
||||
unknownEditorTypes.add(targetType);
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -69,7 +69,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
private CachedIntrospectionResults cachedIntrospectionResults;
|
||||
|
||||
/**
|
||||
* The security context used for invoking the property methods
|
||||
* The security context used for invoking the property methods.
|
||||
*/
|
||||
private AccessControlContext acc;
|
||||
|
||||
@@ -95,7 +95,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
|
||||
/**
|
||||
* Create a new BeanWrapperImpl for the given object.
|
||||
* @param object object wrapped by this BeanWrapper
|
||||
* @param object the object wrapped by this BeanWrapper
|
||||
*/
|
||||
public BeanWrapperImpl(Object object) {
|
||||
super(object);
|
||||
@@ -112,7 +112,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
/**
|
||||
* Create a new BeanWrapperImpl for the given object,
|
||||
* registering a nested path that the object is in.
|
||||
* @param object object wrapped by this BeanWrapper
|
||||
* @param object the object wrapped by this BeanWrapper
|
||||
* @param nestedPath the nested path of the object
|
||||
* @param rootObject the root object at the top of the path
|
||||
*/
|
||||
@@ -123,7 +123,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
/**
|
||||
* Create a new BeanWrapperImpl for the given object,
|
||||
* registering a nested path that the object is in.
|
||||
* @param object object wrapped by this BeanWrapper
|
||||
* @param object the object wrapped by this BeanWrapper
|
||||
* @param nestedPath the nested path of the object
|
||||
* @param parent the containing BeanWrapper (must not be {@code null})
|
||||
*/
|
||||
@@ -164,7 +164,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a lazily initializted CachedIntrospectionResults instance
|
||||
* Obtain a lazily initialized CachedIntrospectionResults instance
|
||||
* for the wrapped object.
|
||||
*/
|
||||
private CachedIntrospectionResults getCachedIntrospectionResults() {
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -43,9 +43,9 @@ import org.springframework.util.StringUtils;
|
||||
* Internal class that caches JavaBeans {@link java.beans.PropertyDescriptor}
|
||||
* information for a Java class. Not intended for direct use by application code.
|
||||
*
|
||||
* <p>Necessary for own caching of descriptors within the application's
|
||||
* ClassLoader, rather than rely on the JDK's system-wide BeanInfo cache
|
||||
* (in order to avoid leaks on ClassLoader shutdown).
|
||||
* <p>Necessary for Spring's own caching of bean descriptors within the application
|
||||
* {@link ClassLoader}, rather than relying on the JDK's system-wide {@link BeanInfo}
|
||||
* cache (in order to avoid leaks on individual application shutdown in a shared JVM).
|
||||
*
|
||||
* <p>Information is cached statically, so we don't need to create new
|
||||
* objects of this class for every JavaBean we manipulate. Hence, this class
|
||||
@@ -97,7 +97,7 @@ public class CachedIntrospectionResults {
|
||||
SpringProperties.getFlag(IGNORE_BEANINFO_PROPERTY_NAME);
|
||||
|
||||
/** Stores the BeanInfoFactory instances */
|
||||
private static List<BeanInfoFactory> beanInfoFactories = SpringFactoriesLoader.loadFactories(
|
||||
private static final List<BeanInfoFactory> beanInfoFactories = SpringFactoriesLoader.loadFactories(
|
||||
BeanInfoFactory.class, CachedIntrospectionResults.class.getClassLoader());
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -51,7 +51,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
|
||||
|
||||
/**
|
||||
* Create a new DirectFieldAccessor for the given object.
|
||||
* @param object object wrapped by this DirectFieldAccessor
|
||||
* @param object the object wrapped by this DirectFieldAccessor
|
||||
*/
|
||||
public DirectFieldAccessor(Object object) {
|
||||
super(object);
|
||||
@@ -60,7 +60,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
|
||||
/**
|
||||
* Create a new DirectFieldAccessor for the given object,
|
||||
* registering a nested path that the object is in.
|
||||
* @param object object wrapped by this DirectFieldAccessor
|
||||
* @param object the object wrapped by this DirectFieldAccessor
|
||||
* @param nestedPath the nested path of the object
|
||||
* @param parent the containing DirectFieldAccessor (must not be {@code null})
|
||||
*/
|
||||
@@ -90,8 +90,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
|
||||
@Override
|
||||
protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) {
|
||||
PropertyMatches matches = PropertyMatches.forField(propertyName, getRootClass());
|
||||
throw new NotWritablePropertyException(
|
||||
getRootClass(), getNestedPath() + propertyName,
|
||||
throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName,
|
||||
matches.buildErrorMessage(), matches.getPossibleMatches());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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,8 +41,8 @@ import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Decorator for a standard {@link BeanInfo} object, e.g. as created by
|
||||
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register static
|
||||
* and/or non-void returning setter methods. For example:
|
||||
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register
|
||||
* static and/or non-void returning setter methods. For example:
|
||||
*
|
||||
* <pre class="code">
|
||||
* public class Bean {
|
||||
@@ -216,7 +216,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
private String propertyNameFor(Method method) {
|
||||
return Introspector.decapitalize(method.getName().substring(3, method.getName().length()));
|
||||
return Introspector.decapitalize(method.getName().substring(3));
|
||||
}
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
/*
|
||||
* See java.beans.IndexedPropertyDescriptor#equals(java.lang.Object)
|
||||
* See java.beans.IndexedPropertyDescriptor#equals
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
+1
-1
@@ -516,7 +516,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
if (endIndex != -1) {
|
||||
String prefix = propertyPath.substring(0, startIndex);
|
||||
String key = propertyPath.substring(startIndex, endIndex + 1);
|
||||
String suffix = propertyPath.substring(endIndex + 1, propertyPath.length());
|
||||
String suffix = propertyPath.substring(endIndex + 1);
|
||||
// Strip the first key.
|
||||
strippedPaths.add(nestedPath + prefix + suffix);
|
||||
// Search for further keys to strip, with the first key stripped.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -255,7 +255,7 @@ class TypeConverterDelegate {
|
||||
}
|
||||
}
|
||||
String trimmedValue = ((String) convertedValue).trim();
|
||||
if (requiredType.isEnum() && "".equals(trimmedValue)) {
|
||||
if (requiredType.isEnum() && trimmedValue.isEmpty()) {
|
||||
// It's an empty enum identifier: reset the enum value to null.
|
||||
return null;
|
||||
}
|
||||
@@ -569,8 +569,7 @@ class TypeConverterDelegate {
|
||||
return original;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (; it.hasNext(); i++) {
|
||||
for (int i = 0; it.hasNext(); i++) {
|
||||
Object element = it.next();
|
||||
String indexedPropertyName = buildIndexedPropertyName(propertyName, i);
|
||||
Object convertedElement = convertIfNecessary(indexedPropertyName, null, element,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,10 +37,16 @@ package org.springframework.beans.factory;
|
||||
*
|
||||
* <p><b>{@code FactoryBean} is a programmatic contract. Implementations are not
|
||||
* supposed to rely on annotation-driven injection or other reflective facilities.</b>
|
||||
* {@link #getObjectType()} {@link #getObject()} invocations may arrive early in
|
||||
* the bootstrap process, even ahead of any post-processor setup. If you need access
|
||||
* {@link #getObjectType()} {@link #getObject()} invocations may arrive early in the
|
||||
* bootstrap process, even ahead of any post-processor setup. If you need access to
|
||||
* other beans, implement {@link BeanFactoryAware} and obtain them programmatically.
|
||||
*
|
||||
* <p><b>The container is only responsible for managing the lifecycle of the FactoryBean
|
||||
* instance, not the lifecycle of the objects created by the FactoryBean.</b> Therefore,
|
||||
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()}
|
||||
* will <i>not</i> be called automatically. Instead, a FactoryBean should implement
|
||||
* {@link DisposableBean} and delegate any such close call to the underlying object.
|
||||
*
|
||||
* <p>Finally, FactoryBean objects participate in the containing BeanFactory's
|
||||
* synchronization of bean creation. There is usually no need for internal
|
||||
* synchronization other than for purposes of lazy initialization within the
|
||||
@@ -49,6 +55,7 @@ package org.springframework.beans.factory;
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 08.03.2003
|
||||
* @param <T> the bean type
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.aop.framework.ProxyFactoryBean
|
||||
* @see org.springframework.jndi.JndiObjectFactoryBean
|
||||
|
||||
+14
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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,19 +23,21 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a constructor, field, setter method or config method as to be autowired by
|
||||
* Marks a constructor, field, setter method, or config method as to be autowired by
|
||||
* Spring's dependency injection facilities. This is an alternative to the JSR-330
|
||||
* {@link javax.inject.Inject} annotation, adding required-vs-optional semantics.
|
||||
*
|
||||
* <p>Only one constructor (at max) of any given bean class may declare this annotation
|
||||
* with the 'required' parameter set to {@code true}, indicating <i>the</i> constructor
|
||||
* to autowire when used as a Spring bean. If multiple <i>non-required</i> constructors
|
||||
* declare the annotation, they will be considered as candidates for autowiring.
|
||||
* The constructor with the greatest number of dependencies that can be satisfied by
|
||||
* matching beans in the Spring container will be chosen. If none of the candidates
|
||||
* can be satisfied, then a standard default constructor (if present) will be used.
|
||||
* If a class only declares a single constructor to begin with, it will always be used,
|
||||
* even if not annotated. An annotated constructor does not have to be public.
|
||||
* <p>Only one constructor of any given bean class may declare this annotation with
|
||||
* the 'required' attribute set to {@code true}, indicating <i>the</i> constructor
|
||||
* to autowire when used as a Spring bean. Furthermore, if the 'required' attribute
|
||||
* is set to {@code true}, only a single constructor may be annotated with
|
||||
* {@code @Autowired}. If multiple <i>non-required</i> constructors declare the
|
||||
* annotation, they will be considered as candidates for autowiring. The constructor
|
||||
* with the greatest number of dependencies that can be satisfied by matching beans
|
||||
* in the Spring container will be chosen. If none of the candidates can be satisfied,
|
||||
* then a primary/default constructor (if present) will be used. If a class only
|
||||
* declares a single constructor to begin with, it will always be used, even if not
|
||||
* annotated. An annotated constructor does not have to be public.
|
||||
*
|
||||
* <p>Fields are injected right after construction of a bean, before any config methods
|
||||
* are invoked. Such a config field does not have to be public.
|
||||
@@ -45,7 +47,7 @@ import java.lang.annotation.Target;
|
||||
* Bean property setter methods are effectively just a special case of such a general
|
||||
* config method. Such config methods do not have to be public.
|
||||
*
|
||||
* <p>In the case of a multi-arg constructor or method, the 'required' parameter is
|
||||
* <p>In the case of a multi-arg constructor or method, the 'required' attribute is
|
||||
* applicable to all arguments. Individual parameters may be declared as Java-8-style
|
||||
* {@link java.util.Optional}, overriding the base required semantics.
|
||||
*
|
||||
|
||||
+8
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -141,9 +141,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AutowiredAnnotationBeanPostProcessor
|
||||
* for Spring's standard {@link Autowired} annotation.
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
|
||||
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
|
||||
* standard {@link Autowired @Autowired} annotation.
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
|
||||
* if available.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AutowiredAnnotationBeanPostProcessor() {
|
||||
@@ -239,7 +240,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
|
||||
throws BeanCreationException {
|
||||
|
||||
// Let's check for lookup methods here..
|
||||
// Let's check for lookup methods here...
|
||||
if (!this.lookupMethodsChecked.contains(beanName)) {
|
||||
try {
|
||||
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
|
||||
@@ -249,7 +250,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
if (lookup != null) {
|
||||
LookupOverride override = new LookupOverride(method, lookup.value());
|
||||
try {
|
||||
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
|
||||
RootBeanDefinition mbd = (RootBeanDefinition)
|
||||
beanFactory.getMergedBeanDefinition(beanName);
|
||||
mbd.getMethodOverrides().addOverride(override);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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,12 +41,11 @@ import java.lang.annotation.Target;
|
||||
* regular constructors: i.e. lookup methods cannot get replaced on beans returned
|
||||
* from factory methods where we cannot dynamically provide a subclass for them.
|
||||
*
|
||||
* <p><b>Concrete limitations in typical Spring configuration scenarios:</b>
|
||||
* When used with component scanning or any other mechanism that filters out abstract
|
||||
* beans, provide stub implementations of your lookup methods to be able to declare
|
||||
* them as concrete classes. And please remember that lookup methods won't work on
|
||||
* beans returned from {@code @Bean} methods in configuration classes; you'll have
|
||||
* to resort to {@code @Inject Provider<TargetBean>} or the like instead.
|
||||
* <p><b>Recommendations for typical Spring configuration scenarios:</b>
|
||||
* When a concrete class may be needed in certain scenarios, consider providing stub
|
||||
* implementations of your lookup methods. And please remember that lookup methods
|
||||
* won't work on beans returned from {@code @Bean} methods in configuration classes;
|
||||
* you'll have to resort to {@code @Inject Provider<TargetBean>} or the like instead.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.1
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -401,7 +401,7 @@ public class ConstructorArgumentValues {
|
||||
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
|
||||
ValueHolder vh1 = entry.getValue();
|
||||
ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey());
|
||||
if (!vh1.contentEquals(vh2)) {
|
||||
if (vh2 == null || !vh1.contentEquals(vh2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -84,8 +84,9 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
*/
|
||||
public DependencyDescriptor(MethodParameter methodParameter, boolean required, boolean eager) {
|
||||
super(methodParameter);
|
||||
|
||||
this.declaringClass = methodParameter.getDeclaringClass();
|
||||
if (this.methodParameter.getMethod() != null) {
|
||||
if (methodParameter.getMethod() != null) {
|
||||
this.methodName = methodParameter.getMethod().getName();
|
||||
this.parameterTypes = methodParameter.getMethod().getParameterTypes();
|
||||
}
|
||||
@@ -117,6 +118,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
*/
|
||||
public DependencyDescriptor(Field field, boolean required, boolean eager) {
|
||||
super(field);
|
||||
|
||||
this.declaringClass = field.getDeclaringClass();
|
||||
this.fieldName = field.getName();
|
||||
this.required = required;
|
||||
@@ -129,6 +131,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
*/
|
||||
public DependencyDescriptor(DependencyDescriptor original) {
|
||||
super(original);
|
||||
|
||||
this.declaringClass = original.declaringClass;
|
||||
this.methodName = original.methodName;
|
||||
this.parameterTypes = original.parameterTypes;
|
||||
@@ -236,7 +239,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ResolvableType object for the wrapped parameter/field.
|
||||
* Build a {@link ResolvableType} object for the wrapped parameter/field.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ResolvableType getResolvableType() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,11 +24,11 @@ package org.springframework.beans.factory.parsing;
|
||||
*/
|
||||
public class BeanEntry implements ParseState.Entry {
|
||||
|
||||
private String beanDefinitionName;
|
||||
private final String beanDefinitionName;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link BeanEntry} class.
|
||||
* Create a new {@code BeanEntry} instance.
|
||||
* @param beanDefinitionName the name of the associated bean definition
|
||||
*/
|
||||
public BeanEntry(String beanDefinitionName) {
|
||||
|
||||
+13
-17
@@ -20,23 +20,17 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Simple {@link Stack}-based structure for tracking the logical position during
|
||||
* a parsing process. {@link Entry entries} are added to the stack at
|
||||
* each point during the parse phase in a reader-specific manner.
|
||||
* a parsing process. {@link Entry entries} are added to the stack at each point
|
||||
* during the parse phase in a reader-specific manner.
|
||||
*
|
||||
* <p>Calling {@link #toString()} will render a tree-style view of the current logical
|
||||
* position in the parse phase. This representation is intended for use in
|
||||
* error messages.
|
||||
* position in the parse phase. This representation is intended for use in error messages.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class ParseState {
|
||||
|
||||
/**
|
||||
* Tab character used when rendering the tree-style representation.
|
||||
*/
|
||||
private static final char TAB = '\t';
|
||||
|
||||
/**
|
||||
* Internal {@link Stack} storage.
|
||||
*/
|
||||
@@ -51,7 +45,7 @@ public final class ParseState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ParseState} whose {@link Stack} is a {@link Object#clone clone}
|
||||
* Create a new {@code ParseState} whose {@link Stack} is a clone
|
||||
* of that of the passed in {@code ParseState}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -79,7 +73,7 @@ public final class ParseState {
|
||||
* {@code null} if the {@link Stack} is empty.
|
||||
*/
|
||||
public Entry peek() {
|
||||
return this.state.empty() ? null : this.state.peek();
|
||||
return (this.state.empty() ? null : this.state.peek());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,16 +90,18 @@ public final class ParseState {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int x = 0; x < this.state.size(); x++) {
|
||||
if (x > 0) {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
int i = 0;
|
||||
for (ParseState.Entry entry : this.state) {
|
||||
if (i > 0) {
|
||||
sb.append('\n');
|
||||
for (int y = 0; y < x; y++) {
|
||||
sb.append(TAB);
|
||||
for (int j = 0; j < i; j++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
sb.append("-> ");
|
||||
}
|
||||
sb.append(this.state.get(x));
|
||||
sb.append(entry);
|
||||
i++;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -30,14 +30,12 @@ public class PropertyEntry implements ParseState.Entry {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link PropertyEntry} class.
|
||||
* Create a new {@code PropertyEntry} instance.
|
||||
* @param name the name of the JavaBean property represented by this instance
|
||||
* @throws IllegalArgumentException if the supplied {@code name} is {@code null}
|
||||
* or consists wholly of whitespace
|
||||
*/
|
||||
public PropertyEntry(String name) {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
throw new IllegalArgumentException("Invalid property name '" + name + "'.");
|
||||
throw new IllegalArgumentException("Invalid property name '" + name + "'");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -26,16 +26,21 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class QualifierEntry implements ParseState.Entry {
|
||||
|
||||
private String typeName;
|
||||
private final String typeName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code QualifierEntry} instance.
|
||||
* @param typeName the name of the qualifier type
|
||||
*/
|
||||
public QualifierEntry(String typeName) {
|
||||
if (!StringUtils.hasText(typeName)) {
|
||||
throw new IllegalArgumentException("Invalid qualifier type '" + typeName + "'.");
|
||||
throw new IllegalArgumentException("Invalid qualifier type '" + typeName + "'");
|
||||
}
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Qualifier '" + this.typeName + "'";
|
||||
|
||||
+13
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -294,7 +294,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
public void autowireBean(Object existingBean) {
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
initBeanWrapper(bw);
|
||||
@@ -314,7 +314,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (bd == null) {
|
||||
bd = new RootBeanDefinition(mbd);
|
||||
}
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
@@ -337,7 +337,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
return createBean(beanClass.getName(), bd, null);
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
|
||||
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
|
||||
}
|
||||
@@ -378,7 +378,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd =
|
||||
new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
initBeanWrapper(bw);
|
||||
populateBean(bd.getBeanClass().getName(), bd, bw);
|
||||
@@ -584,7 +584,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
"] in its raw version as part of a circular reference, but has eventually been " +
|
||||
"wrapped. This means that said other beans do not use the final version of the " +
|
||||
"bean. This is often the result of over-eager type matching - consider using " +
|
||||
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
|
||||
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,7 +605,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
@Override
|
||||
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
|
||||
Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
|
||||
|
||||
// Apply SmartInstantiationAwareBeanPostProcessors to predict the
|
||||
// eventual type after a before-instantiation shortcut.
|
||||
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||||
@@ -1221,43 +1220,33 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
|
||||
// state of the bean before properties are set. This can be used, for example,
|
||||
// to support styles of field injection.
|
||||
boolean continueWithPropertyPopulation = true;
|
||||
|
||||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof InstantiationAwareBeanPostProcessor) {
|
||||
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
|
||||
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
|
||||
continueWithPropertyPopulation = false;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!continueWithPropertyPopulation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
|
||||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
|
||||
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
|
||||
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
|
||||
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
|
||||
|
||||
// Add property values based on autowire by name if applicable.
|
||||
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
|
||||
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
|
||||
autowireByName(beanName, mbd, bw, newPvs);
|
||||
}
|
||||
|
||||
// Add property values based on autowire by type if applicable.
|
||||
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
|
||||
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
|
||||
autowireByType(beanName, mbd, bw, newPvs);
|
||||
}
|
||||
|
||||
pvs = newPvs;
|
||||
}
|
||||
|
||||
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
|
||||
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||||
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||||
|
||||
if (hasInstAwareBpps || needsDepCheck) {
|
||||
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
|
||||
+22
-8
@@ -362,10 +362,13 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class of the wrapped bean, if already resolved.
|
||||
* @return the bean class, or {@code null} if none defined
|
||||
* Return the class of the wrapped bean (assuming it is resolved already).
|
||||
* @return the bean class (never {@code null})
|
||||
* @throws IllegalStateException if the bean definition does not define a bean class,
|
||||
* or a specified bean class name has not been resolved into an actual Class
|
||||
* or a specified bean class name has not been resolved into an actual Class yet
|
||||
* @see #hasBeanClass()
|
||||
* @see #setBeanClass(Class)
|
||||
* @see #resolveBeanClass(ClassLoader)
|
||||
*/
|
||||
public Class<?> getBeanClass() throws IllegalStateException {
|
||||
Object beanClassObject = this.beanClass;
|
||||
@@ -381,6 +384,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
|
||||
/**
|
||||
* Return whether this definition specifies a bean class.
|
||||
* @see #getBeanClass()
|
||||
* @see #setBeanClass(Class)
|
||||
* @see #resolveBeanClass(ClassLoader)
|
||||
*/
|
||||
public boolean hasBeanClass() {
|
||||
return (this.beanClass instanceof Class);
|
||||
@@ -803,16 +809,20 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether or not the configured init method is the default.
|
||||
* <p>The default value is {@code false}.
|
||||
* Specify whether or not the configured initializer method is the default.
|
||||
* <p>The default value is {@code true} for a locally specified init method
|
||||
* but switched to {@code false} for a shared setting in a defaults section
|
||||
* (e.g. {@code bean init-method} versus {@code beans default-init-method}
|
||||
* level in XML) which might not apply to all contained bean definitions.
|
||||
* @see #setInitMethodName
|
||||
* @see #applyDefaults
|
||||
*/
|
||||
public void setEnforceInitMethod(boolean enforceInitMethod) {
|
||||
this.enforceInitMethod = enforceInitMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether the configured init method is the default.
|
||||
* Indicate whether the configured initializer method is the default.
|
||||
* @see #getInitMethodName()
|
||||
*/
|
||||
public boolean isEnforceInitMethod() {
|
||||
@@ -836,8 +846,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
|
||||
/**
|
||||
* Specify whether or not the configured destroy method is the default.
|
||||
* <p>The default value is {@code false}.
|
||||
* <p>The default value is {@code true} for a locally specified destroy method
|
||||
* but switched to {@code false} for a shared setting in a defaults section
|
||||
* (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
|
||||
* level in XML) which might not apply to all contained bean definitions.
|
||||
* @see #setDestroyMethodName
|
||||
* @see #applyDefaults
|
||||
*/
|
||||
public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
|
||||
this.enforceDestroyMethod = enforceDestroyMethod;
|
||||
@@ -845,7 +859,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
|
||||
/**
|
||||
* Indicate whether the configured destroy method is the default.
|
||||
* @see #getDestroyMethodName
|
||||
* @see #getDestroyMethodName()
|
||||
*/
|
||||
public boolean isEnforceDestroyMethod() {
|
||||
return this.enforceDestroyMethod;
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -879,7 +879,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
/**
|
||||
* Return whether this factory holds a InstantiationAwareBeanPostProcessor
|
||||
* that will get applied to singleton beans on shutdown.
|
||||
* that will get applied to singleton beans on creation.
|
||||
* @see #addBeanPostProcessor
|
||||
* @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
|
||||
*/
|
||||
@@ -1280,7 +1280,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(parentBeanName,
|
||||
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
|
||||
"': cannot be resolved without an AbstractBeanFactory parent");
|
||||
"': cannot be resolved without a ConfigurableBeanFactory parent");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1295,7 +1295,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
// Set default singleton scope, if not configured before.
|
||||
if (!StringUtils.hasLength(mbd.getScope())) {
|
||||
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
|
||||
mbd.setScope(SCOPE_SINGLETON);
|
||||
}
|
||||
|
||||
// A bean contained in a non-singleton bean cannot be a singleton itself.
|
||||
@@ -1508,7 +1508,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* should be used as fallback.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @return the type for the bean if determinable, or {@code null} else
|
||||
* @return the type for the bean if determinable, or {@code null} otherwise
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
* @see #getBean(String)
|
||||
*/
|
||||
|
||||
+13
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see AbstractBeanDefinition#applyDefaults
|
||||
*/
|
||||
public class BeanDefinitionDefaults {
|
||||
|
||||
@@ -42,6 +43,7 @@ public class BeanDefinitionDefaults {
|
||||
* Set whether beans should be lazily initialized by default.
|
||||
* <p>If {@code false}, the bean will get instantiated on startup by bean
|
||||
* factories that perform eager initialization of singletons.
|
||||
* @see AbstractBeanDefinition#setLazyInit
|
||||
*/
|
||||
public void setLazyInit(boolean lazyInit) {
|
||||
this.lazyInit = lazyInit;
|
||||
@@ -63,6 +65,7 @@ public class BeanDefinitionDefaults {
|
||||
* (however, there may still be explicit annotation-driven autowiring).
|
||||
* @param autowireMode the autowire mode to set.
|
||||
* Must be one of the constants defined in {@link AbstractBeanDefinition}.
|
||||
* @see AbstractBeanDefinition#setAutowireMode
|
||||
*/
|
||||
public void setAutowireMode(int autowireMode) {
|
||||
this.autowireMode = autowireMode;
|
||||
@@ -79,6 +82,7 @@ public class BeanDefinitionDefaults {
|
||||
* Set the dependency check code.
|
||||
* @param dependencyCheck the code to set.
|
||||
* Must be one of the constants defined in {@link AbstractBeanDefinition}.
|
||||
* @see AbstractBeanDefinition#setDependencyCheck
|
||||
*/
|
||||
public void setDependencyCheck(int dependencyCheck) {
|
||||
this.dependencyCheck = dependencyCheck;
|
||||
@@ -93,6 +97,10 @@ public class BeanDefinitionDefaults {
|
||||
|
||||
/**
|
||||
* Set the name of the default initializer method.
|
||||
* <p>Note that this method is not enforced on all affected bean definitions
|
||||
* but rather taken as an optional callback, to be invoked if actually present.
|
||||
* @see AbstractBeanDefinition#setInitMethodName
|
||||
* @see AbstractBeanDefinition#setEnforceInitMethod
|
||||
*/
|
||||
public void setInitMethodName(String initMethodName) {
|
||||
this.initMethodName = (StringUtils.hasText(initMethodName) ? initMethodName : null);
|
||||
@@ -107,6 +115,10 @@ public class BeanDefinitionDefaults {
|
||||
|
||||
/**
|
||||
* Set the name of the default destroy method.
|
||||
* <p>Note that this method is not enforced on all affected bean definitions
|
||||
* but rather taken as an optional callback, to be invoked if actually present.
|
||||
* @see AbstractBeanDefinition#setDestroyMethodName
|
||||
* @see AbstractBeanDefinition#setEnforceDestroyMethod
|
||||
*/
|
||||
public void setDestroyMethodName(String destroyMethodName) {
|
||||
this.destroyMethodName = (StringUtils.hasText(destroyMethodName) ? destroyMethodName : null);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -246,7 +246,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
public int accept(Method method) {
|
||||
MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]");
|
||||
logger.trace("MethodOverride for " + method + ": " + methodOverride);
|
||||
}
|
||||
if (methodOverride == null) {
|
||||
return PASSTHROUGH;
|
||||
|
||||
+8
-5
@@ -90,8 +90,7 @@ import org.springframework.util.StringUtils;
|
||||
* operating on pre-resolved bean definition metadata objects.
|
||||
*
|
||||
* <p>Note that readers for specific bean definition formats are typically
|
||||
* implemented separately rather than as bean factory subclasses:
|
||||
* see for example {@link PropertiesBeanDefinitionReader} and
|
||||
* implemented separately rather than as bean factory subclasses: see for example
|
||||
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
|
||||
*
|
||||
* <p>For an alternative implementation of the
|
||||
@@ -179,7 +178,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
private volatile String[] frozenBeanDefinitionNames;
|
||||
|
||||
/** Whether bean definition metadata may be cached for all beans */
|
||||
private volatile boolean configurationFrozen = false;
|
||||
private volatile boolean configurationFrozen;
|
||||
|
||||
|
||||
/**
|
||||
@@ -323,7 +322,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
|
||||
this.dependencyComparator = otherListableFactory.dependencyComparator;
|
||||
// A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware...
|
||||
setAutowireCandidateResolver(BeanUtils.instantiateClass(getAutowireCandidateResolver().getClass()));
|
||||
setAutowireCandidateResolver(
|
||||
BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass()));
|
||||
// Make resolvable dependencies (e.g. ResourceLoader) available here as well...
|
||||
this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
|
||||
}
|
||||
@@ -860,6 +860,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (existingDefinition != null || containsSingleton(beanName)) {
|
||||
resetBeanDefinition(beanName);
|
||||
}
|
||||
else if (isConfigurationFrozen()) {
|
||||
clearByTypeCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -909,7 +912,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
for (String bdName : this.beanDefinitionNames) {
|
||||
if (!beanName.equals(bdName)) {
|
||||
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
|
||||
if (beanName.equals(bd.getParentName())) {
|
||||
if (bd != null && beanName.equals(bd.getParentName())) {
|
||||
resetBeanDefinition(bdName);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -622,6 +622,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* should <i>not</i> have their own mutexes involved in singleton creation,
|
||||
* to avoid the potential for deadlocks in lazy-init situations.
|
||||
*/
|
||||
@Override
|
||||
public final Object getSingletonMutex() {
|
||||
return this.singletonObjects;
|
||||
}
|
||||
|
||||
+10
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
|
||||
@@ -81,7 +82,14 @@ public class GenericBeanDefinition extends AbstractBeanDefinition {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof GenericBeanDefinition && super.equals(other)));
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof GenericBeanDefinition)) {
|
||||
return false;
|
||||
}
|
||||
GenericBeanDefinition that = (GenericBeanDefinition) other;
|
||||
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,9 +17,8 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* Set of method overrides, determining which, if any, methods on a
|
||||
@@ -35,10 +34,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class MethodOverrides {
|
||||
|
||||
private final Set<MethodOverride> overrides =
|
||||
Collections.synchronizedSet(new LinkedHashSet<MethodOverride>(0));
|
||||
|
||||
private volatile boolean modified = false;
|
||||
private final Set<MethodOverride> overrides = new CopyOnWriteArraySet<MethodOverride>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -60,7 +56,6 @@ public class MethodOverrides {
|
||||
*/
|
||||
public void addOverrides(MethodOverrides other) {
|
||||
if (other != null) {
|
||||
this.modified = true;
|
||||
this.overrides.addAll(other.overrides);
|
||||
}
|
||||
}
|
||||
@@ -69,17 +64,15 @@ public class MethodOverrides {
|
||||
* Add the given method override.
|
||||
*/
|
||||
public void addOverride(MethodOverride override) {
|
||||
this.modified = true;
|
||||
this.overrides.add(override);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all method overrides contained by this object.
|
||||
* @return Set of MethodOverride objects
|
||||
* @return a Set of MethodOverride objects
|
||||
* @see MethodOverride
|
||||
*/
|
||||
public Set<MethodOverride> getOverrides() {
|
||||
this.modified = true;
|
||||
return this.overrides;
|
||||
}
|
||||
|
||||
@@ -87,7 +80,7 @@ public class MethodOverrides {
|
||||
* Return whether the set of method overrides is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return (!this.modified || this.overrides.isEmpty());
|
||||
return this.overrides.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,18 +89,13 @@ public class MethodOverrides {
|
||||
* @return the method override, or {@code null} if none
|
||||
*/
|
||||
public MethodOverride getOverride(Method method) {
|
||||
if (!this.modified) {
|
||||
return null;
|
||||
}
|
||||
synchronized (this.overrides) {
|
||||
MethodOverride match = null;
|
||||
for (MethodOverride candidate : this.overrides) {
|
||||
if (candidate.matches(method)) {
|
||||
match = candidate;
|
||||
}
|
||||
MethodOverride match = null;
|
||||
for (MethodOverride candidate : this.overrides) {
|
||||
if (candidate.matches(method)) {
|
||||
match = candidate;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +109,6 @@ public class MethodOverrides {
|
||||
}
|
||||
MethodOverrides that = (MethodOverrides) other;
|
||||
return this.overrides.equals(that.overrides);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -38,7 +38,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
|
||||
private final String methodReplacerBeanName;
|
||||
|
||||
private List<String> typeIdentifiers = new LinkedList<String>();
|
||||
private final List<String> typeIdentifiers = new LinkedList<String>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
*/
|
||||
public ReplaceOverride(String methodName, String methodReplacerBeanName) {
|
||||
super(methodName);
|
||||
Assert.notNull(methodName, "Method replacer bean name must not be null");
|
||||
Assert.notNull(methodReplacerBeanName, "Method replacer bean name must not be null");
|
||||
this.methodReplacerBeanName = methodReplacerBeanName;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ public class ReplaceOverride extends MethodOverride {
|
||||
this.typeIdentifiers.add(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method) {
|
||||
if (!method.getName().equals(getMethodName())) {
|
||||
|
||||
+14
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -40,20 +40,22 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Static {@link org.springframework.beans.factory.BeanFactory} implementation
|
||||
* which allows to register existing singleton instances programmatically.
|
||||
* Does not have support for prototype beans or aliases.
|
||||
* which allows one to register existing singleton instances programmatically.
|
||||
*
|
||||
* <p>Serves as example for a simple implementation of the
|
||||
* <p>Does not have support for prototype beans or aliases.
|
||||
*
|
||||
* <p>Serves as an example for a simple implementation of the
|
||||
* {@link org.springframework.beans.factory.ListableBeanFactory} interface,
|
||||
* managing existing bean instances rather than creating new ones based on bean
|
||||
* definitions, and not implementing any extended SPI interfaces (such as
|
||||
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}).
|
||||
*
|
||||
* <p>For a full-fledged factory based on bean definitions, have a look
|
||||
* at {@link DefaultListableBeanFactory}.
|
||||
* <p>For a full-fledged factory based on bean definitions, have a look at
|
||||
* {@link DefaultListableBeanFactory}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 06.01.2003
|
||||
* @see DefaultListableBeanFactory
|
||||
*/
|
||||
@@ -78,7 +80,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
* or {@link java.util.Collections#emptyMap()} for a dummy factory which
|
||||
* enforces operating against an empty set of beans.
|
||||
* @param beans a {@code Map} for holding this factory's beans, with the
|
||||
* bean name String as key and the corresponding singleton object as value
|
||||
* bean name as key and the corresponding singleton object as value
|
||||
* @since 4.3
|
||||
*/
|
||||
public StaticListableBeanFactory(Map<String, Object> beans) {
|
||||
@@ -89,7 +91,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
|
||||
/**
|
||||
* Add a new singleton bean.
|
||||
* Will overwrite any existing instance for the given name.
|
||||
* <p>Will overwrite any existing instance for the given name.
|
||||
* @param name the name of the bean
|
||||
* @param bean the bean instance
|
||||
*/
|
||||
@@ -182,7 +184,10 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||
Object bean = getBean(name);
|
||||
// In case of FactoryBean, return singleton status of created object.
|
||||
return (bean instanceof FactoryBean && ((FactoryBean<?>) bean).isSingleton());
|
||||
if (bean instanceof FactoryBean) {
|
||||
return ((FactoryBean<?>) bean).isSingleton();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+64
-12
@@ -673,6 +673,9 @@ public class BeanDefinitionParserDelegate {
|
||||
parentName, className, this.readerContext.getBeanClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the meta elements underneath the given element, if any.
|
||||
*/
|
||||
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
|
||||
NodeList nl = ele.getChildNodes();
|
||||
for (int i = 0; i < nl.getLength(); i++) {
|
||||
@@ -688,23 +691,27 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given autowire attribute value into
|
||||
* {@link AbstractBeanDefinition} autowire constants.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getAutowireMode(String attValue) {
|
||||
String att = attValue;
|
||||
if (isDefaultValue(att)) {
|
||||
att = this.defaults.getAutowire();
|
||||
public int getAutowireMode(String attrValue) {
|
||||
String attr = attrValue;
|
||||
if (isDefaultValue(attr)) {
|
||||
attr = this.defaults.getAutowire();
|
||||
}
|
||||
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
|
||||
if (AUTOWIRE_BY_NAME_VALUE.equals(att)) {
|
||||
if (AUTOWIRE_BY_NAME_VALUE.equals(attr)) {
|
||||
autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME;
|
||||
}
|
||||
else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) {
|
||||
else if (AUTOWIRE_BY_TYPE_VALUE.equals(attr)) {
|
||||
autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
|
||||
}
|
||||
else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) {
|
||||
else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(attr)) {
|
||||
autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR;
|
||||
}
|
||||
else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) {
|
||||
else if (AUTOWIRE_AUTODETECT_VALUE.equals(attr)) {
|
||||
autowire = AbstractBeanDefinition.AUTOWIRE_AUTODETECT;
|
||||
}
|
||||
// Else leave default value.
|
||||
@@ -1001,6 +1008,12 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a value, ref or collection sub-element of a property or
|
||||
* constructor-arg element.
|
||||
* @param ele subelement of property element; we don't know which yet
|
||||
* @param bd the current bean definition (if any)
|
||||
*/
|
||||
public Object parsePropertySubElement(Element ele, BeanDefinition bd) {
|
||||
return parsePropertySubElement(ele, bd, null);
|
||||
}
|
||||
@@ -1009,6 +1022,7 @@ public class BeanDefinitionParserDelegate {
|
||||
* Parse a value, ref or collection sub-element of a property or
|
||||
* constructor-arg element.
|
||||
* @param ele subelement of property element; we don't know which yet
|
||||
* @param bd the current bean definition (if any)
|
||||
* @param defaultValueType the default type (class name) for any
|
||||
* {@code <value>} tag that might be created
|
||||
*/
|
||||
@@ -1396,10 +1410,21 @@ public class BeanDefinitionParserDelegate {
|
||||
return TRUE_VALUE.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a custom element (outside of the default namespace).
|
||||
* @param ele the element to parse
|
||||
* @return the resulting bean definition
|
||||
*/
|
||||
public BeanDefinition parseCustomElement(Element ele) {
|
||||
return parseCustomElement(ele, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a custom element (outside of the default namespace).
|
||||
* @param ele the element to parse
|
||||
* @param containingBd the containing bean definition (if any)
|
||||
* @return the resulting bean definition
|
||||
*/
|
||||
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
|
||||
String namespaceUri = getNamespaceURI(ele);
|
||||
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
|
||||
@@ -1410,14 +1435,27 @@ public class BeanDefinitionParserDelegate {
|
||||
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
|
||||
return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
|
||||
/**
|
||||
* Decorate the given bean definition through a namespace handler, if applicable.
|
||||
* @param ele the current element
|
||||
* @param originalDef the current bean definition
|
||||
* @return the decorated bean definition
|
||||
*/
|
||||
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) {
|
||||
return decorateBeanDefinitionIfRequired(ele, originalDef, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate the given bean definition through a namespace handler, if applicable.
|
||||
* @param ele the current element
|
||||
* @param originalDef the current bean definition
|
||||
* @param containingBd the containing bean definition (if any)
|
||||
* @return the decorated bean definition
|
||||
*/
|
||||
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
|
||||
Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {
|
||||
Element ele, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
|
||||
|
||||
BeanDefinitionHolder finalDefinition = definitionHolder;
|
||||
BeanDefinitionHolder finalDefinition = originalDef;
|
||||
|
||||
// Decorate based on custom attributes first.
|
||||
NamedNodeMap attributes = ele.getAttributes();
|
||||
@@ -1437,6 +1475,14 @@ public class BeanDefinitionParserDelegate {
|
||||
return finalDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate the given bean definition through a namespace handler,
|
||||
* if applicable.
|
||||
* @param node the current child node
|
||||
* @param originalDef the current bean definition
|
||||
* @param containingBd the containing bean definition (if any)
|
||||
* @return the decorated bean definition
|
||||
*/
|
||||
public BeanDefinitionHolder decorateIfRequired(
|
||||
Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
|
||||
|
||||
@@ -1511,10 +1557,16 @@ public class BeanDefinitionParserDelegate {
|
||||
return desiredName.equals(node.getNodeName()) || desiredName.equals(getLocalName(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given URI indicates the default namespace.
|
||||
*/
|
||||
public boolean isDefaultNamespace(String namespaceUri) {
|
||||
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given node indicates the default namespace.
|
||||
*/
|
||||
public boolean isDefaultNamespace(Node node) {
|
||||
return isDefaultNamespace(getNamespaceURI(node));
|
||||
}
|
||||
|
||||
+109
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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,7 @@ import static org.springframework.tests.TestResourceUtils.*;
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 04.07.2003
|
||||
*/
|
||||
public final class BeanFactoryUtilsTests {
|
||||
@@ -289,4 +290,111 @@ public final class BeanFactoryUtilsTests {
|
||||
assertTrue(Arrays.equals(new String[] { "buffer" }, deps));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSingletonAndIsPrototypeWithStaticFactory() {
|
||||
StaticListableBeanFactory lbf = new StaticListableBeanFactory();
|
||||
TestBean bean = new TestBean();
|
||||
DummyFactory fb1 = new DummyFactory();
|
||||
DummyFactory fb2 = new DummyFactory();
|
||||
fb2.setSingleton(false);
|
||||
TestBeanSmartFactoryBean sfb1 = new TestBeanSmartFactoryBean(true, true);
|
||||
TestBeanSmartFactoryBean sfb2 = new TestBeanSmartFactoryBean(true, false);
|
||||
TestBeanSmartFactoryBean sfb3 = new TestBeanSmartFactoryBean(false, true);
|
||||
TestBeanSmartFactoryBean sfb4 = new TestBeanSmartFactoryBean(false, false);
|
||||
lbf.addBean("bean", bean);
|
||||
lbf.addBean("fb1", fb1);
|
||||
lbf.addBean("fb2", fb2);
|
||||
lbf.addBean("sfb1", sfb1);
|
||||
lbf.addBean("sfb2", sfb2);
|
||||
lbf.addBean("sfb3", sfb3);
|
||||
lbf.addBean("sfb4", sfb4);
|
||||
|
||||
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, true);
|
||||
assertSame(bean, beans.get("bean"));
|
||||
assertSame(fb1.getObject(), beans.get("fb1"));
|
||||
assertTrue(beans.get("fb2") instanceof TestBean);
|
||||
assertTrue(beans.get("sfb1") instanceof TestBean);
|
||||
assertTrue(beans.get("sfb2") instanceof TestBean);
|
||||
assertTrue(beans.get("sfb3") instanceof TestBean);
|
||||
assertTrue(beans.get("sfb4") instanceof TestBean);
|
||||
|
||||
assertEquals(7, lbf.getBeanDefinitionCount());
|
||||
assertTrue(lbf.getBean("bean") instanceof TestBean);
|
||||
assertTrue(lbf.getBean("&fb1") instanceof FactoryBean);
|
||||
assertTrue(lbf.getBean("&fb2") instanceof FactoryBean);
|
||||
assertTrue(lbf.getBean("&sfb1") instanceof SmartFactoryBean);
|
||||
assertTrue(lbf.getBean("&sfb2") instanceof SmartFactoryBean);
|
||||
assertTrue(lbf.getBean("&sfb3") instanceof SmartFactoryBean);
|
||||
assertTrue(lbf.getBean("&sfb4") instanceof SmartFactoryBean);
|
||||
|
||||
assertTrue(lbf.isSingleton("bean"));
|
||||
assertTrue(lbf.isSingleton("fb1"));
|
||||
assertTrue(lbf.isSingleton("fb2"));
|
||||
assertTrue(lbf.isSingleton("sfb1"));
|
||||
assertTrue(lbf.isSingleton("sfb2"));
|
||||
assertTrue(lbf.isSingleton("sfb3"));
|
||||
assertTrue(lbf.isSingleton("sfb4"));
|
||||
|
||||
assertTrue(lbf.isSingleton("&fb1"));
|
||||
assertFalse(lbf.isSingleton("&fb2"));
|
||||
assertTrue(lbf.isSingleton("&sfb1"));
|
||||
assertTrue(lbf.isSingleton("&sfb2"));
|
||||
assertFalse(lbf.isSingleton("&sfb3"));
|
||||
assertFalse(lbf.isSingleton("&sfb4"));
|
||||
|
||||
assertFalse(lbf.isPrototype("bean"));
|
||||
assertFalse(lbf.isPrototype("fb1"));
|
||||
assertFalse(lbf.isPrototype("fb2"));
|
||||
assertFalse(lbf.isPrototype("sfb1"));
|
||||
assertFalse(lbf.isPrototype("sfb2"));
|
||||
assertFalse(lbf.isPrototype("sfb3"));
|
||||
assertFalse(lbf.isPrototype("sfb4"));
|
||||
|
||||
assertFalse(lbf.isPrototype("&fb1"));
|
||||
assertTrue(lbf.isPrototype("&fb2"));
|
||||
assertTrue(lbf.isPrototype("&sfb1"));
|
||||
assertFalse(lbf.isPrototype("&sfb2"));
|
||||
assertTrue(lbf.isPrototype("&sfb3"));
|
||||
assertTrue(lbf.isPrototype("&sfb4"));
|
||||
}
|
||||
|
||||
|
||||
static class TestBeanSmartFactoryBean implements SmartFactoryBean<TestBean> {
|
||||
|
||||
private final TestBean testBean = new TestBean("enigma", 42);
|
||||
private final boolean singleton;
|
||||
private final boolean prototype;
|
||||
|
||||
TestBeanSmartFactoryBean(boolean singleton, boolean prototype) {
|
||||
this.singleton = singleton;
|
||||
this.prototype = prototype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return this.singleton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrototype() {
|
||||
return this.prototype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEagerInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<TestBean> getObjectType() {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
public TestBean getObject() throws Exception {
|
||||
// We don't really care if the actual instance is a singleton or prototype
|
||||
// for the tests that use this factory.
|
||||
return this.testBean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+70
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -810,6 +810,19 @@ public class DefaultListableBeanFactoryTests {
|
||||
lbf.registerAlias("test", "test3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasChaining() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||
lbf.registerAlias("test", "testAlias");
|
||||
lbf.registerAlias("testAlias", "testAlias2");
|
||||
lbf.registerAlias("testAlias2", "testAlias3");
|
||||
Object bean = lbf.getBean("test");
|
||||
assertSame(bean, lbf.getBean("testAlias"));
|
||||
assertSame(bean, lbf.getBean("testAlias2"));
|
||||
assertSame(bean, lbf.getBean("testAlias3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanDefinitionOverriding() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
@@ -821,21 +834,6 @@ public class DefaultListableBeanFactoryTests {
|
||||
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanDefinitionRemoval() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.setAllowBeanDefinitionOverriding(false);
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
lbf.registerAlias("test", "test2");
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.removeBeanDefinition("test");
|
||||
lbf.removeAlias("test2");
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||
lbf.registerAlias("test", "test2");
|
||||
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
|
||||
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanDefinitionOverridingNotAllowed() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
@@ -863,16 +861,31 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasChaining() {
|
||||
public void beanDefinitionOverridingWithConstructorArgumentMismatch() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(NestedTestBean.class);
|
||||
bd1.getConstructorArgumentValues().addIndexedArgumentValue(1, "value1");
|
||||
lbf.registerBeanDefinition("test", bd1);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
|
||||
bd2.getConstructorArgumentValues().addIndexedArgumentValue(0, "value0");
|
||||
lbf.registerBeanDefinition("test", bd2);
|
||||
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
|
||||
assertEquals("value0", lbf.getBean("test", NestedTestBean.class).getCompany());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanDefinitionRemoval() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.setAllowBeanDefinitionOverriding(false);
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
|
||||
lbf.registerAlias("test", "test2");
|
||||
lbf.preInstantiateSingletons();
|
||||
lbf.removeBeanDefinition("test");
|
||||
lbf.removeAlias("test2");
|
||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||
lbf.registerAlias("test", "testAlias");
|
||||
lbf.registerAlias("testAlias", "testAlias2");
|
||||
lbf.registerAlias("testAlias2", "testAlias3");
|
||||
Object bean = lbf.getBean("test");
|
||||
assertSame(bean, lbf.getBean("testAlias"));
|
||||
assertSame(bean, lbf.getBean("testAlias2"));
|
||||
assertSame(bean, lbf.getBean("testAlias3"));
|
||||
lbf.registerAlias("test", "test2");
|
||||
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
|
||||
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1412,6 +1425,39 @@ public class DefaultListableBeanFactoryTests {
|
||||
lbf.getBean(TestBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanByTypeWithLateRegistration() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
try {
|
||||
lbf.getBean(TestBean.class);
|
||||
fail("Should have thrown NoSuchBeanDefinitionException");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// expected
|
||||
}
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName(), equalTo("bd1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanByTypeWithLateRegistrationAgainstFrozen() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.freezeConfiguration();
|
||||
try {
|
||||
lbf.getBean(TestBean.class);
|
||||
fail("Should have thrown NoSuchBeanDefinitionException");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// expected
|
||||
}
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("bd1", bd1);
|
||||
TestBean bean = lbf.getBean(TestBean.class);
|
||||
assertThat(bean.getBeanName(), equalTo("bd1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanByTypeDefinedInParent() {
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
|
||||
+20
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -100,6 +100,25 @@ public class BeanDefinitionTests {
|
||||
assertTrue(bd.hashCode() == otherBd.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericBeanDefinitionEquality() {
|
||||
GenericBeanDefinition bd = new GenericBeanDefinition();
|
||||
bd.setParentName("parent");
|
||||
bd.setScope("request");
|
||||
bd.setAbstract(true);
|
||||
bd.setLazyInit(true);
|
||||
GenericBeanDefinition otherBd = new GenericBeanDefinition();
|
||||
otherBd.setScope("request");
|
||||
otherBd.setAbstract(true);
|
||||
otherBd.setLazyInit(true);
|
||||
assertTrue(!bd.equals(otherBd));
|
||||
assertTrue(!otherBd.equals(bd));
|
||||
otherBd.setParentName("parent");
|
||||
assertTrue(bd.equals(otherBd));
|
||||
assertTrue(otherBd.equals(bd));
|
||||
assertTrue(bd.hashCode() == otherBd.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanDefinitionHolderEquality() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
|
||||
+6
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -49,7 +49,7 @@ public class DefaultNamespaceHandlerResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonExistentHandlerClass() throws Exception {
|
||||
public void testNonExistentHandlerClass() {
|
||||
String mappingPath = "org/springframework/beans/factory/xml/support/nonExistent.properties";
|
||||
try {
|
||||
new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), mappingPath);
|
||||
@@ -61,29 +61,18 @@ public class DefaultNamespaceHandlerResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveInvalidHandler() throws Exception {
|
||||
String mappingPath = "org/springframework/beans/factory/xml/support/invalid.properties";
|
||||
try {
|
||||
new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), mappingPath);
|
||||
fail("Should not be able to map a class that doesn't implement NamespaceHandler");
|
||||
}
|
||||
catch (Throwable expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithNullClassLoaderArgument() throws Exception {
|
||||
public void testCtorWithNullClassLoaderArgument() {
|
||||
// simply must not bail...
|
||||
new DefaultNamespaceHandlerResolver(null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testCtorWithNullClassLoaderArgumentAndNullMappingLocationArgument() throws Exception {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCtorWithNullClassLoaderArgumentAndNullMappingLocationArgument() {
|
||||
new DefaultNamespaceHandlerResolver(null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithNonExistentMappingLocationArgument() throws Exception {
|
||||
public void testCtorWithNonExistentMappingLocationArgument() {
|
||||
// simply must not bail; we don't want non-existent resources to result in an Exception
|
||||
new DefaultNamespaceHandlerResolver(null, "738trbc bobabloobop871");
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.3
|
||||
* @see CaffeineCacheManager
|
||||
*/
|
||||
@UsesJava8
|
||||
public class CaffeineCache extends AbstractValueAdaptingCache {
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -92,7 +92,6 @@ public class EhCacheCache implements Cache {
|
||||
this.cache.releaseWriteLockOnKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private <T> T loadValue(Object key, Callable<T> valueLoader) {
|
||||
|
||||
Vendored
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.cache.transaction.AbstractTransactionSupportingCacheM
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see EhCacheCache
|
||||
*/
|
||||
public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -27,13 +27,14 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.cache.Cache} implementation on top of a
|
||||
* {@link javax.cache.Cache} instance.
|
||||
* {@link Cache javax.cache.Cache} instance.
|
||||
*
|
||||
* <p>Note: This class has been updated for JCache 1.0, as of Spring 4.0.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.2
|
||||
* @see JCacheCacheManager
|
||||
*/
|
||||
public class JCacheCache extends AbstractValueAdaptingCache {
|
||||
|
||||
@@ -41,7 +42,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
|
||||
|
||||
|
||||
/**
|
||||
* Create an {@link org.springframework.cache.jcache.JCacheCache} instance.
|
||||
* Create a {@code JCacheCache} instance.
|
||||
* @param jcache backing JCache Cache instance
|
||||
*/
|
||||
public JCacheCache(Cache<Object, Object> jcache) {
|
||||
@@ -49,7 +50,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link org.springframework.cache.jcache.JCacheCache} instance.
|
||||
* Create a {@code JCacheCache} instance.
|
||||
* @param jcache backing JCache Cache instance
|
||||
* @param allowNullValues whether to accept and convert null values for this cache
|
||||
*/
|
||||
@@ -123,7 +124,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new EntryProcessorException("Value loader '" + valueLoader + "' failed " +
|
||||
"to compute value for key '" + entry.getKey() + "'", ex);
|
||||
"to compute value for key '" + entry.getKey() + "'", ex);
|
||||
}
|
||||
entry.setValue(toStoreValue(value));
|
||||
return value;
|
||||
|
||||
Vendored
+11
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -26,7 +26,7 @@ import org.springframework.cache.transaction.AbstractTransactionSupportingCacheM
|
||||
|
||||
/**
|
||||
* {@link org.springframework.cache.CacheManager} implementation
|
||||
* backed by a JCache {@link javax.cache.CacheManager}.
|
||||
* backed by a JCache {@link CacheManager javax.cache.CacheManager}.
|
||||
*
|
||||
* <p>Note: This class has been updated for JCache 1.0, as of Spring 4.0.
|
||||
*
|
||||
@@ -42,15 +42,18 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
|
||||
|
||||
|
||||
/**
|
||||
* Create a new JCacheCacheManager, setting the target JCache CacheManager
|
||||
* through the {@link #setCacheManager} bean property.
|
||||
* Create a new {@code JCacheCacheManager} without a backing JCache
|
||||
* {@link CacheManager javax.cache.CacheManager}.
|
||||
* <p>The backing JCache {@code javax.cache.CacheManager} can be set via the
|
||||
* {@link #setCacheManager} bean property.
|
||||
*/
|
||||
public JCacheCacheManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new JCacheCacheManager for the given backing JCache.
|
||||
* @param cacheManager the backing JCache {@link javax.cache.CacheManager}
|
||||
* Create a new {@code JCacheCacheManager} for the given backing JCache
|
||||
* {@link CacheManager javax.cache.CacheManager}.
|
||||
* @param cacheManager the backing JCache {@code javax.cache.CacheManager}
|
||||
*/
|
||||
public JCacheCacheManager(CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
@@ -58,14 +61,14 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
|
||||
|
||||
|
||||
/**
|
||||
* Set the backing JCache {@link javax.cache.CacheManager}.
|
||||
* Set the backing JCache {@link CacheManager javax.cache.CacheManager}.
|
||||
*/
|
||||
public void setCacheManager(CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the backing JCache {@link javax.cache.CacheManager}.
|
||||
* Return the backing JCache {@link CacheManager javax.cache.CacheManager}.
|
||||
*/
|
||||
public CacheManager getCacheManager() {
|
||||
return this.cacheManager;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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,7 @@ import org.springframework.context.annotation.Role;
|
||||
* @see JCacheConfigurer
|
||||
*/
|
||||
@Configuration
|
||||
public class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
|
||||
public abstract class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
protected CacheResolver exceptionCacheResolver;
|
||||
|
||||
|
||||
+1
@@ -77,6 +77,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
||||
return this.cacheOperationSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.state(getCacheOperationSource() != null, "The 'cacheOperationSource' property is required: " +
|
||||
"If there are no cacheable methods, then don't use a cache aspect.");
|
||||
|
||||
+11
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -24,14 +24,16 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Cache decorator which synchronizes its {@link #put}, {@link #evict} and {@link #clear}
|
||||
* operations with Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager},
|
||||
* performing the actual cache put/evict/clear operation only in the after-commit phase of a
|
||||
* successful transaction. If no transaction is active, {@link #put}, {@link #evict} and
|
||||
* Cache decorator which synchronizes its {@link #put}, {@link #evict} and
|
||||
* {@link #clear} operations with Spring-managed transactions (through Spring's
|
||||
* {@link TransactionSynchronizationManager}, performing the actual cache
|
||||
* put/evict/clear operation only in the after-commit phase of a successful
|
||||
* transaction. If no transaction is active, {@link #put}, {@link #evict} and
|
||||
* {@link #clear} operations will be performed immediately, as usual.
|
||||
*
|
||||
* <p>Use of more aggressive operations such as {@link #putIfAbsent} cannot be deferred
|
||||
* to the after-commit phase of a running transaction. Use these with care.
|
||||
* <p><b>Note:</b> Use of immediate operations such as {@link #putIfAbsent}
|
||||
* cannot be deferred to the after-commit phase of a running transaction.
|
||||
* Use these with care in a transactional environment.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
@@ -53,6 +55,7 @@ public class TransactionAwareCacheDecorator implements Cache {
|
||||
this.targetCache = targetCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the target Cache that this Cache should delegate to.
|
||||
*/
|
||||
@@ -101,7 +104,7 @@ public class TransactionAwareCacheDecorator implements Cache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueWrapper putIfAbsent(final Object key, final Object value) {
|
||||
public ValueWrapper putIfAbsent(Object key, Object value) {
|
||||
return this.targetCache.putIfAbsent(key, value);
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -56,9 +56,9 @@ import org.springframework.util.concurrent.ListenableFutureTask;
|
||||
* <p>The CommonJ WorkManager will usually be retrieved from the application
|
||||
* server's JNDI environment, as defined in the server's management console.
|
||||
*
|
||||
* <p>Note: On the upcoming EE 7 compliant versions of WebLogic and WebSphere, a
|
||||
* <p>Note: On EE 7/8 compliant versions of WebLogic and WebSphere, a
|
||||
* {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor}
|
||||
* should be preferred, following JSR-236 support in Java EE 7.
|
||||
* should be preferred, following JSR-236 support in Java EE 7/8.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
@@ -112,6 +112,11 @@ public class WorkManagerTaskExecutor extends JndiLocatorSupport
|
||||
* execution callback (which may be a wrapper around the user-supplied task).
|
||||
* <p>The primary use case is to set some execution context around the task's
|
||||
* invocation, or to provide some monitoring/statistics for task execution.
|
||||
* <p><b>NOTE:</b> Exception handling in {@code TaskDecorator} implementations
|
||||
* is limited to plain {@code Runnable} execution via {@code execute} calls.
|
||||
* In case of {@code #submit} calls, the exposed {@code Runnable} will be a
|
||||
* {@code FutureTask} which does not propagate any exceptions; you might
|
||||
* have to cast it and call {@code Future#get} to evaluate exceptions.
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setTaskDecorator(TaskDecorator taskDecorator) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ public abstract class FreeMarkerTemplateUtils {
|
||||
public static String processTemplateIntoString(Template template, Object model)
|
||||
throws IOException, TemplateException {
|
||||
|
||||
StringWriter result = new StringWriter();
|
||||
StringWriter result = new StringWriter(1024);
|
||||
template.process(model, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,22 +20,27 @@ import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Spring's central cache manager SPI.
|
||||
* Allows for retrieving named {@link Cache} regions.
|
||||
*
|
||||
* <p>Allows for retrieving named {@link Cache} regions.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface CacheManager {
|
||||
|
||||
/**
|
||||
* Return the cache associated with the given name.
|
||||
* Get the cache associated with the given name.
|
||||
* <p>Note that the cache may be lazily created at runtime if the
|
||||
* native provider supports it.
|
||||
* @param name the cache identifier (must not be {@code null})
|
||||
* @return the associated cache, or {@code null} if none found
|
||||
* @return the associated cache, or {@code null} if such a cache
|
||||
* does not exist or could be not created
|
||||
*/
|
||||
Cache getCache(String name);
|
||||
|
||||
/**
|
||||
* Return a collection of the cache names known by this manager.
|
||||
* Get a collection of the cache names known by this manager.
|
||||
* @return the names of all caches known by the cache manager
|
||||
*/
|
||||
Collection<String> getCacheNames();
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -50,6 +50,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -365,9 +366,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}));
|
||||
}
|
||||
catch (Cache.ValueRetrievalException ex) {
|
||||
// The invoker wraps any Throwable in a ThrowableWrapper instance so we
|
||||
// can just make sure that one bubbles up the stack.
|
||||
throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
|
||||
// Directly propagate ThrowableWrapper from the invoker,
|
||||
// or potentially also an IllegalArgumentException etc.
|
||||
ReflectionUtils.rethrowRuntimeException(ex.getCause());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+10
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -32,9 +32,14 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class SimpleKey implements Serializable {
|
||||
|
||||
/**
|
||||
* An empty key.
|
||||
*/
|
||||
public static final SimpleKey EMPTY = new SimpleKey();
|
||||
|
||||
|
||||
private final Object[] params;
|
||||
|
||||
private final int hashCode;
|
||||
|
||||
|
||||
@@ -49,10 +54,11 @@ public class SimpleKey implements Serializable {
|
||||
this.hashCode = Arrays.deepHashCode(this.params);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (this == obj || (obj instanceof SimpleKey
|
||||
&& Arrays.deepEquals(this.params, ((SimpleKey) obj).params)));
|
||||
public boolean equals(Object other) {
|
||||
return (this == other ||
|
||||
(other instanceof SimpleKey && Arrays.deepEquals(this.params, ((SimpleKey) other).params)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -171,15 +171,15 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a missing cache with the specified {@code name} or {@code null} if
|
||||
* such cache does not exist or could not be created on the fly.
|
||||
* <p>Some caches may be created at runtime if the native provider supports
|
||||
* it. If a lookup by name does not yield any result, a subclass gets a chance
|
||||
* to register such a cache at runtime. The returned cache will be automatically
|
||||
* added to this instance.
|
||||
* Return a missing cache with the specified {@code name}, or {@code null} if
|
||||
* such a cache does not exist or could not be created on demand.
|
||||
* <p>Caches may be lazily created at runtime if the native provider supports it.
|
||||
* If a lookup by name does not yield any result, an {@code AbstractCacheManager}
|
||||
* subclass gets a chance to register such a cache at runtime. The returned cache
|
||||
* will be automatically added to this cache manager.
|
||||
* @param name the name of the cache to retrieve
|
||||
* @return the missing cache or {@code null} if no such cache exists or could be
|
||||
* created
|
||||
* @return the missing cache, or {@code null} if no such cache exists or could be
|
||||
* created on demand
|
||||
* @since 4.1
|
||||
* @see #getCache(String)
|
||||
*/
|
||||
|
||||
Vendored
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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,7 @@ public abstract class AbstractValueAdaptingCache implements Cache {
|
||||
|
||||
@Override
|
||||
public ValueWrapper get(Object key) {
|
||||
Object value = lookup(key);
|
||||
return toValueWrapper(value);
|
||||
return toValueWrapper(lookup(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,5 +112,4 @@ public abstract class AbstractValueAdaptingCache implements Cache {
|
||||
return (storeValue != null ? new SimpleValueWrapper(fromStoreValue(storeValue)) : null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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,6 +29,7 @@ import org.springframework.util.Assert;
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.3.4
|
||||
* @see NoOpCacheManager
|
||||
*/
|
||||
public class NoOpCache implements Cache {
|
||||
|
||||
@@ -36,7 +37,7 @@ public class NoOpCache implements Cache {
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link NoOpCache} instance with the specified name
|
||||
* Create a {@link NoOpCache} instance with the specified name.
|
||||
* @param name the name of the cache
|
||||
*/
|
||||
public NoOpCache(String name) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -36,7 +36,7 @@ import org.springframework.cache.CacheManager;
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see CompositeCacheManager
|
||||
* @see NoOpCache
|
||||
*/
|
||||
public class NoOpCacheManager implements CacheManager {
|
||||
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -147,11 +147,12 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
void addProtocolResolver(ProtocolResolver resolver);
|
||||
|
||||
/**
|
||||
* Load or refresh the persistent representation of the configuration,
|
||||
* which might an XML file, properties file, or relational database schema.
|
||||
* Load or refresh the persistent representation of the configuration, which
|
||||
* might be from Java-based configuration, an XML file, a properties file, a
|
||||
* relational database schema, or some other format.
|
||||
* <p>As this is a startup method, it should destroy already created singletons
|
||||
* if it fails, to avoid dangling resources. In other words, after invocation
|
||||
* of that method, either all or no singletons at all should be instantiated.
|
||||
* of this method, either all or no singletons at all should be instantiated.
|
||||
* @throws BeansException if the bean factory could not be initialized
|
||||
* @throws IllegalStateException if already initialized and multiple refresh
|
||||
* attempts are not supported
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -24,10 +24,10 @@ import java.util.Locale;
|
||||
*
|
||||
* <p>Spring provides two out-of-the-box implementations for production:
|
||||
* <ul>
|
||||
* <li>{@link org.springframework.context.support.ResourceBundleMessageSource},
|
||||
* built on top of the standard {@link java.util.ResourceBundle}
|
||||
* <li>{@link org.springframework.context.support.ReloadableResourceBundleMessageSource},
|
||||
* being able to reload message definitions without restarting the VM
|
||||
* <li>{@link org.springframework.context.support.ResourceBundleMessageSource}: built
|
||||
* on top of the standard {@link java.util.ResourceBundle}, sharing its limitations.
|
||||
* <li>{@link org.springframework.context.support.ReloadableResourceBundleMessageSource}:
|
||||
* highly configurable, in particular with respect to reloading message definitions.
|
||||
* </ul>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
@@ -39,29 +39,33 @@ public interface MessageSource {
|
||||
|
||||
/**
|
||||
* Try to resolve the message. Return default message if no message was found.
|
||||
* @param code the code to lookup up, such as 'calculator.noRateSet'. Users of
|
||||
* this class are encouraged to base message names on the relevant fully
|
||||
* qualified class name, thus avoiding conflict and ensuring maximum clarity.
|
||||
* @param code the message code to look up, e.g. 'calculator.noRateSet'.
|
||||
* MessageSource users are encouraged to base message names on qualified class
|
||||
* or package names, avoiding potential conflicts and ensuring maximum clarity.
|
||||
* @param args an array of arguments that will be filled in for params within
|
||||
* the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
|
||||
* or {@code null} if none.
|
||||
* or {@code null} if none
|
||||
* @param defaultMessage a default message to return if the lookup fails
|
||||
* @param locale the locale in which to do the lookup
|
||||
* @return the resolved message if the lookup was successful;
|
||||
* otherwise the default message passed as a parameter
|
||||
* @return the resolved message if the lookup was successful, otherwise
|
||||
* the default message passed as a parameter (which may be {@code null})
|
||||
* @see #getMessage(MessageSourceResolvable, Locale)
|
||||
* @see java.text.MessageFormat
|
||||
*/
|
||||
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
|
||||
|
||||
/**
|
||||
* Try to resolve the message. Treat as an error if the message can't be found.
|
||||
* @param code the code to lookup up, such as 'calculator.noRateSet'
|
||||
* @param code the message code to look up, e.g. 'calculator.noRateSet'.
|
||||
* MessageSource users are encouraged to base message names on qualified class
|
||||
* or package names, avoiding potential conflicts and ensuring maximum clarity.
|
||||
* @param args an array of arguments that will be filled in for params within
|
||||
* the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
|
||||
* or {@code null} if none.
|
||||
* or {@code null} if none
|
||||
* @param locale the locale in which to do the lookup
|
||||
* @return the resolved message
|
||||
* @throws NoSuchMessageException if the message wasn't found
|
||||
* @return the resolved message (never {@code null})
|
||||
* @throws NoSuchMessageException if no corresponding message was found
|
||||
* @see #getMessage(MessageSourceResolvable, Locale)
|
||||
* @see java.text.MessageFormat
|
||||
*/
|
||||
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
|
||||
@@ -73,9 +77,15 @@ public interface MessageSource {
|
||||
* since at the time of calling this method we aren't able to determine if the
|
||||
* {@code defaultMessage} property of the resolvable is {@code null} or not.
|
||||
* @param resolvable the value object storing attributes required to resolve a message
|
||||
* (may include a default message)
|
||||
* @param locale the locale in which to do the lookup
|
||||
* @return the resolved message
|
||||
* @throws NoSuchMessageException if the message wasn't found
|
||||
* @return the resolved message (never {@code null} since even a
|
||||
* {@code MessageSourceResolvable}-provided default message needs to be non-null)
|
||||
* @throws NoSuchMessageException if no corresponding message was found
|
||||
* (and no default message was provided by the {@code MessageSourceResolvable})
|
||||
* @see MessageSourceResolvable#getCodes()
|
||||
* @see MessageSourceResolvable#getArguments()
|
||||
* @see MessageSourceResolvable#getDefaultMessage()
|
||||
* @see java.text.MessageFormat
|
||||
*/
|
||||
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -33,7 +33,8 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableAspectJAutoProxy
|
||||
* @see org.springframework.cache.annotation.EnableCaching
|
||||
* @see org.springframework.transaction.annotation.EnableTransactionManagement
|
||||
*/
|
||||
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -343,15 +343,16 @@ import org.springframework.stereotype.Component;
|
||||
*
|
||||
* <p>By default, {@code @Bean} methods will be <em>eagerly instantiated</em> at container
|
||||
* bootstrap time. To avoid this, {@code @Configuration} may be used in conjunction with
|
||||
* the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared within
|
||||
* the class are by default lazily initialized. Note that {@code @Lazy} may be used on
|
||||
* individual {@code @Bean} methods as well.
|
||||
* the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared
|
||||
* within the class are by default lazily initialized. Note that {@code @Lazy} may be used
|
||||
* on individual {@code @Bean} methods as well.
|
||||
*
|
||||
* <h2>Testing support for {@code @Configuration} classes</h2>
|
||||
*
|
||||
* <p>The Spring <em>TestContext framework</em> available in the {@code spring-test} module
|
||||
* provides the {@code @ContextConfiguration} annotation which can accept an array of
|
||||
* {@code @Configuration} {@code Class} objects:
|
||||
* <em>component class</em> references — typically {@code @Configuration} or
|
||||
* {@code @Component} classes.
|
||||
*
|
||||
* <pre class="code">
|
||||
* @RunWith(SpringRunner.class)
|
||||
|
||||
+28
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.context.annotation;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
@@ -458,7 +459,8 @@ class ConfigurationClassParser {
|
||||
catch (IOException ex) {
|
||||
// Resource not found when trying to open it
|
||||
if (ignoreResourceNotFound &&
|
||||
(ex instanceof FileNotFoundException || ex instanceof UnknownHostException)) {
|
||||
(ex instanceof FileNotFoundException || ex instanceof UnknownHostException ||
|
||||
ex instanceof SocketException)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
|
||||
}
|
||||
@@ -473,32 +475,35 @@ class ConfigurationClassParser {
|
||||
private void addPropertySource(PropertySource<?> propertySource) {
|
||||
String name = propertySource.getName();
|
||||
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
|
||||
if (propertySources.contains(name) && this.propertySourceNames.contains(name)) {
|
||||
|
||||
if (this.propertySourceNames.contains(name)) {
|
||||
// We've already added a version, we need to extend it
|
||||
PropertySource<?> existing = propertySources.get(name);
|
||||
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
|
||||
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
|
||||
if (existing instanceof CompositePropertySource) {
|
||||
((CompositePropertySource) existing).addFirstPropertySource(newSource);
|
||||
}
|
||||
else {
|
||||
if (existing instanceof ResourcePropertySource) {
|
||||
existing = ((ResourcePropertySource) existing).withResourceName();
|
||||
if (existing != null) {
|
||||
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
|
||||
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
|
||||
if (existing instanceof CompositePropertySource) {
|
||||
((CompositePropertySource) existing).addFirstPropertySource(newSource);
|
||||
}
|
||||
CompositePropertySource composite = new CompositePropertySource(name);
|
||||
composite.addPropertySource(newSource);
|
||||
composite.addPropertySource(existing);
|
||||
propertySources.replace(name, composite);
|
||||
else {
|
||||
if (existing instanceof ResourcePropertySource) {
|
||||
existing = ((ResourcePropertySource) existing).withResourceName();
|
||||
}
|
||||
CompositePropertySource composite = new CompositePropertySource(name);
|
||||
composite.addPropertySource(newSource);
|
||||
composite.addPropertySource(existing);
|
||||
propertySources.replace(name, composite);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.propertySourceNames.isEmpty()) {
|
||||
propertySources.addLast(propertySource);
|
||||
}
|
||||
else {
|
||||
if (this.propertySourceNames.isEmpty()) {
|
||||
propertySources.addLast(propertySource);
|
||||
}
|
||||
else {
|
||||
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
|
||||
propertySources.addBefore(firstProcessed, propertySource);
|
||||
}
|
||||
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
|
||||
propertySources.addBefore(firstProcessed, propertySource);
|
||||
}
|
||||
this.propertySourceNames.add(name);
|
||||
}
|
||||
@@ -675,7 +680,7 @@ class ConfigurationClassParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to obtain {@link SourceClass}s from class names.
|
||||
* Factory method to obtain a {@link SourceClass} collection from class names.
|
||||
*/
|
||||
private Collection<SourceClass> asSourceClasses(String[] classNames) throws IOException {
|
||||
List<SourceClass> annotatedClasses = new ArrayList<SourceClass>(classNames.length);
|
||||
|
||||
+21
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,12 +20,14 @@ import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
@@ -71,9 +73,11 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat
|
||||
}
|
||||
|
||||
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final String beanName) {
|
||||
Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
Assert.state(beanFactory instanceof DefaultListableBeanFactory,
|
||||
"BeanFactory needs to be a DefaultListableBeanFactory");
|
||||
final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
|
||||
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
|
||||
|
||||
TargetSource ts = new TargetSource() {
|
||||
@Override
|
||||
public Class<?> getTargetClass() {
|
||||
@@ -85,34 +89,43 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat
|
||||
}
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
|
||||
Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<String>(1) : null);
|
||||
Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
|
||||
if (target == null) {
|
||||
Class<?> type = getTargetClass();
|
||||
if (Map.class == type) {
|
||||
return Collections.EMPTY_MAP;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
else if (List.class == type) {
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else if (Set.class == type || Collection.class == type) {
|
||||
return Collections.EMPTY_SET;
|
||||
return Collections.emptySet();
|
||||
}
|
||||
throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
|
||||
"Optional dependency not present for lazy injection point");
|
||||
}
|
||||
if (autowiredBeanNames != null) {
|
||||
for (String autowiredBeanName : autowiredBeanNames) {
|
||||
if (dlbf.containsBean(autowiredBeanName)) {
|
||||
dlbf.registerDependentBean(autowiredBeanName, beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@Override
|
||||
public void releaseTarget(Object target) {
|
||||
}
|
||||
};
|
||||
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTargetSource(ts);
|
||||
Class<?> dependencyType = descriptor.getDependencyType();
|
||||
if (dependencyType.isInterface()) {
|
||||
pf.addInterface(dependencyType);
|
||||
}
|
||||
return pf.getProxy(beanFactory.getBeanClassLoader());
|
||||
return pf.getProxy(dlbf.getBeanClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -50,6 +50,7 @@ public interface ImportSelector {
|
||||
/**
|
||||
* Select and return the names of which class(es) should be imported based on
|
||||
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
|
||||
* @return the class names, or an empty array if none
|
||||
*/
|
||||
String[] selectImports(AnnotationMetadata importingClassMetadata);
|
||||
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -40,6 +40,7 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* @see ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoaderAware {
|
||||
|
||||
private AnnotationAttributes enableLTW;
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,6 +47,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see EnableMBeanExport
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class MBeanExportConfiguration implements ImportAware, EnvironmentAware, BeanFactoryAware {
|
||||
|
||||
private static final String MBEAN_EXPORTER_BEAN_NAME = "mbeanExporter";
|
||||
|
||||
+32
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,25 +54,30 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* Notice that the {@code Environment} object is
|
||||
* <p>Notice that the {@code Environment} object is
|
||||
* {@link org.springframework.beans.factory.annotation.Autowired @Autowired} into the
|
||||
* configuration class and then used when populating the {@code TestBean} object. Given
|
||||
* the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
|
||||
*
|
||||
* <h3>Resolving ${...} placeholders in {@code <bean>} and {@code @Value} annotations</h3>
|
||||
* <h3>Resolving <code>${...}</code> placeholders in {@code <bean>} and {@code @Value} annotations</h3>
|
||||
*
|
||||
* In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
|
||||
* annotations using properties from a {@code PropertySource}, one must register
|
||||
* a {@code PropertySourcesPlaceholderConfigurer}. This happens automatically when using
|
||||
* {@code <context:property-placeholder>} in XML, but must be explicitly registered using
|
||||
* a {@code static} {@code @Bean} method when using {@code @Configuration} classes. See
|
||||
* the "Working with externalized values" section of @{@link Configuration}'s javadoc and
|
||||
* "a note on BeanFactoryPostProcessor-returning @Bean methods" of @{@link Bean}'s javadoc
|
||||
* for details and examples.
|
||||
* <p>In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
|
||||
* annotations using properties from a {@code PropertySource}, you must ensure that an
|
||||
* appropriate <em>embedded value resolver</em> is registered in the {@code BeanFactory}
|
||||
* used by the {@code ApplicationContext}. This happens automatically when using
|
||||
* {@code <context:property-placeholder>} in XML. When using {@code @Configuration} classes
|
||||
* this can be achieved by explicitly registering a {@code PropertySourcesPlaceholderConfigurer}
|
||||
* via a {@code static} {@code @Bean} method. Note, however, that explicit registration
|
||||
* of a {@code PropertySourcesPlaceholderConfigurer} via a {@code static} {@code @Bean}
|
||||
* method is typically only required if you need to customize configuration such as the
|
||||
* placeholder syntax, etc. See the "Working with externalized values" section of
|
||||
* {@link Configuration @Configuration}'s javadocs and "a note on
|
||||
* BeanFactoryPostProcessor-returning {@code @Bean} methods" of {@link Bean @Bean}'s
|
||||
* javadocs for details and examples.
|
||||
*
|
||||
* <h3>Resolving ${...} placeholders within {@code @PropertySource} resource locations</h3>
|
||||
*
|
||||
* Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
|
||||
* <p>Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
|
||||
* resource location} will be resolved against the set of property sources already
|
||||
* registered against the environment. For example:
|
||||
*
|
||||
@@ -92,7 +97,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* Assuming that "my.placeholder" is present in one of the property sources already
|
||||
* <p>Assuming that "my.placeholder" is present in one of the property sources already
|
||||
* registered, e.g. system properties or environment variables, the placeholder will
|
||||
* be resolved to the corresponding value. If not, then "default/path" will be used as a
|
||||
* default. Expressing a default value (delimited by colon ":") is optional. If no
|
||||
@@ -101,10 +106,10 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
*
|
||||
* <h3>A note on property overriding with @PropertySource</h3>
|
||||
*
|
||||
* In cases where a given property key exists in more than one {@code .properties}
|
||||
* <p>In cases where a given property key exists in more than one {@code .properties}
|
||||
* file, the last {@code @PropertySource} annotation processed will 'win' and override.
|
||||
*
|
||||
* For example, given two properties files {@code a.properties} and
|
||||
* <p>For example, given two properties files {@code a.properties} and
|
||||
* {@code b.properties}, consider the following two configuration classes
|
||||
* that reference them with {@code @PropertySource} annotations:
|
||||
*
|
||||
@@ -118,7 +123,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* public class ConfigB { }
|
||||
* </pre>
|
||||
*
|
||||
* The override ordering depends on the order in which these classes are registered
|
||||
* <p>The override ordering depends on the order in which these classes are registered
|
||||
* with the application context.
|
||||
*
|
||||
* <pre class="code">
|
||||
@@ -128,12 +133,12 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* ctx.refresh();
|
||||
* </pre>
|
||||
*
|
||||
* In the scenario above, the properties in {@code b.properties} will override any
|
||||
* <p>In the scenario above, the properties in {@code b.properties} will override any
|
||||
* duplicates that exist in {@code a.properties}, because {@code ConfigB} was registered
|
||||
* last.
|
||||
*
|
||||
* <p>In certain situations, it may not be possible or practical to tightly control
|
||||
* property source ordering when using {@code @ProperySource} annotations. For example,
|
||||
* property source ordering when using {@code @PropertySource} annotations. For example,
|
||||
* if the {@code @Configuration} classes above were registered via component-scanning,
|
||||
* the ordering is difficult to predict. In such cases - and if overriding is important -
|
||||
* it is recommended that the user fall back to using the programmatic PropertySource API.
|
||||
@@ -150,6 +155,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
* @see PropertySources
|
||||
* @see Configuration
|
||||
@@ -164,8 +170,11 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
public @interface PropertySource {
|
||||
|
||||
/**
|
||||
* Indicate the name of this property source. If omitted, a name will
|
||||
* be generated based on the description of the underlying resource.
|
||||
* Indicate the name of this property source. If omitted, the {@link #factory()}
|
||||
* will generate a name based on the underlying resource (in the case of
|
||||
* {@link org.springframework.core.io.support.DefaultPropertySourceFactory}:
|
||||
* derived from the resource description through a corresponding name-less
|
||||
* {@link org.springframework.core.io.support.ResourcePropertySource} constructor).
|
||||
* @see org.springframework.core.env.PropertySource#getName()
|
||||
* @see org.springframework.core.io.Resource#getDescription()
|
||||
*/
|
||||
@@ -173,8 +182,9 @@ public @interface PropertySource {
|
||||
|
||||
/**
|
||||
* Indicate the resource location(s) of the properties file to be loaded.
|
||||
* For example, {@code "classpath:/com/myco/app.properties"} or
|
||||
* {@code "file:/path/to/file"}.
|
||||
* <p>Both traditional and XML-based properties file formats are supported
|
||||
* — for example, {@code "classpath:/com/myco/app.properties"}
|
||||
* or {@code "file:/path/to/file.xml"}.
|
||||
* <p>Resource location wildcards (e.g. **/*.properties) are not permitted;
|
||||
* each location must evaluate to exactly one {@code .properties} resource.
|
||||
* <p>${...} placeholders will be resolved against any/all property sources already
|
||||
|
||||
+15
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -68,10 +68,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
private Boolean allowCircularReferences;
|
||||
|
||||
/** Bean factory for this context */
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
|
||||
/** Synchronization monitor for the internal BeanFactory */
|
||||
private final Object beanFactoryMonitor = new Object();
|
||||
private volatile DefaultListableBeanFactory beanFactory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -127,9 +124,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
beanFactory.setSerializationId(getId());
|
||||
customizeBeanFactory(beanFactory);
|
||||
loadBeanDefinitions(beanFactory);
|
||||
synchronized (this.beanFactoryMonitor) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
|
||||
@@ -138,17 +133,18 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
|
||||
@Override
|
||||
protected void cancelRefresh(BeansException ex) {
|
||||
synchronized (this.beanFactoryMonitor) {
|
||||
if (this.beanFactory != null)
|
||||
this.beanFactory.setSerializationId(null);
|
||||
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||
if (beanFactory != null) {
|
||||
beanFactory.setSerializationId(null);
|
||||
}
|
||||
super.cancelRefresh(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void closeBeanFactory() {
|
||||
synchronized (this.beanFactoryMonitor) {
|
||||
this.beanFactory.setSerializationId(null);
|
||||
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||
if (beanFactory != null) {
|
||||
beanFactory.setSerializationId(null);
|
||||
this.beanFactory = null;
|
||||
}
|
||||
}
|
||||
@@ -158,20 +154,17 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
* i.e. has been refreshed at least once and not been closed yet.
|
||||
*/
|
||||
protected final boolean hasBeanFactory() {
|
||||
synchronized (this.beanFactoryMonitor) {
|
||||
return (this.beanFactory != null);
|
||||
}
|
||||
return (this.beanFactory != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ConfigurableListableBeanFactory getBeanFactory() {
|
||||
synchronized (this.beanFactoryMonitor) {
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
|
||||
"call 'refresh' before accessing beans via the ApplicationContext");
|
||||
}
|
||||
return this.beanFactory;
|
||||
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||
if (beanFactory == null) {
|
||||
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
|
||||
"call 'refresh' before accessing beans via the ApplicationContext");
|
||||
}
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
|
||||
* a non-classpath location.
|
||||
*/
|
||||
public void setCacheSeconds(int cacheSeconds) {
|
||||
this.cacheMillis = (cacheSeconds * 1000);
|
||||
this.cacheMillis = cacheSeconds * 1000L;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -237,6 +237,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
|
||||
if (mergedHolder != null) {
|
||||
return mergedHolder;
|
||||
}
|
||||
|
||||
Properties mergedProps = newProperties();
|
||||
long latestTimestamp = -1;
|
||||
String[] basenames = StringUtils.toStringArray(getBasenameSet());
|
||||
@@ -253,6 +254,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mergedHolder = new PropertiesHolder(mergedProps, latestTimestamp);
|
||||
PropertiesHolder existing = this.cachedMergedProperties.putIfAbsent(locale, mergedHolder);
|
||||
if (existing != null) {
|
||||
@@ -279,18 +281,28 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
|
||||
return filenames;
|
||||
}
|
||||
}
|
||||
|
||||
// Filenames for given Locale
|
||||
List<String> filenames = new ArrayList<String>(7);
|
||||
filenames.addAll(calculateFilenamesForLocale(basename, locale));
|
||||
if (isFallbackToSystemLocale() && !locale.equals(Locale.getDefault())) {
|
||||
List<String> fallbackFilenames = calculateFilenamesForLocale(basename, Locale.getDefault());
|
||||
for (String fallbackFilename : fallbackFilenames) {
|
||||
if (!filenames.contains(fallbackFilename)) {
|
||||
// Entry for fallback locale that isn't already in filenames list.
|
||||
filenames.add(fallbackFilename);
|
||||
|
||||
// Filenames for default Locale, if any
|
||||
if (isFallbackToSystemLocale()) {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
if (!locale.equals(defaultLocale)) {
|
||||
List<String> fallbackFilenames = calculateFilenamesForLocale(basename, defaultLocale);
|
||||
for (String fallbackFilename : fallbackFilenames) {
|
||||
if (!filenames.contains(fallbackFilename)) {
|
||||
// Entry for fallback locale that isn't already in filenames list.
|
||||
filenames.add(fallbackFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filename for default bundle file
|
||||
filenames.add(basename);
|
||||
|
||||
if (localeMap == null) {
|
||||
localeMap = new ConcurrentHashMap<Locale, List<String>>();
|
||||
Map<Locale, List<String>> existing = this.cachedFilenames.putIfAbsent(basename, localeMap);
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,9 @@ import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
import static org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.*;
|
||||
import static org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.DEFAULT_VALUE;
|
||||
import static org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.LAZY_INIT_ATTRIBUTE;
|
||||
import static org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.TRUE_VALUE;
|
||||
|
||||
/**
|
||||
* Abstract base class for BeanDefinitionParsers which build
|
||||
@@ -47,8 +49,9 @@ abstract class AbstractJndiLocatingBeanDefinitionParser extends AbstractSimpleBe
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return (super.isEligibleAttribute(attributeName) && !ENVIRONMENT_REF.equals(attributeName) && !LAZY_INIT_ATTRIBUTE
|
||||
.equals(attributeName));
|
||||
return (super.isEligibleAttribute(attributeName) &&
|
||||
!ENVIRONMENT_REF.equals(attributeName) &&
|
||||
!LAZY_INIT_ATTRIBUTE.equals(attributeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -105,7 +105,6 @@ public @interface DateTimeFormat {
|
||||
/**
|
||||
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSZ},
|
||||
* e.g. "2000-10-31T01:30:00.000-05:00".
|
||||
* <p>This is the default if no annotation value is specified.
|
||||
*/
|
||||
DATE_TIME,
|
||||
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ public class InterfaceBasedMBeanInfoAssembler extends AbstractConfigurableMBeanI
|
||||
* configured interfaces and is public, otherwise {@code false}.
|
||||
*/
|
||||
private boolean isPublicInInterface(Method method, String beanKey) {
|
||||
return ((method.getModifiers() & Modifier.PUBLIC) > 0) && isDeclaredInInterface(method, beanKey);
|
||||
return Modifier.isPublic(method.getModifiers()) && isDeclaredInInterface(method, beanKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 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.
|
||||
@@ -22,7 +22,7 @@ package org.springframework.jmx.export.metadata;
|
||||
* @author Rob Harrop
|
||||
* @since 1.2
|
||||
*/
|
||||
public class AbstractJmxAttribute {
|
||||
public abstract class AbstractJmxAttribute {
|
||||
|
||||
private String description = "";
|
||||
|
||||
|
||||
+6
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -136,6 +136,11 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche
|
||||
* execution callback (which may be a wrapper around the user-supplied task).
|
||||
* <p>The primary use case is to set some execution context around the task's
|
||||
* invocation, or to provide some monitoring/statistics for task execution.
|
||||
* <p><b>NOTE:</b> Exception handling in {@code TaskDecorator} implementations
|
||||
* is limited to plain {@code Runnable} execution via {@code execute} calls.
|
||||
* In case of {@code #submit} calls, the exposed {@code Runnable} will be a
|
||||
* {@code FutureTask} which does not propagate any exceptions; you might
|
||||
* have to cast it and call {@code Future#get} to evaluate exceptions.
|
||||
* @since 4.3
|
||||
*/
|
||||
public final void setTaskDecorator(TaskDecorator taskDecorator) {
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -26,7 +26,7 @@ import org.springframework.jndi.JndiTemplate;
|
||||
|
||||
/**
|
||||
* JNDI-based variant of {@link ConcurrentTaskExecutor}, performing a default lookup for
|
||||
* JSR-236's "java:comp/DefaultManagedExecutorService" in a Java EE 7 environment.
|
||||
* JSR-236's "java:comp/DefaultManagedExecutorService" in a Java EE 7/8 environment.
|
||||
*
|
||||
* <p>Note: This class is not strictly JSR-236 based; it can work with any regular
|
||||
* {@link java.util.concurrent.Executor} that can be found in JNDI.
|
||||
@@ -35,10 +35,11 @@ import org.springframework.jndi.JndiTemplate;
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @see javax.enterprise.concurrent.ManagedExecutorService
|
||||
*/
|
||||
public class DefaultManagedTaskExecutor extends ConcurrentTaskExecutor implements InitializingBean {
|
||||
|
||||
private JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
||||
private final JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
||||
|
||||
private String jndiName = "java:comp/DefaultManagedExecutorService";
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user