mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
217 Commits
main
...
v5.1.17.RELEASE
| Author | SHA1 | Date | |
|---|---|---|---|
| aa0d4a2530 | |||
| 35adf2b1bc | |||
| 6be892e03d | |||
| ab6b504692 | |||
| 515bae9195 | |||
| 7a793588fb | |||
| 1c5fb9a3e8 | |||
| d841af4e37 | |||
| ba8000d5b8 | |||
| d6d3023ed9 | |||
| f96a3d5ee1 | |||
| a53d28edf1 | |||
| a6f7386c9d | |||
| bca63918ab | |||
| 14d539017c | |||
| f4ae18fa89 | |||
| fc5a6db84b | |||
| 9a847dc5a0 | |||
| a82cf2fb7d | |||
| a6258b8b4f | |||
| 0400fc8443 | |||
| df9d09389f | |||
| 3d14970c03 | |||
| 236eea8de9 | |||
| 1b6afd52cb | |||
| 837d3e0ccf | |||
| 4173ceefa5 | |||
| 586235e9e4 | |||
| 4f81ab7e14 | |||
| 7281d44178 | |||
| f965c2f5af | |||
| cf5bbce3f8 | |||
| a80e36fd9f | |||
| 840ae05942 | |||
| b5928977d1 | |||
| 5cb950db3b | |||
| 4b7890315f | |||
| f81b1de2c0 | |||
| d9c98801bc | |||
| 70a2219fac | |||
| 083dd0e19d | |||
| e6553939b2 | |||
| 008d011d37 | |||
| 16ab43d957 | |||
| 6c5129b829 | |||
| e25e6a68cf | |||
| bb96bd4f48 | |||
| 370bf184af | |||
| cbcd8fdeba | |||
| 9bb534e74c | |||
| ec915bfd5d | |||
| 5c04c96d0e | |||
| 7d39fbea16 | |||
| 4ad7deda4c | |||
| 4ec02a7e53 | |||
| 2785ef0887 | |||
| b22e670668 | |||
| 436e9d8cdc | |||
| f474595dee | |||
| 42f60fe490 | |||
| ce76a9b5de | |||
| 6d26b962a9 | |||
| a4cc16051c | |||
| c8b49346b1 | |||
| 34b9ca310d | |||
| ea7b0103c5 | |||
| e3175a2dc9 | |||
| 91316dc11b | |||
| ac8d1df3ab | |||
| f023df703a | |||
| 9ab7cde00e | |||
| fad9b509ab | |||
| 5ddbefecea | |||
| a4bba6aff2 | |||
| 906583c40a | |||
| 3689b3fdd5 | |||
| 4a5bac97b5 | |||
| 45a270b71f | |||
| ef013f7158 | |||
| 818d18aa09 | |||
| 4715ad242e | |||
| e51f660286 | |||
| 9f71c98871 | |||
| dbb09334f3 | |||
| 5953d99d1c | |||
| c9be4f6874 | |||
| fbc63b0e32 | |||
| 5f7df0d14f | |||
| ee832206dc | |||
| 1e295c7bbb | |||
| 4fbba931a5 | |||
| 86f19f6cb6 | |||
| df60919bb0 | |||
| 2f1f36eeda | |||
| 1c0a4f8d78 | |||
| cc376ac5ed | |||
| 10c9d2fcec | |||
| 439ffe2e8a | |||
| 4e55262521 | |||
| ebd2ec57fc | |||
| f536819c5d | |||
| af75c6db2f | |||
| d12619cf1f | |||
| 4c1d227776 | |||
| da02b7a141 | |||
| 17117bd21a | |||
| 0d7494ac52 | |||
| a59a33846e | |||
| 51b8ba334a | |||
| abc2269d97 | |||
| ff385aaf7b | |||
| 1b50ca6bd3 | |||
| 6bae759349 | |||
| e1e8c165db | |||
| 6699833121 | |||
| 095acefd7e | |||
| b62e066b7d | |||
| 9969cb6d83 | |||
| 04b3f5a247 | |||
| c91b47fded | |||
| f2c364b491 | |||
| 170adccf80 | |||
| 98390e1e5e | |||
| 6df8c2678b | |||
| 7f49abb6d1 | |||
| b9bf56e41d | |||
| d0e3e2acfc | |||
| 18d983c686 | |||
| d8abbc501e | |||
| 6ce19ff861 | |||
| c8ef49cc8e | |||
| f61983d908 | |||
| 7615e0b036 | |||
| afe22b84c2 | |||
| 634aba4ab6 | |||
| 26a2d3875f | |||
| 802d083df7 | |||
| f5b43a264a | |||
| 59e4755562 | |||
| 2576aa4063 | |||
| 3fbe762832 | |||
| 611bb0b92e | |||
| 32a8b9b25a | |||
| 97cad6ca8e | |||
| 015f7d8ce1 | |||
| da4e2710b4 | |||
| a368040fd6 | |||
| 5dbd3b0bbf | |||
| 197dbffe20 | |||
| 5341e77796 | |||
| f049a6ec16 | |||
| 7203da7133 | |||
| a21df0cc6d | |||
| 83683a13bb | |||
| 59165dd526 | |||
| 25554d0b21 | |||
| 4f86282b14 | |||
| b3237f3eb6 | |||
| fd68fb115d | |||
| 43e047c523 | |||
| 7fdf775394 | |||
| 59084c6b73 | |||
| 4fcc09a02c | |||
| f5b082d3b3 | |||
| c164759c41 | |||
| 2179b67706 | |||
| fbde98f36e | |||
| 529f8ba786 | |||
| f4676bb41c | |||
| 262332a7c9 | |||
| 8b1709b8f3 | |||
| aee33d8b4b | |||
| 83f03976ea | |||
| ffcd83e3a8 | |||
| 9a522946a5 | |||
| 268d029584 | |||
| 85471d0587 | |||
| 96a1a0dec5 | |||
| 40ac055d11 | |||
| c9a6f4282a | |||
| 6ed6c08ace | |||
| e4c57a9b61 | |||
| b0d8a667a1 | |||
| 9c9ee22c2b | |||
| 639dce6282 | |||
| 8e65834c44 | |||
| 64db939e4a | |||
| 3d83f869d9 | |||
| 088a653318 | |||
| bdb1a81a39 | |||
| c2e7b6341c | |||
| e75556bc7b | |||
| d3d40983d6 | |||
| 32adf77b22 | |||
| 1301c7e95d | |||
| 1a057654b2 | |||
| ca3440cb42 | |||
| 48b22292ff | |||
| e0faaa4807 | |||
| 2e4944198d | |||
| 38a1caefb8 | |||
| e731a0a164 | |||
| 0f2efdbe97 | |||
| feeeab1761 | |||
| b4cf471021 | |||
| 82751141ac | |||
| 9f43ee3304 | |||
| 614c7b0f8e | |||
| cc84533d85 | |||
| 6faf61ba40 | |||
| 80a5019534 | |||
| 03bd02a627 | |||
| f16aa4a9b5 | |||
| a3c9e8d4fc | |||
| 3814f12b67 | |||
| ceb881ab05 | |||
| 871464811c |
@@ -0,0 +1,10 @@
|
||||
name: "Validate Gradle Wrapper"
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
@@ -24,6 +24,10 @@ buildSrc/build
|
||||
/src/asciidoc/build
|
||||
target/
|
||||
|
||||
# Projects not in this branch
|
||||
integration-tests/
|
||||
spring-core/kotlin-coroutines/
|
||||
|
||||
# Eclipse artifacts, including WTP generated manifests
|
||||
.classpath
|
||||
.project
|
||||
|
||||
+12
-12
@@ -28,24 +28,24 @@ ext {
|
||||
!it.name.equals("spring-build-src") && !it.name.equals("spring-framework-bom")
|
||||
}
|
||||
|
||||
aspectjVersion = "1.9.4"
|
||||
aspectjVersion = "1.9.5"
|
||||
freemarkerVersion = "2.3.28"
|
||||
groovyVersion = "2.5.8"
|
||||
groovyVersion = "2.5.9"
|
||||
hsqldbVersion = "2.4.1"
|
||||
jackson2Version = "2.9.9"
|
||||
jettyVersion = "9.4.21.v20190926"
|
||||
jettyVersion = "9.4.30.v20200611"
|
||||
junit5Version = "5.3.2"
|
||||
kotlinVersion = "1.2.71"
|
||||
log4jVersion = "2.11.2"
|
||||
nettyVersion = "4.1.43.Final"
|
||||
reactorVersion = "Californium-SR13"
|
||||
nettyVersion = "4.1.51.Final"
|
||||
reactorVersion = "Californium-SR20"
|
||||
rxjavaVersion = "1.3.8"
|
||||
rxjavaAdapterVersion = "1.2.1"
|
||||
rxjava2Version = "2.2.12"
|
||||
slf4jVersion = "1.7.28" // spring-jcl + consistent 3rd party deps
|
||||
rxjava2Version = "2.2.19"
|
||||
slf4jVersion = "1.7.30" // spring-jcl + consistent 3rd party deps
|
||||
tiles3Version = "3.0.8"
|
||||
tomcatVersion = "9.0.26"
|
||||
undertowVersion = "2.0.26.Final"
|
||||
tomcatVersion = "9.0.37"
|
||||
undertowVersion = "2.0.30.Final"
|
||||
|
||||
gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
withoutJclOverSlf4j = {
|
||||
@@ -142,13 +142,13 @@ configure(allprojects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.24"
|
||||
toolVersion = "8.34"
|
||||
configDir = rootProject.file("src/checkstyle")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -184,7 +184,7 @@ configure(allprojects) { project ->
|
||||
"https://tiles.apache.org/tiles-request/apidocs/",
|
||||
"https://tiles.apache.org/framework/apidocs/",
|
||||
"https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"https://www.ehcache.org/apidocs/2.10.4",
|
||||
"https://www.ehcache.org/apidocs/2.10.4/",
|
||||
"https://www.quartz-scheduler.org/api/2.3.0/",
|
||||
"https://fasterxml.github.io/jackson-core/javadoc/2.9/",
|
||||
"https://fasterxml.github.io/jackson-databind/javadoc/2.9/",
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=5.1.11.BUILD-SNAPSHOT
|
||||
version=5.1.17.RELEASE
|
||||
|
||||
+2
-2
@@ -149,14 +149,14 @@ task schemaZip(type: Zip) {
|
||||
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) {
|
||||
|
||||
@@ -4,6 +4,6 @@ dependencies {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.apache.commons:commons-pool2:2.6.0")
|
||||
optional("org.apache.commons:commons-pool2:2.6.2")
|
||||
optional("com.jamonapi:jamon:2.81")
|
||||
}
|
||||
|
||||
+7
-6
@@ -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.
|
||||
@@ -76,9 +76,8 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new InstanceComparator<>(
|
||||
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
|
||||
(Converter<Method, Annotation>) method -> {
|
||||
AspectJAnnotation<?> annotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (annotation != null ? annotation.getAnnotation() : null);
|
||||
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (ann != null ? ann.getAnnotation() : null);
|
||||
});
|
||||
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
|
||||
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
|
||||
@@ -153,8 +152,10 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
|
||||
methods.add(method);
|
||||
}
|
||||
});
|
||||
methods.sort(METHOD_COMPARATOR);
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
if (methods.size() > 1) {
|
||||
methods.sort(METHOD_COMPARATOR);
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
|
||||
+3
-9
@@ -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.
|
||||
@@ -138,14 +138,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.
|
||||
@@ -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-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.
|
||||
@@ -258,15 +258,17 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
int mod = method.getModifiers();
|
||||
if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) {
|
||||
if (Modifier.isFinal(mod)) {
|
||||
if (implementsInterface(method, ifcs)) {
|
||||
if (logger.isInfoEnabled() && implementsInterface(method, ifcs)) {
|
||||
logger.info("Unable to proxy interface-implementing method [" + method + "] because " +
|
||||
"it is marked as final: Consider using interface-based JDK proxies instead!");
|
||||
}
|
||||
logger.debug("Final method [" + method + "] cannot get proxied via CGLIB: " +
|
||||
"Calls to this method will NOT be routed to the target instance and " +
|
||||
"might lead to NPEs against uninitialized fields in the proxy instance.");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Final method [" + method + "] cannot get proxied via CGLIB: " +
|
||||
"Calls to this method will NOT be routed to the target instance and " +
|
||||
"might lead to NPEs against uninitialized fields in the proxy instance.");
|
||||
}
|
||||
}
|
||||
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) &&
|
||||
else if (logger.isDebugEnabled() && !Modifier.isPublic(mod) && !Modifier.isProtected(mod) &&
|
||||
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
|
||||
logger.debug("Method [" + method + "] is package-visible across different ClassLoaders " +
|
||||
"and cannot get proxied via CGLIB: Declare this method as public or protected " +
|
||||
@@ -526,7 +528,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
private static class StaticDispatcher implements Dispatcher, Serializable {
|
||||
|
||||
@Nullable
|
||||
private Object target;
|
||||
private final Object target;
|
||||
|
||||
public StaticDispatcher(@Nullable Object target) {
|
||||
this.target = target;
|
||||
@@ -552,7 +554,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object loadObject() throws Exception {
|
||||
public Object loadObject() {
|
||||
return this.advised;
|
||||
}
|
||||
}
|
||||
@@ -940,11 +942,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean equalsAdviceClasses(Advisor a, Advisor b) {
|
||||
private static boolean equalsAdviceClasses(Advisor a, Advisor b) {
|
||||
return (a.getAdvice().getClass() == b.getAdvice().getClass());
|
||||
}
|
||||
|
||||
private boolean equalsPointcuts(Advisor a, Advisor b) {
|
||||
private static boolean equalsPointcuts(Advisor a, Advisor b) {
|
||||
// If only one of the advisor (but not both) is PointcutAdvisor, then it is a mismatch.
|
||||
// Takes care of the situations where an IntroductionAdvisor is used (see SPR-3959).
|
||||
return (!(a instanceof PointcutAdvisor) ||
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
@@ -342,11 +340,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());
|
||||
@@ -359,9 +354,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
}
|
||||
copy.setFrozen(this.freezeProxy);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Using ProxyCreatorSupport copy: " + copy);
|
||||
}
|
||||
return getProxy(copy.createAopProxy());
|
||||
}
|
||||
|
||||
@@ -395,9 +387,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
logger.debug("Bean with name '" + finalName + "' concluding interceptor chain " +
|
||||
"is not an advisor class: treating it as a target or TargetSource");
|
||||
}
|
||||
String[] newNames = new String[this.interceptorNames.length - 1];
|
||||
System.arraycopy(this.interceptorNames, 0, newNames, 0, newNames.length);
|
||||
this.interceptorNames = newNames;
|
||||
this.interceptorNames = Arrays.copyOf(this.interceptorNames, this.interceptorNames.length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,16 +439,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()));
|
||||
}
|
||||
|
||||
@@ -475,7 +461,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -498,11 +484,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);
|
||||
@@ -519,28 +504,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<>(globalAdvisorNames.length + globalInterceptorNames.length);
|
||||
Map<Object, String> names = new HashMap<>(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<>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -551,17 +534,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,9 +549,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 {
|
||||
@@ -602,8 +577,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,7 +589,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
-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
|
||||
*/
|
||||
|
||||
+6
-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.
|
||||
@@ -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-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.
|
||||
@@ -37,6 +37,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-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.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
* @see TransactionManagementConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJJtaTransactionManagementConfiguration extends AspectJTransactionManagementConfiguration {
|
||||
|
||||
@Bean(name = TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_BEAN_NAME)
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -38,6 +38,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
* @see AspectJJtaTransactionManagementConfiguration
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
|
||||
|
||||
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
|
||||
|
||||
@@ -9,7 +9,7 @@ dependencies {
|
||||
optional("org.codehaus.groovy:groovy-xml:${groovyVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("javax.annotation:javax.annotation-api:1.3.2")
|
||||
}
|
||||
|
||||
// This module does joint compilation for Java and Groovy code with the compileGroovy task.
|
||||
|
||||
@@ -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.
|
||||
@@ -97,7 +97,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);
|
||||
@@ -114,7 +114,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
|
||||
*/
|
||||
@@ -125,7 +125,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})
|
||||
*/
|
||||
@@ -289,15 +289,15 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getValue() throws Exception {
|
||||
final Method readMethod = this.pd.getReadMethod();
|
||||
Method readMethod = this.pd.getReadMethod();
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(readMethod);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
readMethod.invoke(getWrappedInstance(), (Object[]) null), acc);
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> readMethod.invoke(getWrappedInstance(), (Object[]) null), acc);
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
@@ -310,8 +310,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(final @Nullable Object value) throws Exception {
|
||||
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
|
||||
public void setValue(@Nullable Object value) throws Exception {
|
||||
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
|
||||
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
|
||||
this.pd.getWriteMethod());
|
||||
if (System.getSecurityManager() != null) {
|
||||
@@ -320,8 +320,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
writeMethod.invoke(getWrappedInstance(), value), acc);
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
|
||||
}
|
||||
catch (PrivilegedActionException ex) {
|
||||
throw ex.getException();
|
||||
|
||||
+5
-6
@@ -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.
|
||||
@@ -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 final 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);
|
||||
@@ -163,7 +163,6 @@ public final class CachedIntrospectionResults {
|
||||
* @return the corresponding CachedIntrospectionResults
|
||||
* @throws BeansException in case of introspection failure
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static CachedIntrospectionResults forClass(Class<?> beanClass) throws BeansException {
|
||||
CachedIntrospectionResults results = strongClassCache.get(beanClass);
|
||||
if (results != null) {
|
||||
|
||||
@@ -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 {
|
||||
@@ -145,11 +145,10 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
|
||||
public static boolean isCandidateWriteMethod(Method method) {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
int nParams = parameterTypes.length;
|
||||
int nParams = method.getParameterCount();
|
||||
return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
|
||||
(!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) &&
|
||||
(nParams == 1 || (nParams == 2 && int.class == parameterTypes[0])));
|
||||
(nParams == 1 || (nParams == 2 && int.class == method.getParameterTypes()[0])));
|
||||
}
|
||||
|
||||
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
|
||||
@@ -209,7 +208,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));
|
||||
}
|
||||
|
||||
|
||||
@@ -488,7 +487,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
/*
|
||||
* See java.beans.IndexedPropertyDescriptor#equals(java.lang.Object)
|
||||
* See java.beans.IndexedPropertyDescriptor#equals
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
@@ -535,11 +534,13 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
public int compare(PropertyDescriptor desc1, PropertyDescriptor desc2) {
|
||||
String left = desc1.getName();
|
||||
String right = desc2.getName();
|
||||
byte[] leftBytes = left.getBytes();
|
||||
byte[] rightBytes = right.getBytes();
|
||||
for (int i = 0; i < left.length(); i++) {
|
||||
if (right.length() == i) {
|
||||
return 1;
|
||||
}
|
||||
int result = left.getBytes()[i] - right.getBytes()[i];
|
||||
int result = leftBytes[i] - rightBytes[i];
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -66,8 +66,7 @@ abstract class PropertyDescriptorUtils {
|
||||
Class<?> propertyType = null;
|
||||
|
||||
if (readMethod != null) {
|
||||
Class<?>[] params = readMethod.getParameterTypes();
|
||||
if (params.length != 0) {
|
||||
if (readMethod.getParameterCount() != 0) {
|
||||
throw new IntrospectionException("Bad read method arg count: " + readMethod);
|
||||
}
|
||||
propertyType = readMethod.getReturnType();
|
||||
|
||||
@@ -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.
|
||||
@@ -39,10 +39,16 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* <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
|
||||
|
||||
@@ -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-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.
|
||||
@@ -373,7 +373,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
|
||||
/**
|
||||
* Determine the name of the wrapped parameter/field.
|
||||
* @return the declared name (never {@code null})
|
||||
* @return the declared name (may be {@code null} if unresolvable)
|
||||
*/
|
||||
@Nullable
|
||||
public String getDependencyName() {
|
||||
|
||||
+60
-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.
|
||||
@@ -25,17 +25,23 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.reader.UnicodeReader;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -45,6 +51,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public abstract class YamlProcessor {
|
||||
@@ -59,6 +66,8 @@ public abstract class YamlProcessor {
|
||||
|
||||
private boolean matchDefault = true;
|
||||
|
||||
private Set<String> supportedTypes = Collections.emptySet();
|
||||
|
||||
|
||||
/**
|
||||
* A map of document matchers allowing callers to selectively use only
|
||||
@@ -117,6 +126,27 @@ public abstract class YamlProcessor {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the supported types that can be loaded from YAML documents.
|
||||
* <p>If no supported types are configured, all types encountered in YAML
|
||||
* documents will be supported. If an unsupported type is encountered, an
|
||||
* {@link IllegalStateException} will be thrown when the corresponding YAML
|
||||
* node is processed.
|
||||
* @param supportedTypes the supported types, or an empty array to clear the
|
||||
* supported types
|
||||
* @since 5.1.16
|
||||
* @see #createYaml()
|
||||
*/
|
||||
public void setSupportedTypes(Class<?>... supportedTypes) {
|
||||
if (ObjectUtils.isEmpty(supportedTypes)) {
|
||||
this.supportedTypes = Collections.emptySet();
|
||||
}
|
||||
else {
|
||||
Assert.noNullElements(supportedTypes, "'supportedTypes' must not contain null elements");
|
||||
this.supportedTypes = Arrays.stream(supportedTypes).map(Class::getName)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an opportunity for subclasses to process the Yaml parsed from the supplied
|
||||
@@ -142,12 +172,22 @@ public abstract class YamlProcessor {
|
||||
* Create the {@link Yaml} instance to use.
|
||||
* <p>The default implementation sets the "allowDuplicateKeys" flag to {@code false},
|
||||
* enabling built-in duplicate key handling in SnakeYAML 1.18+.
|
||||
* <p>As of Spring Framework 5.1.16, if custom {@linkplain #setSupportedTypes
|
||||
* supported types} have been configured, the default implementation creates
|
||||
* a {@code Yaml} instance that filters out unsupported types encountered in
|
||||
* YAML documents. If an unsupported type is encountered, an
|
||||
* {@link IllegalStateException} will be thrown when the node is processed.
|
||||
* @see LoaderOptions#setAllowDuplicateKeys(boolean)
|
||||
*/
|
||||
protected Yaml createYaml() {
|
||||
LoaderOptions options = new LoaderOptions();
|
||||
options.setAllowDuplicateKeys(false);
|
||||
return new Yaml(options);
|
||||
LoaderOptions loaderOptions = new LoaderOptions();
|
||||
loaderOptions.setAllowDuplicateKeys(false);
|
||||
|
||||
if (!this.supportedTypes.isEmpty()) {
|
||||
return new Yaml(new FilteringConstructor(), new Representer(),
|
||||
new DumperOptions(), loaderOptions);
|
||||
}
|
||||
return new Yaml(loaderOptions);
|
||||
}
|
||||
|
||||
private boolean process(MatchCallback callback, Yaml yaml, Resource resource) {
|
||||
@@ -388,4 +428,20 @@ public abstract class YamlProcessor {
|
||||
FIRST_FOUND
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link Constructor} that supports filtering of unsupported types.
|
||||
* <p>If an unsupported type is encountered in a YAML document, an
|
||||
* {@link IllegalStateException} will be thrown from {@link #getClassForName}.
|
||||
*/
|
||||
private class FilteringConstructor extends Constructor {
|
||||
|
||||
@Override
|
||||
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
|
||||
Assert.state(YamlProcessor.this.supportedTypes.contains(name),
|
||||
() -> "Unsupported type encountered in YAML document: " + name);
|
||||
return super.getClassForName(name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+45
-31
@@ -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.
|
||||
@@ -182,10 +182,12 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMetaClass(MetaClass metaClass) {
|
||||
this.metaClass = metaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaClass getMetaClass() {
|
||||
return this.metaClass;
|
||||
}
|
||||
@@ -216,6 +218,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* @return the number of bean definitions found
|
||||
* @throws BeanDefinitionStoreException in case of loading or parsing errors
|
||||
*/
|
||||
@Override
|
||||
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
|
||||
return loadBeanDefinitions(new EncodedResource(resource));
|
||||
}
|
||||
@@ -240,10 +243,11 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
logger.trace("Loading Groovy bean definitions from " + encodedResource);
|
||||
}
|
||||
|
||||
Closure beans = new Closure(this) {
|
||||
@SuppressWarnings("serial")
|
||||
Closure<Object> beans = new Closure<Object>(this) {
|
||||
@Override
|
||||
public Object call(Object[] args) {
|
||||
invokeBeanDefiningClosure((Closure) args[0]);
|
||||
public Object call(Object... args) {
|
||||
invokeBeanDefiningClosure((Closure<?>) args[0]);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -285,7 +289,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* @param closure the block or closure
|
||||
* @return this {@code GroovyBeanDefinitionReader} instance
|
||||
*/
|
||||
public GroovyBeanDefinitionReader beans(Closure closure) {
|
||||
public GroovyBeanDefinitionReader beans(Closure<?> closure) {
|
||||
return invokeBeanDefiningClosure(closure);
|
||||
}
|
||||
|
||||
@@ -309,25 +313,22 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
public AbstractBeanDefinition bean(Class<?> type, Object...args) {
|
||||
GroovyBeanDefinitionWrapper current = this.currentBeanDefinition;
|
||||
try {
|
||||
Closure callable = null;
|
||||
Collection constructorArgs = null;
|
||||
Closure<?> callable = null;
|
||||
Collection<Object> constructorArgs = null;
|
||||
if (!ObjectUtils.isEmpty(args)) {
|
||||
int index = args.length;
|
||||
Object lastArg = args[index - 1];
|
||||
if (lastArg instanceof Closure) {
|
||||
callable = (Closure) lastArg;
|
||||
if (lastArg instanceof Closure<?>) {
|
||||
callable = (Closure<?>) lastArg;
|
||||
index--;
|
||||
}
|
||||
if (index > -1) {
|
||||
constructorArgs = resolveConstructorArguments(args, 0, index);
|
||||
}
|
||||
constructorArgs = resolveConstructorArguments(args, 0, index);
|
||||
}
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(null, type, constructorArgs);
|
||||
if (callable != null) {
|
||||
callable.call(this.currentBeanDefinition);
|
||||
}
|
||||
return this.currentBeanDefinition.getBeanDefinition();
|
||||
|
||||
}
|
||||
finally {
|
||||
this.currentBeanDefinition = current;
|
||||
@@ -373,10 +374,11 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* This method overrides method invocation to create beans for each method name that
|
||||
* takes a class argument.
|
||||
*/
|
||||
@Override
|
||||
public Object invokeMethod(String name, Object arg) {
|
||||
Object[] args = (Object[])arg;
|
||||
if ("beans".equals(name) && args.length == 1 && args[0] instanceof Closure) {
|
||||
return beans((Closure) args[0]);
|
||||
return beans((Closure<?>) args[0]);
|
||||
}
|
||||
else if ("ref".equals(name)) {
|
||||
String refName;
|
||||
@@ -429,10 +431,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
private void finalizeDeferredProperties() {
|
||||
for (DeferredProperty dp : this.deferredProperties.values()) {
|
||||
if (dp.value instanceof List) {
|
||||
dp.value = manageListIfNecessary((List) dp.value);
|
||||
dp.value = manageListIfNecessary((List<?>) dp.value);
|
||||
}
|
||||
else if (dp.value instanceof Map) {
|
||||
dp.value = manageMapIfNecessary((Map) dp.value);
|
||||
dp.value = manageMapIfNecessary((Map<?, ?>) dp.value);
|
||||
}
|
||||
dp.apply();
|
||||
}
|
||||
@@ -444,7 +446,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* @param callable the closure argument
|
||||
* @return this {@code GroovyBeanDefinitionReader} instance
|
||||
*/
|
||||
protected GroovyBeanDefinitionReader invokeBeanDefiningClosure(Closure callable) {
|
||||
protected GroovyBeanDefinitionReader invokeBeanDefiningClosure(Closure<?> callable) {
|
||||
callable.setDelegate(this);
|
||||
callable.call();
|
||||
finalizeDeferredProperties();
|
||||
@@ -483,9 +485,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
else if (args[0] instanceof Map) {
|
||||
// named constructor arguments
|
||||
if (args.length > 1 && args[1] instanceof Class) {
|
||||
List constructorArgs = resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class)args[1], constructorArgs);
|
||||
Map namedArgs = (Map)args[0];
|
||||
List<Object> constructorArgs =
|
||||
resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class<?>) args[1], constructorArgs);
|
||||
Map<?, ?> namedArgs = (Map<?, ?>) args[0];
|
||||
for (Object o : namedArgs.keySet()) {
|
||||
String propName = (String) o;
|
||||
setProperty(propName, namedArgs.get(propName));
|
||||
@@ -494,8 +497,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
// factory method syntax
|
||||
else {
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName);
|
||||
//First arg is the map containing factoryBean : factoryMethod
|
||||
Map.Entry factoryBeanEntry = (Map.Entry) ((Map) args[0]).entrySet().iterator().next();
|
||||
// First arg is the map containing factoryBean : factoryMethod
|
||||
Map.Entry<?, ?> factoryBeanEntry = ((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);
|
||||
@@ -519,12 +522,13 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
this.currentBeanDefinition.getBeanDefinition().setAbstract(true);
|
||||
}
|
||||
else {
|
||||
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length);
|
||||
List<Object> constructorArgs =
|
||||
resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length);
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
|
||||
}
|
||||
|
||||
if (hasClosureArgument) {
|
||||
Closure callable = (Closure) args[args.length - 1];
|
||||
Closure<?> callable = (Closure<?>) args[args.length - 1];
|
||||
callable.setDelegate(this);
|
||||
callable.setResolveStrategy(Closure.DELEGATE_FIRST);
|
||||
callable.call(this.currentBeanDefinition);
|
||||
@@ -544,10 +548,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
constructorArgs[i] = constructorArgs[i].toString();
|
||||
}
|
||||
else if (constructorArgs[i] instanceof List) {
|
||||
constructorArgs[i] = manageListIfNecessary((List) constructorArgs[i]);
|
||||
constructorArgs[i] = manageListIfNecessary((List<?>) constructorArgs[i]);
|
||||
}
|
||||
else if (constructorArgs[i] instanceof Map){
|
||||
constructorArgs[i] = manageMapIfNecessary((Map) constructorArgs[i]);
|
||||
constructorArgs[i] = manageMapIfNecessary((Map<?, ?>) constructorArgs[i]);
|
||||
}
|
||||
}
|
||||
return Arrays.asList(constructorArgs);
|
||||
@@ -601,6 +605,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* This method overrides property setting in the scope of the {@code GroovyBeanDefinitionReader}
|
||||
* to set properties on the current bean definition.
|
||||
*/
|
||||
@Override
|
||||
public void setProperty(String name, Object value) {
|
||||
if (this.currentBeanDefinition != null) {
|
||||
applyPropertyToBeanDefinition(name, value);
|
||||
@@ -617,7 +622,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
else if (value instanceof Closure) {
|
||||
GroovyBeanDefinitionWrapper current = this.currentBeanDefinition;
|
||||
try {
|
||||
Closure callable = (Closure) value;
|
||||
Closure<?> callable = (Closure<?>) value;
|
||||
Class<?> parameterType = callable.getParameterTypes()[0];
|
||||
if (Object.class == parameterType) {
|
||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper("");
|
||||
@@ -647,6 +652,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
* properties from the {@code GroovyBeanDefinitionReader} itself
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
Binding binding = getBinding();
|
||||
if (binding != null && binding.hasVariable(name)) {
|
||||
@@ -690,8 +696,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) {
|
||||
@@ -749,10 +755,12 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
this.metaClass = InvokerHelper.getMetaClass(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaClass getMetaClass() {
|
||||
return this.metaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String property) {
|
||||
if (property.equals("beanName")) {
|
||||
return getBeanName();
|
||||
@@ -769,14 +777,17 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeMethod(String name, Object args) {
|
||||
return this.metaClass.invokeMethod(this, name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetaClass(MetaClass metaClass) {
|
||||
this.metaClass = metaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String property, Object newValue) {
|
||||
if (!addDeferredProperty(property, newValue)) {
|
||||
this.beanDefinition.getBeanDefinition().getPropertyValues().add(property, newValue);
|
||||
@@ -785,7 +796,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 {
|
||||
@@ -799,18 +810,21 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
this.propertyValue = propertyValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void leftShift(Object value) {
|
||||
InvokerHelper.invokeMethod(this.propertyValue, "leftShift", value);
|
||||
updateDeferredProperties(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public boolean add(Object value) {
|
||||
boolean retVal = (Boolean) InvokerHelper.invokeMethod(this.propertyValue, "add", value);
|
||||
updateDeferredProperties(value);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public boolean addAll(Collection values) {
|
||||
@SuppressWarnings("unused")
|
||||
public boolean addAll(Collection<?> values) {
|
||||
boolean retVal = (Boolean) InvokerHelper.invokeMethod(this.propertyValue, "addAll", values);
|
||||
for (Object value : values) {
|
||||
updateDeferredProperties(value);
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -196,7 +196,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
// constructorArgs
|
||||
else if (CONSTRUCTOR_ARGS.equals(property) && newValue instanceof List) {
|
||||
ConstructorArgumentValues cav = new ConstructorArgumentValues();
|
||||
List args = (List) newValue;
|
||||
List<?> args = (List<?>) newValue;
|
||||
for (Object arg : args) {
|
||||
cav.addGenericArgumentValue(arg);
|
||||
}
|
||||
|
||||
+30
-39
@@ -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.
|
||||
@@ -309,7 +309,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);
|
||||
@@ -329,7 +329,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
bd = new RootBeanDefinition(mbd);
|
||||
}
|
||||
if (!bd.isPrototype()) {
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
@@ -347,28 +347,27 @@ 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
|
||||
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
|
||||
}
|
||||
else {
|
||||
Object bean;
|
||||
final BeanFactory parent = this;
|
||||
if (System.getSecurityManager() != null) {
|
||||
bean = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
|
||||
getInstantiationStrategy().instantiate(bd, null, parent),
|
||||
bean = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(bd, null, this),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
bean = getInstantiationStrategy().instantiate(bd, null, parent);
|
||||
bean = getInstantiationStrategy().instantiate(bd, null, this);
|
||||
}
|
||||
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
|
||||
return bean;
|
||||
@@ -385,7 +384,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);
|
||||
@@ -543,7 +542,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @see #instantiateUsingFactoryMethod
|
||||
* @see #autowireConstructor
|
||||
*/
|
||||
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
|
||||
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
// Instantiate the bean.
|
||||
@@ -554,7 +553,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (instanceWrapper == null) {
|
||||
instanceWrapper = createBeanInstance(beanName, mbd, args);
|
||||
}
|
||||
final Object bean = instanceWrapper.getWrappedInstance();
|
||||
Object bean = instanceWrapper.getWrappedInstance();
|
||||
Class<?> beanType = instanceWrapper.getWrappedClass();
|
||||
if (beanType != NullBean.class) {
|
||||
mbd.resolvedTargetType = beanType;
|
||||
@@ -623,7 +622,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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -645,7 +644,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
@Nullable
|
||||
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()) {
|
||||
@@ -900,7 +898,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @return the common {@code FactoryBean} object type, or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) {
|
||||
private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, String factoryMethodName) {
|
||||
|
||||
/**
|
||||
* Holder used to keep a reference to a {@code Class} value.
|
||||
@@ -1282,17 +1280,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
|
||||
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
|
||||
try {
|
||||
Object beanInstance;
|
||||
final BeanFactory parent = this;
|
||||
if (System.getSecurityManager() != null) {
|
||||
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
|
||||
getInstantiationStrategy().instantiate(mbd, beanName, parent),
|
||||
beanInstance = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
|
||||
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
|
||||
initBeanWrapper(bw);
|
||||
@@ -1364,34 +1361,28 @@ 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;
|
||||
}
|
||||
|
||||
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
|
||||
|
||||
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == 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() == 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() == AUTOWIRE_BY_TYPE) {
|
||||
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
|
||||
autowireByType(beanName, mbd, bw, newPvs);
|
||||
}
|
||||
pvs = newPvs;
|
||||
@@ -1495,7 +1486,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (Object.class != pd.getPropertyType()) {
|
||||
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
|
||||
// Do not allow eager init for type matching in case of a prioritized post-processor.
|
||||
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
|
||||
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
|
||||
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
|
||||
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
|
||||
if (autowiredArgument != null) {
|
||||
@@ -1754,7 +1745,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @see #invokeInitMethods
|
||||
* @see #applyBeanPostProcessorsAfterInitialization
|
||||
*/
|
||||
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
|
||||
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
@@ -1785,7 +1776,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return wrappedBean;
|
||||
}
|
||||
|
||||
private void invokeAwareMethods(final String beanName, final Object bean) {
|
||||
private void invokeAwareMethods(String beanName, Object bean) {
|
||||
if (bean instanceof Aware) {
|
||||
if (bean instanceof BeanNameAware) {
|
||||
((BeanNameAware) bean).setBeanName(beanName);
|
||||
@@ -1814,7 +1805,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @throws Throwable if thrown by init methods or by the invocation process
|
||||
* @see #invokeCustomInitMethod
|
||||
*/
|
||||
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
|
||||
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
|
||||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
@@ -1855,7 +1846,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* methods with arguments.
|
||||
* @see #invokeInitMethods
|
||||
*/
|
||||
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
|
||||
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
|
||||
throws Throwable {
|
||||
|
||||
String initMethodName = mbd.getInitMethodName();
|
||||
@@ -1890,8 +1881,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
methodToInvoke.invoke(bean), getAccessControlContext());
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> methodToInvoke.invoke(bean), getAccessControlContext());
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
InvocationTargetException ex = (InvocationTargetException) pae.getException();
|
||||
|
||||
+37
-29
@@ -898,16 +898,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() {
|
||||
@@ -934,8 +938,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;
|
||||
@@ -943,7 +951,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;
|
||||
@@ -1127,30 +1135,30 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
return false;
|
||||
}
|
||||
AbstractBeanDefinition that = (AbstractBeanDefinition) other;
|
||||
boolean rtn = ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName());
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.scope, that.scope);
|
||||
rtn = rtn &= this.abstractFlag == that.abstractFlag;
|
||||
rtn = rtn &= this.lazyInit == that.lazyInit;
|
||||
rtn = rtn &= this.autowireMode == that.autowireMode;
|
||||
rtn = rtn &= this.dependencyCheck == that.dependencyCheck;
|
||||
rtn = rtn &= Arrays.equals(this.dependsOn, that.dependsOn);
|
||||
rtn = rtn &= this.autowireCandidate == that.autowireCandidate;
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers);
|
||||
rtn = rtn &= this.primary == that.primary;
|
||||
rtn = rtn &= this.nonPublicAccessAllowed == that.nonPublicAccessAllowed;
|
||||
rtn = rtn &= this.lenientConstructorResolution == that.lenientConstructorResolution;
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues);
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues);
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides);
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName);
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName);
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName);
|
||||
rtn = rtn &= this.enforceInitMethod == that.enforceInitMethod;
|
||||
rtn = rtn &= ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName);
|
||||
rtn = rtn &= this.enforceDestroyMethod == that.enforceDestroyMethod;
|
||||
rtn = rtn &= this.synthetic == that.synthetic;
|
||||
rtn = rtn &= this.role == that.role;
|
||||
return rtn && super.equals(other);
|
||||
return (ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()) &&
|
||||
ObjectUtils.nullSafeEquals(this.scope, that.scope) &&
|
||||
this.abstractFlag == that.abstractFlag &&
|
||||
this.lazyInit == that.lazyInit &&
|
||||
this.autowireMode == that.autowireMode &&
|
||||
this.dependencyCheck == that.dependencyCheck &&
|
||||
Arrays.equals(this.dependsOn, that.dependsOn) &&
|
||||
this.autowireCandidate == that.autowireCandidate &&
|
||||
ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers) &&
|
||||
this.primary == that.primary &&
|
||||
this.nonPublicAccessAllowed == that.nonPublicAccessAllowed &&
|
||||
this.lenientConstructorResolution == that.lenientConstructorResolution &&
|
||||
ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues) &&
|
||||
ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues) &&
|
||||
ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
|
||||
ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
|
||||
ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
|
||||
ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) &&
|
||||
this.enforceInitMethod == that.enforceInitMethod &&
|
||||
ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) &&
|
||||
this.enforceDestroyMethod == that.enforceDestroyMethod &&
|
||||
this.synthetic == that.synthetic &&
|
||||
this.role == that.role &&
|
||||
super.equals(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+23
-17
@@ -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.
|
||||
@@ -147,7 +147,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
/** String resolvers to apply e.g. to annotation attribute values. */
|
||||
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();
|
||||
|
||||
/** BeanPostProcessors to apply in createBean. */
|
||||
/** BeanPostProcessors to apply. */
|
||||
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
|
||||
|
||||
/** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */
|
||||
@@ -236,10 +236,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
|
||||
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
|
||||
protected <T> T doGetBean(
|
||||
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
|
||||
throws BeansException {
|
||||
|
||||
final String beanName = transformedBeanName(name);
|
||||
String beanName = transformedBeanName(name);
|
||||
Object bean;
|
||||
|
||||
// Eagerly check singleton cache for manually registered singletons.
|
||||
@@ -291,7 +292,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
}
|
||||
|
||||
try {
|
||||
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
checkMergedBeanDefinition(mbd, beanName, args);
|
||||
|
||||
// Guarantee initialization of beans that the current bean depends on.
|
||||
@@ -345,7 +346,10 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
else {
|
||||
String scopeName = mbd.getScope();
|
||||
final Scope scope = this.scopes.get(scopeName);
|
||||
if (!StringUtils.hasLength(scopeName)) {
|
||||
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
|
||||
}
|
||||
Scope scope = this.scopes.get(scopeName);
|
||||
if (scope == null) {
|
||||
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
|
||||
}
|
||||
@@ -469,10 +473,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return false;
|
||||
}
|
||||
if (isFactoryBean(beanName, mbd)) {
|
||||
final FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
|
||||
((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || !fb.isSingleton()),
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) () ->
|
||||
((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
|
||||
!fb.isSingleton()),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
@@ -887,7 +893,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
|
||||
*/
|
||||
@@ -1283,7 +1289,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1298,7 +1304,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.
|
||||
@@ -1369,7 +1375,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @throws CannotLoadBeanClassException if we failed to load the class
|
||||
*/
|
||||
@Nullable
|
||||
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
|
||||
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
|
||||
throws CannotLoadBeanClassException {
|
||||
|
||||
try {
|
||||
@@ -1377,8 +1383,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return mbd.getBeanClass();
|
||||
}
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
|
||||
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
|
||||
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return doResolveBeanClass(mbd, typesToMatch);
|
||||
@@ -1634,7 +1640,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* Get the object for the given bean instance, either the bean
|
||||
* instance itself or its created object in case of a FactoryBean.
|
||||
* @param beanInstance the shared bean instance
|
||||
* @param name name that may include factory dereference prefix
|
||||
* @param name the name that may include factory dereference prefix
|
||||
* @param beanName the canonical bean name
|
||||
* @param mbd the merged bean definition
|
||||
* @return the object to expose for the bean
|
||||
|
||||
+9
@@ -302,6 +302,15 @@ public final class BeanDefinitionBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this bean is a primary autowire candidate.
|
||||
* @since 5.1.11
|
||||
*/
|
||||
public BeanDefinitionBuilder setPrimary(boolean primary) {
|
||||
this.beanDefinition.setPrimary(primary);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role of this definition.
|
||||
*/
|
||||
|
||||
+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.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see AbstractBeanDefinition#applyDefaults
|
||||
*/
|
||||
public class BeanDefinitionDefaults {
|
||||
|
||||
@@ -45,6 +46,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;
|
||||
@@ -66,6 +68,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;
|
||||
@@ -82,6 +85,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;
|
||||
@@ -96,6 +100,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(@Nullable String initMethodName) {
|
||||
this.initMethodName = (StringUtils.hasText(initMethodName) ? initMethodName : null);
|
||||
@@ -111,6 +119,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(@Nullable String destroyMethodName) {
|
||||
this.destroyMethodName = (StringUtils.hasText(destroyMethodName) ? destroyMethodName : null);
|
||||
|
||||
+57
-34
@@ -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.
|
||||
@@ -162,6 +162,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
/** Map of bean definition objects, keyed by bean name. */
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
|
||||
|
||||
/** Map from bean name to merged BeanDefinitionHolder. */
|
||||
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);
|
||||
|
||||
/** Map of singleton and non-singleton bean names, keyed by dependency type. */
|
||||
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
|
||||
|
||||
@@ -289,12 +292,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
* when deciding whether a bean definition should be considered as a
|
||||
* candidate for autowiring.
|
||||
*/
|
||||
public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
|
||||
public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
|
||||
Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
|
||||
if (autowireCandidateResolver instanceof BeanFactoryAware) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(DefaultListableBeanFactory.this);
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
@@ -500,8 +503,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
// Check all bean definitions.
|
||||
for (String beanName : this.beanDefinitionNames) {
|
||||
// Only consider bean as eligible if the bean name
|
||||
// is not defined as alias for some other bean.
|
||||
// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
|
||||
if (!isAlias(beanName)) {
|
||||
try {
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
@@ -548,6 +550,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
onSuppressedException(ex);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Bean definition got removed while we were iterating -> ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,8 +603,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
|
||||
throws BeansException {
|
||||
public <T> Map<String, T> getBeansOfType(
|
||||
@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {
|
||||
|
||||
String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
|
||||
Map<String, T> result = new LinkedHashMap<>(beanNames.length);
|
||||
@@ -636,8 +641,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String beanName : this.beanDefinitionNames) {
|
||||
BeanDefinition beanDefinition = getBeanDefinition(beanName);
|
||||
if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
|
||||
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
|
||||
if (bd != null && !bd.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
|
||||
result.add(beanName);
|
||||
}
|
||||
}
|
||||
@@ -717,12 +722,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
* @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm
|
||||
* @return whether the bean should be considered as autowire candidate
|
||||
*/
|
||||
protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
|
||||
protected boolean isAutowireCandidate(
|
||||
String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
if (containsBeanDefinition(beanDefinitionName)) {
|
||||
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
|
||||
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
if (containsBeanDefinition(bdName)) {
|
||||
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
|
||||
}
|
||||
else if (containsSingleton(beanName)) {
|
||||
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
|
||||
@@ -754,13 +760,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
|
||||
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
|
||||
|
||||
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
resolveBeanClass(mbd, beanDefinitionName);
|
||||
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
resolveBeanClass(mbd, bdName);
|
||||
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
|
||||
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
|
||||
}
|
||||
return resolver.isAutowireCandidate(
|
||||
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
|
||||
BeanDefinitionHolder holder = (beanName.equals(bdName) ?
|
||||
this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
|
||||
key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
|
||||
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
|
||||
return resolver.isAutowireCandidate(holder, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -783,9 +792,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearMergedBeanDefinition(String beanName) {
|
||||
super.clearMergedBeanDefinition(beanName);
|
||||
this.mergedBeanDefinitionHolders.remove(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMetadataCache() {
|
||||
super.clearMetadataCache();
|
||||
this.mergedBeanDefinitionHolders.clear();
|
||||
clearByTypeCache();
|
||||
}
|
||||
|
||||
@@ -827,11 +843,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (isFactoryBean(beanName)) {
|
||||
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (bean instanceof FactoryBean) {
|
||||
final FactoryBean<?> factory = (FactoryBean<?>) bean;
|
||||
FactoryBean<?> factory = (FactoryBean<?>) bean;
|
||||
boolean isEagerInit;
|
||||
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
|
||||
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
|
||||
((SmartFactoryBean<?>) factory)::isEagerInit,
|
||||
isEagerInit = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
@@ -853,7 +869,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
for (String beanName : beanNames) {
|
||||
Object singletonInstance = getSingleton(beanName);
|
||||
if (singletonInstance instanceof SmartInitializingSingleton) {
|
||||
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
|
||||
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
smartSingleton.afterSingletonsInstantiated();
|
||||
@@ -942,6 +958,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (existingDefinition != null || containsSingleton(beanName)) {
|
||||
resetBeanDefinition(beanName);
|
||||
}
|
||||
else if (isConfigurationFrozen()) {
|
||||
clearByTypeCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1004,8 +1023,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
for (String bdName : this.beanDefinitionNames) {
|
||||
if (!beanName.equals(bdName)) {
|
||||
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
|
||||
// Ensure bd is non-null due to potential concurrent modification
|
||||
// of the beanDefinitionMap.
|
||||
// Ensure bd is non-null due to potential concurrent modification of beanDefinitionMap.
|
||||
if (bd != null && beanName.equals(bd.getParentName())) {
|
||||
resetBeanDefinition(bdName);
|
||||
}
|
||||
@@ -1275,7 +1293,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
|
||||
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
|
||||
|
||||
final Class<?> type = descriptor.getDependencyType();
|
||||
Class<?> type = descriptor.getDependencyType();
|
||||
|
||||
if (descriptor instanceof StreamDependencyDescriptor) {
|
||||
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
|
||||
@@ -1668,18 +1686,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
*/
|
||||
private void checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor descriptor) {
|
||||
for (String beanName : this.beanDefinitionNames) {
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
Class<?> targetType = mbd.getTargetType();
|
||||
if (targetType != null && type.isAssignableFrom(targetType) &&
|
||||
isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) {
|
||||
// Probably a proxy interfering with target type match -> throw meaningful exception.
|
||||
Object beanInstance = getSingleton(beanName, false);
|
||||
Class<?> beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class ?
|
||||
beanInstance.getClass() : predictBeanType(beanName, mbd));
|
||||
if (beanType != null && !type.isAssignableFrom(beanType)) {
|
||||
throw new BeanNotOfRequiredTypeException(beanName, type, beanType);
|
||||
try {
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
Class<?> targetType = mbd.getTargetType();
|
||||
if (targetType != null && type.isAssignableFrom(targetType) &&
|
||||
isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) {
|
||||
// Probably a proxy interfering with target type match -> throw meaningful exception.
|
||||
Object beanInstance = getSingleton(beanName, false);
|
||||
Class<?> beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class ?
|
||||
beanInstance.getClass() : predictBeanType(beanName, mbd));
|
||||
if (beanType != null && !type.isAssignableFrom(beanType)) {
|
||||
throw new BeanNotOfRequiredTypeException(beanName, type, beanType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Bean definition got removed while we were iterating -> ignore.
|
||||
}
|
||||
}
|
||||
|
||||
BeanFactory parent = getParentBeanFactory();
|
||||
|
||||
+13
-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.
|
||||
@@ -70,6 +70,10 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
|
||||
|
||||
/** Maximum number of suppressed exceptions to preserve. */
|
||||
private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
|
||||
|
||||
|
||||
/** Cache of singleton objects: bean name to bean instance. */
|
||||
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
|
||||
|
||||
@@ -90,7 +94,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
private final Set<String> inCreationCheckExclusions =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
/** List of suppressed Exceptions, available for associating related causes. */
|
||||
/** Collection of suppressed Exceptions, available for associating related causes. */
|
||||
@Nullable
|
||||
private Set<Exception> suppressedExceptions;
|
||||
|
||||
@@ -253,13 +257,17 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an Exception that happened to get suppressed during the creation of a
|
||||
* Register an exception that happened to get suppressed during the creation of a
|
||||
* singleton bean instance, e.g. a temporary circular reference resolution problem.
|
||||
* <p>The default implementation preserves any given exception in this registry's
|
||||
* collection of suppressed exceptions, up to a limit of 100 exceptions, adding
|
||||
* them as related causes to an eventual top-level {@link BeanCreationException}.
|
||||
* @param ex the Exception to register
|
||||
* @see BeanCreationException#getRelatedCauses()
|
||||
*/
|
||||
protected void onSuppressedException(Exception ex) {
|
||||
synchronized (this.singletonObjects) {
|
||||
if (this.suppressedExceptions != null) {
|
||||
if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) {
|
||||
this.suppressedExceptions.add(ex);
|
||||
}
|
||||
}
|
||||
@@ -612,6 +620,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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -311,9 +311,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* assuming a "force" parameter), else logging an error.
|
||||
*/
|
||||
private void invokeCustomDestroyMethod(final Method destroyMethod) {
|
||||
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
|
||||
final Object[] args = new Object[paramTypes.length];
|
||||
if (paramTypes.length == 1) {
|
||||
int paramCount = destroyMethod.getParameterCount();
|
||||
final Object[] args = new Object[paramCount];
|
||||
if (paramCount == 1) {
|
||||
args[0] = Boolean.TRUE;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
||||
+5
-7
@@ -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,11 +54,11 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
* or {@code null} if the type cannot be determined yet
|
||||
*/
|
||||
@Nullable
|
||||
protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
|
||||
protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Class<?>>)
|
||||
factoryBean::getObjectType, getAccessControlContext());
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<Class<?>>) factoryBean::getObjectType, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return factoryBean.getObjectType();
|
||||
@@ -153,9 +153,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
* @throws BeanCreationException if FactoryBean object creation failed
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
|
||||
throws BeanCreationException {
|
||||
|
||||
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
|
||||
Object object;
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
|
||||
+6
-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.
|
||||
@@ -40,6 +40,11 @@ public class SimpleAutowireCandidateResolver implements AutowireCandidateResolve
|
||||
return descriptor.isRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasQualifier(DependencyDescriptor descriptor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getSuggestedValue(DependencyDescriptor descriptor) {
|
||||
|
||||
+4
-3
@@ -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.
|
||||
@@ -146,8 +146,9 @@ public class ArgumentConvertingMethodInvoker extends MethodInvoker {
|
||||
for (Method candidate : candidates) {
|
||||
if (candidate.getName().equals(targetMethod)) {
|
||||
// Check if the inspected method has the correct number of parameters.
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
if (paramTypes.length == argCount) {
|
||||
int parameterCount = candidate.getParameterCount();
|
||||
if (parameterCount == argCount) {
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
Object[] convertedArguments = new Object[argCount];
|
||||
boolean match = true;
|
||||
for (int j = 0; j < argCount && match; j++) {
|
||||
|
||||
+33
@@ -1399,6 +1399,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();
|
||||
|
||||
+56
-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.
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.yaml.snakeyaml.constructor.ConstructorException;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.scanner.ScannerException;
|
||||
|
||||
@@ -34,6 +37,7 @@ import static org.junit.Assert.*;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class YamlProcessorTests {
|
||||
|
||||
@@ -45,7 +49,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void arrayConvertedToIndexedBeanReference() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar: [1,2,3]".getBytes()));
|
||||
setYaml("foo: bar\nbar: [1,2,3]");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(4, properties.size());
|
||||
assertEquals("bar", properties.get("foo"));
|
||||
@@ -61,13 +65,13 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testStringResource() {
|
||||
this.processor.setResources(new ByteArrayResource("foo # a document that is a literal".getBytes()));
|
||||
setYaml("foo # a document that is a literal");
|
||||
this.processor.process((properties, map) -> assertEquals("foo", map.get("document")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadDocumentStart() {
|
||||
this.processor.setResources(new ByteArrayResource("foo # a document\nbar: baz".getBytes()));
|
||||
setYaml("foo # a document\nbar: baz");
|
||||
this.exception.expect(ParserException.class);
|
||||
this.exception.expectMessage("line 2, column 1");
|
||||
this.processor.process((properties, map) -> {});
|
||||
@@ -75,7 +79,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testBadResource() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\ncd\nspam:\n foo: baz".getBytes()));
|
||||
setYaml("foo: bar\ncd\nspam:\n foo: baz");
|
||||
this.exception.expect(ScannerException.class);
|
||||
this.exception.expectMessage("line 3, column 1");
|
||||
this.processor.process((properties, map) -> {});
|
||||
@@ -83,7 +87,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void mapConvertedToIndexedBeanReference() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar:\n spam: bucket".getBytes()));
|
||||
setYaml("foo: bar\nbar:\n spam: bucket");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bucket", properties.get("bar.spam"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -92,7 +96,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void integerKeyBehaves() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\n1: bar".getBytes()));
|
||||
setYaml("foo: bar\n1: bar");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bar", properties.get("[1]"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -101,7 +105,7 @@ public class YamlProcessorTests {
|
||||
|
||||
@Test
|
||||
public void integerDeepKeyBehaves() {
|
||||
this.processor.setResources(new ByteArrayResource("foo:\n 1: bar".getBytes()));
|
||||
setYaml("foo:\n 1: bar");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bar", properties.get("foo[1]"));
|
||||
assertEquals(1, properties.size());
|
||||
@@ -111,7 +115,7 @@ public class YamlProcessorTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void flattenedMapIsSameAsPropertiesButOrdered() {
|
||||
this.processor.setResources(new ByteArrayResource("foo: bar\nbar:\n spam: bucket".getBytes()));
|
||||
setYaml("foo: bar\nbar:\n spam: bucket");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals("bucket", properties.get("bar.spam"));
|
||||
assertEquals(2, properties.size());
|
||||
@@ -124,4 +128,47 @@ public class YamlProcessorTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypeSupportedByDefault() throws Exception {
|
||||
URL url = new URL("https://localhost:9000/");
|
||||
setYaml("value: !!java.net.URL [\"" + url + "\"]");
|
||||
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(1, properties.size());
|
||||
assertEquals(1, map.size());
|
||||
assertEquals(url, properties.get("value"));
|
||||
assertEquals(url, map.get("value"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypesSupportedDueToExplicitConfiguration() throws Exception {
|
||||
this.processor.setSupportedTypes(URL.class, String.class);
|
||||
|
||||
URL url = new URL("https://localhost:9000/");
|
||||
setYaml("value: !!java.net.URL [!!java.lang.String [\"" + url + "\"]]");
|
||||
|
||||
this.processor.process((properties, map) -> {
|
||||
assertEquals(1, properties.size());
|
||||
assertEquals(1, map.size());
|
||||
assertEquals(url, properties.get("value"));
|
||||
assertEquals(url, map.get("value"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTypeNotSupportedDueToExplicitConfiguration() {
|
||||
this.processor.setSupportedTypes(List.class);
|
||||
|
||||
setYaml("value: !!java.net.URL [\"https://localhost:9000/\"]");
|
||||
|
||||
this.exception.expect(ConstructorException.class);
|
||||
this.exception.expectMessage("Unsupported type encountered in YAML document: java.net.URL");
|
||||
this.processor.process((properties, map) -> {});
|
||||
}
|
||||
|
||||
private void setYaml(String yaml) {
|
||||
this.processor.setResources(new ByteArrayResource(yaml.getBytes()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ dependencies {
|
||||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
testCompile(project(":spring-context"))
|
||||
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
testCompile("org.hibernate:hibernate-validator:6.0.17.Final")
|
||||
testCompile("org.hibernate:hibernate-validator:6.0.20.Final")
|
||||
testCompile("javax.annotation:javax.annotation-api:1.3.2")
|
||||
testRuntime("org.ehcache:jcache:1.0.1")
|
||||
testRuntime("org.ehcache:ehcache:3.4.0")
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.3
|
||||
* @see CaffeineCacheManager
|
||||
*/
|
||||
public class CaffeineCache extends AbstractValueAdaptingCache {
|
||||
|
||||
|
||||
+2
-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.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see EhCacheCacheManager
|
||||
*/
|
||||
public class EhCacheCache implements Cache {
|
||||
|
||||
@@ -95,7 +96,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-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.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see EhCacheCache
|
||||
*/
|
||||
public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.2
|
||||
* @see JCacheCacheManager
|
||||
*/
|
||||
public class JCacheCache extends AbstractValueAdaptingCache {
|
||||
|
||||
|
||||
Vendored
+2
-1
@@ -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.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.2
|
||||
* @see JCacheCache
|
||||
*/
|
||||
public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||
|
||||
|
||||
+2
-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.
|
||||
@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
|
||||
* @see JCacheConfigurer
|
||||
*/
|
||||
@Configuration
|
||||
public class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
|
||||
public abstract class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
@Nullable
|
||||
protected Supplier<CacheResolver> exceptionCacheResolver;
|
||||
|
||||
+1
@@ -88,6 +88,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
||||
return this.cacheOperationSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
getCacheOperationSource();
|
||||
|
||||
|
||||
+9
-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.
|
||||
@@ -58,13 +58,13 @@ 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
|
||||
* @deprecated as of 5.1, in favor of EE 7's
|
||||
* @deprecated as of 5.1, in favor of the EE 7/8 based
|
||||
* {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -121,6 +121,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) {
|
||||
|
||||
+3
-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.
|
||||
@@ -110,7 +110,7 @@ public class LocalDataSourceJobStore extends JobStoreCMT {
|
||||
public void shutdown() {
|
||||
// Do nothing - a Spring-managed DataSource has its own lifecycle.
|
||||
}
|
||||
/* Quartz 2.2 initialize method */
|
||||
@Override
|
||||
public void initialize() {
|
||||
// Do nothing - a Spring-managed DataSource has its own lifecycle.
|
||||
}
|
||||
@@ -138,7 +138,7 @@ public class LocalDataSourceJobStore extends JobStoreCMT {
|
||||
public void shutdown() {
|
||||
// Do nothing - a Spring-managed DataSource has its own lifecycle.
|
||||
}
|
||||
/* Quartz 2.2 initialize method */
|
||||
@Override
|
||||
public void initialize() {
|
||||
// Do nothing - a Spring-managed DataSource has its own lifecycle.
|
||||
}
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -82,6 +82,7 @@ public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> Class<? extends T> loadClass(String name, Class<T> clazz) throws ClassNotFoundException {
|
||||
return (Class<? extends T>) loadClass(name);
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ dependencies {
|
||||
optional("javax.xml.ws:jaxws-api:2.3.1")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy:${groovyVersion}")
|
||||
optional("org.beanshell:bsh:2.0b5")
|
||||
optional("joda-time:joda-time:2.10.4")
|
||||
optional("org.apache-extras.beanshell:bsh:2.0b6")
|
||||
optional("joda-time:joda-time:2.10.5")
|
||||
optional("org.hibernate:hibernate-validator:5.4.3.Final")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
testCompile("org.codehaus.groovy:groovy-jsr223:${groovyVersion}")
|
||||
testCompile("org.codehaus.groovy:groovy-test:${groovyVersion}")
|
||||
testCompile("org.codehaus.groovy:groovy-xml:${groovyVersion}")
|
||||
testCompile("org.apache.commons:commons-pool2:2.6.0")
|
||||
testCompile("org.apache.commons:commons-pool2:2.6.2")
|
||||
testCompile("javax.inject:javax.inject-tck:1")
|
||||
testCompile("org.awaitility:awaitility:3.1.3")
|
||||
testCompile("org.awaitility:awaitility:3.1.6")
|
||||
testRuntime("javax.xml.bind:jaxb-api:2.3.1")
|
||||
testRuntime("org.glassfish:javax.el:3.0.1-b08")
|
||||
testRuntime("org.javamoney:moneta:1.3")
|
||||
|
||||
+2
-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.
|
||||
@@ -191,7 +191,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
|
||||
}
|
||||
|
||||
private Object serializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
serialization.serialize(storeValue, out);
|
||||
return out.toByteArray();
|
||||
|
||||
Vendored
+2
-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.
|
||||
@@ -190,9 +190,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
|
||||
*/
|
||||
protected Cache createConcurrentMapCache(String name) {
|
||||
SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
|
||||
return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),
|
||||
isAllowNullValues(), actualSerialization);
|
||||
|
||||
return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256), isAllowNullValues(), actualSerialization);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+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.
|
||||
@@ -52,6 +52,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;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
import org.springframework.util.function.SupplierUtils;
|
||||
@@ -381,9 +382,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
|
||||
}
|
||||
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 {
|
||||
|
||||
+3
-1
@@ -32,7 +32,9 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class SimpleKey implements Serializable {
|
||||
|
||||
/** An empty key. */
|
||||
/**
|
||||
* An empty key.
|
||||
*/
|
||||
public static final SimpleKey EMPTY = new SimpleKey();
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.util.Assert;
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.3.4
|
||||
* @see NoOpCacheManager
|
||||
*/
|
||||
public class NoOpCache implements Cache {
|
||||
|
||||
|
||||
+2
-2
@@ -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,7 +37,7 @@ import org.springframework.lang.Nullable;
|
||||
* @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.
|
||||
@@ -148,11 +148,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-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.
|
||||
@@ -17,19 +17,21 @@
|
||||
package org.springframework.context;
|
||||
|
||||
/**
|
||||
* An extension of the {@link Lifecycle} interface for those objects that require to
|
||||
* be started upon ApplicationContext refresh and/or shutdown in a particular order.
|
||||
* The {@link #isAutoStartup()} return value indicates whether this object should
|
||||
* An extension of the {@link Lifecycle} interface for those objects that require
|
||||
* to be started upon {@code ApplicationContext} refresh and/or shutdown in a
|
||||
* particular order.
|
||||
*
|
||||
* <p>The {@link #isAutoStartup()} return value indicates whether this object should
|
||||
* be started at the time of a context refresh. The callback-accepting
|
||||
* {@link #stop(Runnable)} method is useful for objects that have an asynchronous
|
||||
* shutdown process. Any implementation of this interface <i>must</i> invoke the
|
||||
* callback's {@code run()} method upon shutdown completion to avoid unnecessary
|
||||
* delays in the overall ApplicationContext shutdown.
|
||||
* delays in the overall {@code ApplicationContext} shutdown.
|
||||
*
|
||||
* <p>This interface extends {@link Phased}, and the {@link #getPhase()} method's
|
||||
* return value indicates the phase within which this Lifecycle component should
|
||||
* be started and stopped. The startup process begins with the <i>lowest</i> phase
|
||||
* value and ends with the <i>highest</i> phase value ({@code Integer.MIN_VALUE}
|
||||
* return value indicates the phase within which this {@code Lifecycle} component
|
||||
* should be started and stopped. The startup process begins with the <i>lowest</i>
|
||||
* phase value and ends with the <i>highest</i> phase value ({@code Integer.MIN_VALUE}
|
||||
* is the lowest possible, and {@code Integer.MAX_VALUE} is the highest possible).
|
||||
* The shutdown process will apply the reverse order. Any components with the
|
||||
* same value will be arbitrarily ordered within the same phase.
|
||||
@@ -44,9 +46,11 @@ package org.springframework.context;
|
||||
*
|
||||
* <p>Any {@code Lifecycle} components within the context that do not also
|
||||
* implement {@code SmartLifecycle} will be treated as if they have a phase
|
||||
* value of 0. That way a {@code SmartLifecycle} implementation may start
|
||||
* before those {@code Lifecycle} components if it has a negative phase value,
|
||||
* or it may start after those components if it has a positive phase value.
|
||||
* value of {@code 0}. This allows a {@code SmartLifecycle} component to start
|
||||
* before those {@code Lifecycle} components if the {@code SmartLifecycle}
|
||||
* component has a negative phase value, or the {@code SmartLifecycle} component
|
||||
* may start after those {@code Lifecycle} components if the {@code SmartLifecycle}
|
||||
* component has a positive phase value.
|
||||
*
|
||||
* <p>Note that, due to the auto-startup support in {@code SmartLifecycle}, a
|
||||
* {@code SmartLifecycle} bean instance will usually get initialized on startup
|
||||
@@ -55,6 +59,7 @@ package org.springframework.context;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see LifecycleProcessor
|
||||
* @see ConfigurableApplicationContext
|
||||
@@ -63,9 +68,10 @@ public interface SmartLifecycle extends Lifecycle, Phased {
|
||||
|
||||
/**
|
||||
* The default phase for {@code SmartLifecycle}: {@code Integer.MAX_VALUE}.
|
||||
* <p>This is different from the common phase 0 associated with regular
|
||||
* <p>This is different from the common phase {@code 0} associated with regular
|
||||
* {@link Lifecycle} implementations, putting the typically auto-started
|
||||
* {@code SmartLifecycle} beans into a separate later shutdown phase.
|
||||
* {@code SmartLifecycle} beans into a later startup phase and an earlier
|
||||
* shutdown phase.
|
||||
* @since 5.1
|
||||
* @see #getPhase()
|
||||
* @see org.springframework.context.support.DefaultLifecycleProcessor#getPhase(Lifecycle)
|
||||
@@ -115,7 +121,8 @@ public interface SmartLifecycle extends Lifecycle, Phased {
|
||||
/**
|
||||
* Return the phase that this lifecycle object is supposed to run in.
|
||||
* <p>The default implementation returns {@link #DEFAULT_PHASE} in order to
|
||||
* let stop callbacks execute after regular {@code Lifecycle} implementations.
|
||||
* let {@code stop()} callbacks execute after regular {@code Lifecycle}
|
||||
* implementations.
|
||||
* @see #isAutoStartup()
|
||||
* @see #start()
|
||||
* @see #stop(Runnable)
|
||||
|
||||
+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 {
|
||||
|
||||
|
||||
+3
-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.
|
||||
@@ -29,7 +29,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.Lookup;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
@@ -386,8 +385,8 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
|
||||
for (String type : types) {
|
||||
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type);
|
||||
if (isCandidateComponent(metadataReader)) {
|
||||
AnnotatedGenericBeanDefinition sbd = new AnnotatedGenericBeanDefinition(
|
||||
metadataReader.getAnnotationMetadata());
|
||||
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
|
||||
sbd.setSource(metadataReader.getResource());
|
||||
if (isCandidateComponent(sbd)) {
|
||||
if (debugEnabled) {
|
||||
logger.debug("Using candidate component class from index: " + type);
|
||||
@@ -430,7 +429,6 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
|
||||
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
|
||||
if (isCandidateComponent(metadataReader)) {
|
||||
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
|
||||
sbd.setResource(resource);
|
||||
sbd.setSource(resource);
|
||||
if (isCandidateComponent(sbd)) {
|
||||
if (debugEnabled) {
|
||||
|
||||
+4
-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.
|
||||
@@ -344,9 +344,9 @@ 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>
|
||||
*
|
||||
|
||||
+2
-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.
|
||||
@@ -209,7 +209,6 @@ class ConfigurationClassBeanDefinitionReader {
|
||||
}
|
||||
|
||||
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
|
||||
beanDef.setResource(configClass.getResource());
|
||||
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
|
||||
|
||||
if (metadata.isStatic()) {
|
||||
@@ -381,6 +380,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||
public ConfigurationClassBeanDefinition(ConfigurationClass configClass, MethodMetadata beanMethodMetadata) {
|
||||
this.annotationMetadata = configClass.getMetadata();
|
||||
this.factoryMethodMetadata = beanMethodMetadata;
|
||||
setResource(configClass.getResource());
|
||||
setLenientConstructorResolution(false);
|
||||
}
|
||||
|
||||
|
||||
+5
-11
@@ -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.
|
||||
@@ -748,8 +748,7 @@ class ConfigurationClassParser {
|
||||
* @param importSelector the selector to handle
|
||||
*/
|
||||
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
|
||||
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(
|
||||
configClass, importSelector);
|
||||
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
|
||||
if (this.deferredImportSelectors == null) {
|
||||
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
|
||||
handler.register(holder);
|
||||
@@ -775,7 +774,6 @@ class ConfigurationClassParser {
|
||||
this.deferredImportSelectors = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -786,8 +784,7 @@ class ConfigurationClassParser {
|
||||
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
|
||||
|
||||
public void register(DeferredImportSelectorHolder deferredImport) {
|
||||
Class<? extends Group> group = deferredImport.getImportSelector()
|
||||
.getImportGroup();
|
||||
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
|
||||
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
|
||||
(group != null ? group : deferredImport),
|
||||
key -> new DeferredImportSelectorGrouping(createGroup(group)));
|
||||
@@ -799,8 +796,7 @@ class ConfigurationClassParser {
|
||||
public void processGroupImports() {
|
||||
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
|
||||
grouping.getImports().forEach(entry -> {
|
||||
ConfigurationClass configurationClass = this.configurationClasses.get(
|
||||
entry.getMetadata());
|
||||
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
|
||||
try {
|
||||
processImports(configurationClass, asSourceClass(configurationClass),
|
||||
asSourceClasses(entry.getImportClassName()), false);
|
||||
@@ -818,8 +814,7 @@ class ConfigurationClassParser {
|
||||
}
|
||||
|
||||
private Group createGroup(@Nullable Class<? extends Group> type) {
|
||||
Class<? extends Group> effectiveType = (type != null ? type
|
||||
: DefaultDeferredImportSelectorGroup.class);
|
||||
Class<? extends Group> effectiveType = (type != null ? type : DefaultDeferredImportSelectorGroup.class);
|
||||
Group group = BeanUtils.instantiateClass(effectiveType);
|
||||
ParserStrategyUtils.invokeAwareMethods(group,
|
||||
ConfigurationClassParser.this.environment,
|
||||
@@ -827,7 +822,6 @@ class ConfigurationClassParser {
|
||||
ConfigurationClassParser.this.registry);
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-7
@@ -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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@@ -53,6 +51,7 @@ public interface DeferredImportSelector extends ImportSelector {
|
||||
|
||||
/**
|
||||
* Interface used to group results from different import selectors.
|
||||
* @since 5.0
|
||||
*/
|
||||
interface Group {
|
||||
|
||||
@@ -100,7 +99,7 @@ public interface DeferredImportSelector extends ImportSelector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
@@ -108,13 +107,17 @@ public interface DeferredImportSelector extends ImportSelector {
|
||||
return false;
|
||||
}
|
||||
Entry entry = (Entry) other;
|
||||
return (Objects.equals(this.metadata, entry.metadata) &&
|
||||
Objects.equals(this.importClassName, entry.importClassName));
|
||||
return (this.metadata.equals(entry.metadata) && this.importClassName.equals(entry.importClassName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.metadata, this.importClassName);
|
||||
return (this.metadata.hashCode() * 31 + this.importClassName.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.importClassName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+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-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.
|
||||
@@ -42,6 +42,7 @@ import org.springframework.util.Assert;
|
||||
* @see ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoaderAware {
|
||||
|
||||
@Nullable
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -50,6 +50,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";
|
||||
|
||||
+6
-3
@@ -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.
|
||||
@@ -170,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()
|
||||
*/
|
||||
|
||||
+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.
|
||||
@@ -60,6 +60,7 @@ public class ScannedGenericBeanDefinition extends GenericBeanDefinition implemen
|
||||
Assert.notNull(metadataReader, "MetadataReader must not be null");
|
||||
this.metadata = metadataReader.getAnnotationMetadata();
|
||||
setBeanClassName(this.metadata.getClassName());
|
||||
setResource(metadataReader.getResource());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -53,6 +53,6 @@ public enum ScopedProxyMode {
|
||||
/**
|
||||
* Create a class-based proxy (uses CGLIB).
|
||||
*/
|
||||
TARGET_CLASS;
|
||||
TARGET_CLASS
|
||||
|
||||
}
|
||||
|
||||
+16
-14
@@ -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.
|
||||
@@ -57,6 +57,19 @@ public class CandidateComponentsIndex {
|
||||
this.index = parseIndex(content);
|
||||
}
|
||||
|
||||
private static MultiValueMap<String, Entry> parseIndex(List<Properties> content) {
|
||||
MultiValueMap<String, Entry> index = new LinkedMultiValueMap<>();
|
||||
for (Properties entry : content) {
|
||||
entry.forEach((type, values) -> {
|
||||
String[] stereotypes = ((String) values).split(",");
|
||||
for (String stereotype : stereotypes) {
|
||||
index.add(stereotype, new Entry((String) type));
|
||||
}
|
||||
});
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the candidate types that are associated with the specified stereotype.
|
||||
@@ -76,21 +89,11 @@ public class CandidateComponentsIndex {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private static MultiValueMap<String, Entry> parseIndex(List<Properties> content) {
|
||||
MultiValueMap<String, Entry> index = new LinkedMultiValueMap<>();
|
||||
for (Properties entry : content) {
|
||||
entry.forEach((type, values) -> {
|
||||
String[] stereotypes = ((String) values).split(",");
|
||||
for (String stereotype : stereotypes) {
|
||||
index.add(stereotype, new Entry((String) type));
|
||||
}
|
||||
});
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static class Entry {
|
||||
|
||||
private final String type;
|
||||
|
||||
private final String packageName;
|
||||
|
||||
Entry(String type) {
|
||||
@@ -106,7 +109,6 @@ public class CandidateComponentsIndex {
|
||||
return this.type.startsWith(basePackage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+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.
|
||||
@@ -79,6 +79,7 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -835,7 +836,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
// Publish early application events now that we finally have a multicaster...
|
||||
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
|
||||
this.earlyApplicationEvents = null;
|
||||
if (earlyEventsToProcess != null) {
|
||||
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
|
||||
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
|
||||
getApplicationEventMulticaster().multicastEvent(earlyEvent);
|
||||
}
|
||||
|
||||
+16
-26
@@ -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.
|
||||
@@ -72,10 +72,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||
|
||||
/** Bean factory for this context. */
|
||||
@Nullable
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
|
||||
/** Synchronization monitor for the internal BeanFactory. */
|
||||
private final Object beanFactoryMonitor = new Object();
|
||||
private volatile DefaultListableBeanFactory beanFactory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -131,9 +128,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);
|
||||
@@ -142,21 +137,19 @@ 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) {
|
||||
if (this.beanFactory != null) {
|
||||
this.beanFactory.setSerializationId(null);
|
||||
this.beanFactory = null;
|
||||
}
|
||||
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||
if (beanFactory != null) {
|
||||
beanFactory.setSerializationId(null);
|
||||
this.beanFactory = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,20 +158,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-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.
|
||||
@@ -160,8 +160,9 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
|
||||
/**
|
||||
* Set the number of seconds to cache loaded properties files.
|
||||
* <ul>
|
||||
* <li>Default is "-1", indicating to cache forever (just like
|
||||
* {@code java.util.ResourceBundle}).
|
||||
* <li>Default is "-1", indicating to cache forever (matching the default behavior
|
||||
* of {@code java.util.ResourceBundle}). Note that this constant follows Spring
|
||||
* conventions, not {@link java.util.ResourceBundle.Control#getTimeToLive}.
|
||||
* <li>A positive number will cache loaded properties files for the given
|
||||
* number of seconds. This is essentially the interval between refresh checks.
|
||||
* Note that a refresh attempt will first check the last-modified timestamp
|
||||
@@ -184,8 +185,9 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
|
||||
* Set the number of milliseconds to cache loaded properties files.
|
||||
* Note that it is common to set seconds instead: {@link #setCacheSeconds}.
|
||||
* <ul>
|
||||
* <li>Default is "-1", indicating to cache forever (just like
|
||||
* {@code java.util.ResourceBundle}).
|
||||
* <li>Default is "-1", indicating to cache forever (matching the default behavior
|
||||
* of {@code java.util.ResourceBundle}). Note that this constant follows Spring
|
||||
* conventions, not {@link java.util.ResourceBundle.Control#getTimeToLive}.
|
||||
* <li>A positive number will cache loaded properties files for the given
|
||||
* number of milliseconds. This is essentially the interval between refresh checks.
|
||||
* Note that a refresh attempt will first check the last-modified timestamp
|
||||
|
||||
+5
@@ -225,18 +225,22 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i
|
||||
|
||||
// Implementation of the GroovyObject interface
|
||||
|
||||
@Override
|
||||
public void setMetaClass(MetaClass metaClass) {
|
||||
this.metaClass = metaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaClass getMetaClass() {
|
||||
return this.metaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeMethod(String name, Object args) {
|
||||
return this.metaClass.invokeMethod(this, name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String property, Object newValue) {
|
||||
if (newValue instanceof BeanDefinition) {
|
||||
registerBeanDefinition(property, (BeanDefinition) newValue);
|
||||
@@ -246,6 +250,7 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getProperty(String property) {
|
||||
if (containsBean(property)) {
|
||||
|
||||
+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<>(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<>();
|
||||
Map<Locale, List<String>> existing = this.cachedFilenames.putIfAbsent(basename, localeMap);
|
||||
|
||||
+2
-1
@@ -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.
|
||||
@@ -43,6 +43,7 @@ public class StaticMessageSource extends AbstractMessageSource {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String resolveCodeWithoutArguments(String code, Locale locale) {
|
||||
return this.messages.get(code + '_' + locale.toString());
|
||||
}
|
||||
|
||||
+4
-3
@@ -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.
|
||||
@@ -49,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
@@ -61,14 +61,13 @@ public class DateFormatterRegistrar implements FormatterRegistrar {
|
||||
@Override
|
||||
public void registerFormatters(FormatterRegistry registry) {
|
||||
addDateConverters(registry);
|
||||
registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory());
|
||||
|
||||
// In order to retain back compatibility we only register Date/Calendar
|
||||
// types when a user defined formatter is specified (see SPR-10105)
|
||||
if (this.dateFormatter != null) {
|
||||
registry.addFormatter(this.dateFormatter);
|
||||
registry.addFormatterForFieldType(Calendar.class, this.dateFormatter);
|
||||
}
|
||||
registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-6
@@ -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.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.format.Formatter;
|
||||
* (which is commonly used for HTTP date header values), as of Spring 4.3.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andrei Nevedomskii
|
||||
* @since 4.0
|
||||
* @see java.time.Instant#parse
|
||||
* @see java.time.format.DateTimeFormatter#ISO_INSTANT
|
||||
@@ -40,14 +41,14 @@ public class InstantFormatter implements Formatter<Instant> {
|
||||
|
||||
@Override
|
||||
public Instant parse(String text, Locale locale) throws ParseException {
|
||||
if (text.length() > 0 && Character.isDigit(text.charAt(0))) {
|
||||
// assuming UTC instant a la "2007-12-03T10:15:30.00Z"
|
||||
return Instant.parse(text);
|
||||
}
|
||||
else {
|
||||
if (text.length() > 0 && Character.isAlphabetic(text.charAt(0))) {
|
||||
// assuming RFC-1123 value a la "Tue, 3 Jun 2008 11:05:30 GMT"
|
||||
return Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(text));
|
||||
}
|
||||
else {
|
||||
// assuming UTC instant a la "2007-12-03T10:15:30.00Z"
|
||||
return Instant.parse(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-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.
|
||||
@@ -207,7 +207,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,6 +231,7 @@ public class InterfaceBasedMBeanInfoAssembler extends AbstractConfigurableMBeanI
|
||||
for (Class<?> ifc : ifaces) {
|
||||
for (Method ifcMethod : ifc.getMethods()) {
|
||||
if (ifcMethod.getName().equals(method.getName()) &&
|
||||
ifcMethod.getParameterCount() == method.getParameterCount() &&
|
||||
Arrays.equals(ifcMethod.getParameterTypes(), method.getParameterTypes())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+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 = "";
|
||||
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -42,6 +42,6 @@ public enum RegistrationPolicy {
|
||||
* Registration should replace the affected MBean when attempting to register an MBean
|
||||
* under a name that already exists.
|
||||
*/
|
||||
REPLACE_EXISTING;
|
||||
REPLACE_EXISTING
|
||||
|
||||
}
|
||||
|
||||
+17
-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.
|
||||
@@ -254,7 +254,10 @@ public class ScheduledAnnotationBeanPostProcessor
|
||||
this.registrar.setTaskScheduler(resolveSchedulerBean(this.beanFactory, TaskScheduler.class, false));
|
||||
}
|
||||
catch (NoUniqueBeanDefinitionException ex) {
|
||||
logger.trace("Could not find unique TaskScheduler bean", ex);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Could not find unique TaskScheduler bean - attempting to resolve by name: " +
|
||||
ex.getMessage());
|
||||
}
|
||||
try {
|
||||
this.registrar.setTaskScheduler(resolveSchedulerBean(this.beanFactory, TaskScheduler.class, true));
|
||||
}
|
||||
@@ -269,13 +272,19 @@ public class ScheduledAnnotationBeanPostProcessor
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
logger.trace("Could not find default TaskScheduler bean", ex);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Could not find default TaskScheduler bean - attempting to find ScheduledExecutorService: " +
|
||||
ex.getMessage());
|
||||
}
|
||||
// Search for ScheduledExecutorService bean next...
|
||||
try {
|
||||
this.registrar.setScheduler(resolveSchedulerBean(this.beanFactory, ScheduledExecutorService.class, false));
|
||||
}
|
||||
catch (NoUniqueBeanDefinitionException ex2) {
|
||||
logger.trace("Could not find unique ScheduledExecutorService bean", ex2);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Could not find unique ScheduledExecutorService bean - attempting to resolve by name: " +
|
||||
ex2.getMessage());
|
||||
}
|
||||
try {
|
||||
this.registrar.setScheduler(resolveSchedulerBean(this.beanFactory, ScheduledExecutorService.class, true));
|
||||
}
|
||||
@@ -290,7 +299,10 @@ public class ScheduledAnnotationBeanPostProcessor
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex2) {
|
||||
logger.trace("Could not find default ScheduledExecutorService bean", ex2);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Could not find default ScheduledExecutorService bean - falling back to default: " +
|
||||
ex2.getMessage());
|
||||
}
|
||||
// Giving up -> falling back to default scheduler within the registrar...
|
||||
logger.info("No TaskScheduler/ScheduledExecutorService bean found for scheduled processing");
|
||||
}
|
||||
|
||||
+6
-1
@@ -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.
|
||||
@@ -130,6 +130,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-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.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -37,10 +37,11 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @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();
|
||||
|
||||
@Nullable
|
||||
private String jndiName = "java:comp/DefaultManagedExecutorService";
|
||||
|
||||
+8
-1
@@ -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.
|
||||
@@ -205,6 +205,13 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
|
||||
* 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.
|
||||
* See the {@code ThreadPoolExecutor#afterExecute} javadoc for an example
|
||||
* of how to access exceptions in such a {@code Future} case.
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setTaskDecorator(TaskDecorator taskDecorator) {
|
||||
|
||||
+9
-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.
|
||||
@@ -158,7 +158,14 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.groovyClassLoader = buildGroovyClassLoader(classLoader);
|
||||
if (classLoader instanceof GroovyClassLoader &&
|
||||
(this.compilerConfiguration == null ||
|
||||
((GroovyClassLoader) classLoader).hasCompatibleConfiguration(this.compilerConfiguration))) {
|
||||
this.groovyClassLoader = (GroovyClassLoader) classLoader;
|
||||
}
|
||||
else {
|
||||
this.groovyClassLoader = buildGroovyClassLoader(classLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-3
@@ -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.
|
||||
@@ -50,7 +50,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
* at the type level of the containing target class, applying to all public service methods
|
||||
* of that class. By default, JSR-303 will validate against its default group only.
|
||||
*
|
||||
* <p>As of Spring 5.0, this functionality requires a Bean Validation 1.1 provider.
|
||||
* <p>As of Spring 5.0, this functionality requires a Bean Validation 1.1+ provider.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
@@ -87,7 +87,6 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
// Avoid Validator invocation on FactoryBean.getObjectType/isSingleton
|
||||
if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
|
||||
|
||||
+2
-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.
|
||||
@@ -50,7 +50,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
* inline constraint annotations. Validation groups can be specified through {@code @Validated}
|
||||
* as well. By default, JSR-303 will validate against its default group only.
|
||||
*
|
||||
* <p>As of Spring 5.0, this functionality requires a Bean Validation 1.1 provider.
|
||||
* <p>As of Spring 5.0, this functionality requires a Bean Validation 1.1+ provider.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
|
||||
+3
-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.
|
||||
@@ -60,7 +60,7 @@ public class CacheReproTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void spr11124MultipleAnnotations() throws Exception {
|
||||
public void spr11124MultipleAnnotations() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11124Config.class);
|
||||
Spr11124Service bean = context.getBean(Spr11124Service.class);
|
||||
bean.single(2);
|
||||
@@ -71,7 +71,7 @@ public class CacheReproTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spr11249PrimitiveVarargs() throws Exception {
|
||||
public void spr11249PrimitiveVarargs() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11249Config.class);
|
||||
Spr11249Service bean = context.getBean(Spr11249Service.class);
|
||||
Object result = bean.doSomething("op", 2, 3);
|
||||
@@ -397,7 +397,6 @@ public class CacheReproTests {
|
||||
public TestBean insertItem(TestBean item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+5
-6
@@ -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.
|
||||
@@ -35,8 +35,7 @@ import static org.junit.Assert.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConcurrentMapCacheTests
|
||||
extends AbstractValueAdaptingCacheTests<ConcurrentMapCache> {
|
||||
public class ConcurrentMapCacheTests extends AbstractValueAdaptingCacheTests<ConcurrentMapCache> {
|
||||
|
||||
protected ConcurrentMap<Object, Object> nativeCache;
|
||||
|
||||
@@ -48,12 +47,11 @@ public class ConcurrentMapCacheTests
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setup() {
|
||||
this.nativeCache = new ConcurrentHashMap<>();
|
||||
this.cache = new ConcurrentMapCache(CACHE_NAME, this.nativeCache, true);
|
||||
this.nativeCacheNoNull = new ConcurrentHashMap<>();
|
||||
this.cacheNoNull = new ConcurrentMapCache(CACHE_NAME_NO_NULL,
|
||||
this.nativeCacheNoNull, false);
|
||||
this.cacheNoNull = new ConcurrentMapCache(CACHE_NAME_NO_NULL, this.nativeCacheNoNull, false);
|
||||
this.cache.clear();
|
||||
}
|
||||
|
||||
@@ -72,6 +70,7 @@ public class ConcurrentMapCacheTests
|
||||
return this.nativeCache;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIsStoreByReferenceByDefault() {
|
||||
assertFalse(this.cache.isStoreByValue());
|
||||
|
||||
Vendored
+2
-2
@@ -44,7 +44,7 @@ public class SimpleKeyGeneratorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleValue(){
|
||||
public void singleValue() {
|
||||
Object k1 = generateKey(new Object[] { "a" });
|
||||
Object k2 = generateKey(new Object[] { "a" });
|
||||
Object k3 = generateKey(new Object[] { "different" });
|
||||
@@ -56,7 +56,7 @@ public class SimpleKeyGeneratorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleValues() {
|
||||
public void multipleValues() {
|
||||
Object k1 = generateKey(new Object[] { "a", 1, "b" });
|
||||
Object k2 = generateKey(new Object[] { "a", 1, "b" });
|
||||
Object k3 = generateKey(new Object[] { "b", 1, "a" });
|
||||
|
||||
+61
-3
@@ -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.
|
||||
@@ -28,16 +28,18 @@ import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation2.NamedStubDao2;
|
||||
import org.springframework.context.index.CandidateComponentsTestClassLoader;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -102,10 +104,66 @@ public class ClassPathBeanDefinitionScannerTests {
|
||||
@Test
|
||||
public void testDoubleScan() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertEquals(12, beanCount);
|
||||
scanner.scan(BASE_PACKAGE);
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) {
|
||||
@Override
|
||||
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
|
||||
super.postProcessBeanDefinition(beanDefinition, beanName);
|
||||
beanDefinition.setAttribute("someDifference", "someValue");
|
||||
}
|
||||
};
|
||||
scanner2.scan(BASE_PACKAGE);
|
||||
|
||||
assertTrue(context.containsBean("serviceInvocationCounter"));
|
||||
assertTrue(context.containsBean("fooServiceImpl"));
|
||||
assertTrue(context.containsBean("stubFooDao"));
|
||||
assertTrue(context.containsBean("myNamedComponent"));
|
||||
assertTrue(context.containsBean("myNamedDao"));
|
||||
assertTrue(context.containsBean("thoreau"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithIndex() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.setClassLoader(CandidateComponentsTestClassLoader.index(
|
||||
ClassPathScanningCandidateComponentProviderTests.class.getClassLoader(),
|
||||
new ClassPathResource("spring.components", FooServiceImpl.class)));
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertEquals(12, beanCount);
|
||||
|
||||
assertTrue(context.containsBean("serviceInvocationCounter"));
|
||||
assertTrue(context.containsBean("fooServiceImpl"));
|
||||
assertTrue(context.containsBean("stubFooDao"));
|
||||
assertTrue(context.containsBean("myNamedComponent"));
|
||||
assertTrue(context.containsBean("myNamedDao"));
|
||||
assertTrue(context.containsBean("thoreau"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleScanWithIndex() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.setClassLoader(CandidateComponentsTestClassLoader.index(
|
||||
ClassPathScanningCandidateComponentProviderTests.class.getClassLoader(),
|
||||
new ClassPathResource("spring.components", FooServiceImpl.class)));
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertEquals(12, beanCount);
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) {
|
||||
@Override
|
||||
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
|
||||
super.postProcessBeanDefinition(beanDefinition, beanName);
|
||||
beanDefinition.setAttribute("someDifference", "someValue");
|
||||
}
|
||||
};
|
||||
scanner2.scan(BASE_PACKAGE);
|
||||
|
||||
assertTrue(context.containsBean("serviceInvocationCounter"));
|
||||
assertTrue(context.containsBean("fooServiceImpl"));
|
||||
|
||||
+41
-39
@@ -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.
|
||||
@@ -40,8 +40,8 @@ import example.scannable.sub.BarComponent;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.componentscan.gh24375.MyComponent;
|
||||
import org.springframework.context.index.CandidateComponentsTestClassLoader;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
@@ -80,18 +80,17 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
testDefault(provider, ScannedGenericBeanDefinition.class);
|
||||
testDefault(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultsWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testDefault(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testDefault(provider);
|
||||
}
|
||||
|
||||
private void testDefault(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testDefault(ClassPathScanningCandidateComponentProvider provider) {
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertTrue(containsBeanClass(candidates, DefaultNamedComponent.class));
|
||||
assertTrue(containsBeanClass(candidates, NamedComponent.class));
|
||||
@@ -101,7 +100,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
assertTrue(containsBeanClass(candidates, ServiceInvocationCounter.class));
|
||||
assertTrue(containsBeanClass(candidates, BarComponent.class));
|
||||
assertEquals(7, candidates.size());
|
||||
assertBeanDefinitionType(candidates, expectedBeanDefinitionType);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,22 +108,21 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
testAntStyle(provider, ScannedGenericBeanDefinition.class);
|
||||
testAntStyle(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void antStylePackageWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testAntStyle(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testAntStyle(provider);
|
||||
}
|
||||
|
||||
private void testAntStyle(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testAntStyle(ClassPathScanningCandidateComponentProvider provider) {
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE + ".**.sub");
|
||||
assertTrue(containsBeanClass(candidates, BarComponent.class));
|
||||
assertEquals(1, candidates.size());
|
||||
assertBeanDefinitionType(candidates, expectedBeanDefinitionType);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -151,7 +149,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
provider.resetFilters(true);
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertBeanDefinitionType(candidates, AnnotatedGenericBeanDefinition.class);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,20 +157,19 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
testCustomAnnotationTypeIncludeFilter(provider, ScannedGenericBeanDefinition.class);
|
||||
testCustomAnnotationTypeIncludeFilter(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAnnotationTypeIncludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomAnnotationTypeIncludeFilter(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testCustomAnnotationTypeIncludeFilter(provider);
|
||||
}
|
||||
|
||||
private void testCustomAnnotationTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testCustomAnnotationTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider) {
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
testDefault(provider, expectedBeanDefinitionType);
|
||||
testDefault(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -180,18 +177,17 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
testCustomAssignableTypeIncludeFilter(provider, ScannedGenericBeanDefinition.class);
|
||||
testCustomAssignableTypeIncludeFilter(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAssignableTypeIncludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomAssignableTypeIncludeFilter(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testCustomAssignableTypeIncludeFilter(provider);
|
||||
}
|
||||
|
||||
private void testCustomAssignableTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testCustomAssignableTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider) {
|
||||
provider.addIncludeFilter(new AssignableTypeFilter(FooService.class));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
// Interfaces/Abstract class are filtered out automatically.
|
||||
@@ -199,7 +195,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
assertTrue(containsBeanClass(candidates, FooServiceImpl.class));
|
||||
assertTrue(containsBeanClass(candidates, ScopedProxyTestBean.class));
|
||||
assertEquals(3, candidates.size());
|
||||
assertBeanDefinitionType(candidates, expectedBeanDefinitionType);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,18 +203,17 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
testCustomSupportedIncludeAndExcludeFilter(provider, ScannedGenericBeanDefinition.class);
|
||||
testCustomSupportedIncludeAndExcludeFilter(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSupportedIncludeAndExcludeFilterWithIndex() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
testCustomSupportedIncludeAndExcludeFilter(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testCustomSupportedIncludeAndExcludeFilter(provider);
|
||||
}
|
||||
|
||||
private void testCustomSupportedIncludeAndExcludeFilter(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testCustomSupportedIncludeAndExcludeFilter(ClassPathScanningCandidateComponentProvider provider) {
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
|
||||
provider.addExcludeFilter(new AnnotationTypeFilter(Service.class));
|
||||
provider.addExcludeFilter(new AnnotationTypeFilter(Repository.class));
|
||||
@@ -227,7 +222,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
assertTrue(containsBeanClass(candidates, ServiceInvocationCounter.class));
|
||||
assertTrue(containsBeanClass(candidates, BarComponent.class));
|
||||
assertEquals(3, candidates.size());
|
||||
assertBeanDefinitionType(candidates, expectedBeanDefinitionType);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,7 +235,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertTrue(containsBeanClass(candidates, DefaultNamedComponent.class));
|
||||
assertEquals(1, candidates.size());
|
||||
assertBeanDefinitionType(candidates, ScannedGenericBeanDefinition.class);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -251,7 +246,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertTrue(containsBeanClass(candidates, StubFooDao.class));
|
||||
assertEquals(1, candidates.size());
|
||||
assertBeanDefinitionType(candidates, ScannedGenericBeanDefinition.class);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -260,7 +255,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
provider.setResourceLoader(new DefaultResourceLoader(
|
||||
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
|
||||
provider.addExcludeFilter(new RegexPatternTypeFilter(Pattern.compile(TEST_BASE_PACKAGE + ".*Named.*")));
|
||||
testExclude(provider, ScannedGenericBeanDefinition.class);
|
||||
testExclude(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -268,18 +263,17 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
|
||||
provider.addExcludeFilter(new RegexPatternTypeFilter(Pattern.compile(TEST_BASE_PACKAGE + ".*Named.*")));
|
||||
testExclude(provider, AnnotatedGenericBeanDefinition.class);
|
||||
testExclude(provider);
|
||||
}
|
||||
|
||||
private void testExclude(ClassPathScanningCandidateComponentProvider provider,
|
||||
Class<? extends BeanDefinition> expectedBeanDefinitionType) {
|
||||
private void testExclude(ClassPathScanningCandidateComponentProvider provider) {
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
assertTrue(containsBeanClass(candidates, FooServiceImpl.class));
|
||||
assertTrue(containsBeanClass(candidates, StubFooDao.class));
|
||||
assertTrue(containsBeanClass(candidates, ServiceInvocationCounter.class));
|
||||
assertTrue(containsBeanClass(candidates, BarComponent.class));
|
||||
assertEquals(4, candidates.size());
|
||||
assertBeanDefinitionType(candidates, expectedBeanDefinitionType);
|
||||
assertBeanDefinitionType(candidates);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -307,7 +301,7 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAspectAnnotationOnly() throws Exception {
|
||||
public void testWithAspectAnnotationOnly() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
provider.addIncludeFilter(new AnnotationTypeFilter(Aspect.class));
|
||||
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
|
||||
@@ -501,6 +495,15 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gh24375() {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
Set<BeanDefinition> components = provider.findCandidateComponents(MyComponent.class.getPackage().getName());
|
||||
assertEquals(1, components.size());
|
||||
assertEquals(MyComponent.class.getName(), components.iterator().next().getBeanClassName());
|
||||
}
|
||||
|
||||
|
||||
private boolean containsBeanClass(Set<BeanDefinition> candidates, Class<?> beanClass) {
|
||||
for (BeanDefinition candidate : candidates) {
|
||||
if (beanClass.getName().equals(candidate.getBeanClassName())) {
|
||||
@@ -510,10 +513,9 @@ public class ClassPathScanningCandidateComponentProviderTests {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void assertBeanDefinitionType(Set<BeanDefinition> candidates,
|
||||
Class<? extends BeanDefinition> expectedType) {
|
||||
private void assertBeanDefinitionType(Set<BeanDefinition> candidates) {
|
||||
candidates.forEach(c -> {
|
||||
assertThat(c, is(instanceOf(expectedType)));
|
||||
assertThat(c, is(instanceOf(ScannedGenericBeanDefinition.class)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+3
-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.
|
||||
@@ -530,9 +530,10 @@ public class ImportSelectorTests {
|
||||
static Map<String, List<String>> allImports() {
|
||||
return TestImportGroup.imports.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap((entry) -> entry.getKey().getClassName(),
|
||||
.collect(Collectors.toMap(entry -> entry.getKey().getClassName(),
|
||||
Map.Entry::getValue));
|
||||
}
|
||||
|
||||
private final List<Entry> instanceImports = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation.componentscan.gh24375;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface A {
|
||||
|
||||
@AliasFor("value")
|
||||
B other() default @B;
|
||||
|
||||
@AliasFor("other")
|
||||
B value() default @B;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation.componentscan.gh24375;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface B {
|
||||
|
||||
String name() default "";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user