mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-19 19:29:03 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f07eed2b28 |
+7
-7
@@ -29,7 +29,7 @@ If you have a question, check StackOverflow using
|
||||
Find an existing discussion or start a new one if necessary.
|
||||
|
||||
If you suspect an issue, perform a search in the
|
||||
[Github issue tracker](https://github.com/spring-projects/spring-framework/issues), using a few different keywords.
|
||||
[JIRA issue tracker](https://jira.spring.io/browse/SPR), using a few different keywords.
|
||||
When you find related issues and discussions, prior or current, it helps you to learn and
|
||||
it helps us to make a decision.
|
||||
|
||||
@@ -42,7 +42,7 @@ Before you create a ticket, please take the time to [research first](#discuss).
|
||||
|
||||
If creating a ticket after a discussion on StackOverflow, please provide a self-sufficient description in the ticket, independent of the details on StackOverview. We understand this is extra work but the issue tracker is an important place of record for design discussions and decisions that can often be referenced long after the fix version, for example to revisit decisions, to understand the origin of a feature, and so on.
|
||||
|
||||
When ready create a ticket in the [Github issue tracker](https://github.com/spring-projects/spring-framework/issues).
|
||||
When ready create a ticket in the [JIRA issue tracker](https://jira.spring.io/browse/SPR).
|
||||
|
||||
#### Ticket Lifecycle
|
||||
|
||||
@@ -66,7 +66,7 @@ automatically when you submit a pull request.
|
||||
|
||||
1. For all but the most trivial of contributions, please [create a ticket](#create-a-ticket).
|
||||
The purpose of the ticket is to understand and discuss the underlying issue or feature.
|
||||
We use the GitHub issue tracker as the preferred place of record for conversations and
|
||||
We use the JIRA issue tracker as the preferred place of record for conversations and
|
||||
conclusions. In that sense discussions directly under a PR are more implementation detail
|
||||
oriented and transient in nature.
|
||||
|
||||
@@ -75,7 +75,7 @@ oriented and transient in nature.
|
||||
Backports to prior versions will be considered on a case-by-case basis and reflected as
|
||||
the fix version in the issue tracker.
|
||||
|
||||
1. Use short branch names, preferably based on the GitHub issue (e.g. `22276`), or
|
||||
1. Use short branch names, preferably based on the JIRA issue (e.g. `SPR-1234`), or
|
||||
otherwise using succinct, lower-case, dash (-) delimited names, such as `fix-warnings`.
|
||||
|
||||
1. Choose the granularity of your commits consciously and squash commits that represent
|
||||
@@ -84,12 +84,12 @@ multiple edits or corrections of the same logical change. See
|
||||
for an overview of streamlining commit history.
|
||||
|
||||
1. Format commit messages using 55 characters for the subject line, 72 lines for the
|
||||
description, followed by the issue fixed, e.g. `Fixes #22276`.
|
||||
description, followed by related issues, e.g. `Issues: SPR-1234, SPR-1235`.
|
||||
See the
|
||||
[Commit Guidelines section of Pro Git](http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines)
|
||||
for best practices around commit messages and use `git log` to see some examples.
|
||||
|
||||
1. List the GitHub issue number in the PR description.
|
||||
1. List the JIRA issue number in the PR description.
|
||||
|
||||
If accepted, your contribution may be heavily modified as needed prior to merging.
|
||||
You will likely retain author attribution for your Git commits granted that the bulk of
|
||||
@@ -116,7 +116,7 @@ defines the source file coding standards we use along with some IDEA editor sett
|
||||
|
||||
The reference documentation is in the [src/docs/asciidoc](src/docs/asciidoc) directory and, in
|
||||
[Asciidoctor](http://asciidoctor.org/) format. For trivial changes, you may be able to browse,
|
||||
edit source files, and submit directly from GitHub.
|
||||
edit source files, and submit directly from Github.
|
||||
|
||||
When making changes locally, use `./gradlew asciidoctor` and then browse the result under
|
||||
`build/asciidoc/html5/index.html`.
|
||||
|
||||
@@ -1,30 +1,48 @@
|
||||
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework
|
||||
|
||||
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects is often referred to simply as "Spring".
|
||||
This is the home of the Spring Framework, the foundation for all
|
||||
[Spring projects](https://spring.io/projects). Together the Spring Framework and the family of Spring projects make up what we call "Spring".
|
||||
|
||||
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
|
||||
Spring provides everything you need beyond the Java language to create enterprise
|
||||
applications in a wide range of scenarios and architectures. Please read the
|
||||
[Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction)
|
||||
section in the reference for a more complete introduction.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc).
|
||||
By participating you are expected to uphold this code.
|
||||
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Access to Binaries
|
||||
|
||||
For access to artifacts or a distribution zip, see the [Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts) wiki page.
|
||||
For access to artifacts or a distribution zip, see the
|
||||
[Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts)
|
||||
wiki page.
|
||||
|
||||
## Documentation
|
||||
|
||||
The Spring Framework maintains reference documentation ([published](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
|
||||
[API reference](http://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
|
||||
The Spring Frameworks maintains reference documentation
|
||||
([published](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and
|
||||
[source](src/docs/asciidoc)),
|
||||
Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
|
||||
[API reference](http://docs.spring.io/spring-framework/docs/current/javadoc-api/).
|
||||
There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
|
||||
|
||||
## Build from Source
|
||||
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wikipedia page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
|
||||
wiki page and also [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
## Stay in Touch
|
||||
|
||||
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](http://spring.io/blog/), and releases are announced via our [news feed](http://spring.io/blog/category/news).
|
||||
Follow [@SpringCentral](https://twitter.com/springcentral),
|
||||
[@SpringFramework](https://twitter.com/springframework), and its
|
||||
[team members](https://twitter.com/springframework/lists/team/members) on Twitter.
|
||||
In-depth articles can be found at [The Spring Blog](http://spring.io/blog/),
|
||||
and releases are announced via our [news feed](http://spring.io/blog/category/news).
|
||||
|
||||
## License
|
||||
|
||||
The Spring Framework is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
The Spring Framework is released under version 2.0 of the
|
||||
[Apache License](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
||||
+24
-28
@@ -11,15 +11,15 @@ buildscript {
|
||||
// 3rd party plugin repositories can be configured in settings.gradle
|
||||
plugins {
|
||||
id "io.spring.dependency-management" version "1.0.5.RELEASE" apply false
|
||||
id "org.jetbrains.kotlin.jvm" version "1.2.71" apply false
|
||||
id "org.jetbrains.kotlin.jvm" version "1.2.70" apply false
|
||||
id "org.jetbrains.dokka" version "0.9.17"
|
||||
id "org.asciidoctor.convert" version "1.5.8"
|
||||
id "org.asciidoctor.convert" version "1.5.7"
|
||||
}
|
||||
|
||||
ext {
|
||||
linkHomepage = "https://projects.spring.io/spring-framework"
|
||||
linkCi = "https://build.spring.io/browse/SPR"
|
||||
linkIssue = "https://github.com/spring-projects/spring-framework/issues"
|
||||
linkIssue = "https://jira.spring.io/browse/SPR"
|
||||
linkScmUrl = "https://github.com/spring-projects/spring-framework"
|
||||
linkScmConnection = "scm:git:git://github.com/spring-projects/spring-framework.git"
|
||||
linkScmDevConnection = "scm:git:ssh://git@github.com:spring-projects/spring-framework.git"
|
||||
@@ -28,24 +28,24 @@ ext {
|
||||
!it.name.equals("spring-build-src") && !it.name.equals("spring-framework-bom")
|
||||
}
|
||||
|
||||
aspectjVersion = "1.9.2"
|
||||
aspectjVersion = "1.9.1"
|
||||
freemarkerVersion = "2.3.28"
|
||||
groovyVersion = "2.5.6"
|
||||
groovyVersion = "2.5.2"
|
||||
hsqldbVersion = "2.4.1"
|
||||
jackson2Version = "2.9.8"
|
||||
jettyVersion = "9.4.14.v20181114"
|
||||
junit5Version = "5.3.2"
|
||||
kotlinVersion = "1.2.71"
|
||||
log4jVersion = "2.11.2"
|
||||
nettyVersion = "4.1.33.Final"
|
||||
reactorVersion = "Californium-SR5"
|
||||
jackson2Version = "2.9.7"
|
||||
jettyVersion = "9.4.12.v20180830"
|
||||
junit5Version = "5.3.1"
|
||||
kotlinVersion = "1.2.70"
|
||||
log4jVersion = "2.11.1"
|
||||
nettyVersion = "4.1.29.Final"
|
||||
reactorVersion = "Californium-RELEASE"
|
||||
rxjavaVersion = "1.3.8"
|
||||
rxjavaAdapterVersion = "1.2.1"
|
||||
rxjava2Version = "2.2.6"
|
||||
rxjava2Version = "2.2.2"
|
||||
slf4jVersion = "1.7.25" // spring-jcl + consistent 3rd party deps
|
||||
tiles3Version = "3.0.8"
|
||||
tomcatVersion = "9.0.16"
|
||||
undertowVersion = "2.0.17.Final"
|
||||
tomcatVersion = "9.0.12"
|
||||
undertowVersion = "2.0.13.Final"
|
||||
|
||||
gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
withoutJclOverSlf4J = {
|
||||
@@ -101,13 +101,13 @@ configure(allprojects) { project ->
|
||||
"-Xlint:-deprecation", "-Xlint:-unchecked"]
|
||||
|
||||
compileJava {
|
||||
sourceCompatibility = 1.8 // can be switched to 11 for testing
|
||||
sourceCompatibility = 1.8 // can be switched to 10 for testing
|
||||
targetCompatibility = 1.8
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
compileTestJava {
|
||||
sourceCompatibility = 1.8 // can be switched to 11 for testing
|
||||
sourceCompatibility = 1.8 // can be switched to 10 for testing
|
||||
targetCompatibility = 1.8
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs += "-parameters"
|
||||
@@ -132,7 +132,6 @@ configure(allprojects) { project ->
|
||||
test {
|
||||
systemProperty("java.awt.headless", "true")
|
||||
systemProperty("testGroups", project.properties.get("testGroups"))
|
||||
systemProperty("io.netty.leakDetection.level", "paranoid")
|
||||
scanForTestClasses = false
|
||||
include(["**/*Tests.class", "**/*Test.class"])
|
||||
// Since we set scanForTestClasses to false, we need to filter out inner
|
||||
@@ -143,20 +142,19 @@ configure(allprojects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.17"
|
||||
toolVersion = "8.10.1"
|
||||
configDir = rootProject.file("src/checkstyle")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
maven { url "https://repo.spring.io/snapshot" } // Reactor
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile("junit:junit:4.12") {
|
||||
exclude group: "org.hamcrest", module: "hamcrest-core"
|
||||
}
|
||||
testCompile("org.mockito:mockito-core:2.24.0") {
|
||||
testCompile("org.mockito:mockito-core:2.22.0") {
|
||||
exclude group: "org.hamcrest", module: "hamcrest-core"
|
||||
}
|
||||
testCompile("com.nhaarman:mockito-kotlin:1.6.0") {
|
||||
@@ -187,12 +185,10 @@ configure(allprojects) { project ->
|
||||
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"http://ehcache.org/apidocs/2.10.4",
|
||||
"http://quartz-scheduler.org/api/2.2.1/",
|
||||
"http://fasterxml.github.io/jackson-core/javadoc/2.9/",
|
||||
"http://fasterxml.github.io/jackson-databind/javadoc/2.9/",
|
||||
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.9/",
|
||||
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
|
||||
"https://junit.org/junit4/javadoc/4.12/",
|
||||
"https://junit.org/junit5/docs/${junit5Version}/api/"
|
||||
"http://fasterxml.github.io/jackson-core/javadoc/2.8/",
|
||||
"http://fasterxml.github.io/jackson-databind/javadoc/2.8/",
|
||||
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.8/",
|
||||
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
@@ -280,7 +276,7 @@ configure(rootProject) {
|
||||
testCompile("javax.servlet:javax.servlet-api:3.1.0")
|
||||
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
testCompile("org.hibernate:hibernate-core:5.1.17.Final")
|
||||
testCompile("org.hibernate:hibernate-core:5.1.16.Final")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=5.1.5.RELEASE
|
||||
version=5.1.0.RELEASE
|
||||
|
||||
@@ -52,8 +52,8 @@ def customizePom(pom, gradleProject) {
|
||||
}
|
||||
}
|
||||
issueManagement {
|
||||
system = "GitHub"
|
||||
url = "https://github.com/spring-projects/spring-framework/issues"
|
||||
system = "Jira"
|
||||
url = "https://jira.springsource.org/browse/SPR"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.aopalliance.intercept;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* Description of an invocation to a constructor, given to an
|
||||
* Description of an invocation to a constuctor, given to an
|
||||
* interceptor upon constructor-call.
|
||||
*
|
||||
* <p>A constructor invocation is a joinpoint and can be intercepted
|
||||
|
||||
@@ -32,7 +32,7 @@ public interface MethodInvocation extends Invocation {
|
||||
|
||||
/**
|
||||
* Get the method being called.
|
||||
* <p>This method is a friendly implementation of the
|
||||
* <p>This method is a frienly implementation of the
|
||||
* {@link Joinpoint#getStaticPart()} method (same result).
|
||||
* @return the method being called
|
||||
*/
|
||||
|
||||
@@ -63,7 +63,7 @@ import org.springframework.util.StringUtils;
|
||||
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
|
||||
|
||||
/**
|
||||
* Key used in ReflectiveMethodInvocation userAttributes map for the current joinpoint.
|
||||
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
|
||||
*/
|
||||
protected static final String JOIN_POINT_KEY = JoinPoint.class.getName();
|
||||
|
||||
|
||||
+9
-1
@@ -272,7 +272,15 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AmbiguousBindingException | IllegalArgumentException ex) {
|
||||
catch (AmbiguousBindingException ambigEx) {
|
||||
if (this.raiseExceptions) {
|
||||
throw ambigEx;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (this.raiseExceptions) {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
@@ -723,20 +723,17 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
|
||||
|
||||
@Nullable
|
||||
private final MethodProxy methodProxy;
|
||||
|
||||
private final boolean publicMethod;
|
||||
|
||||
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
|
||||
Object[] arguments, @Nullable Class<?> targetClass,
|
||||
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
|
||||
// Only use method proxy for public methods not derived from java.lang.Object
|
||||
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
|
||||
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
|
||||
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
|
||||
methodProxy : null);
|
||||
this.methodProxy = methodProxy;
|
||||
this.publicMethod = Modifier.isPublic(method.getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -745,7 +742,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.methodProxy != null) {
|
||||
if (this.publicMethod && getMethod().getDeclaringClass() != Object.class) {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
else {
|
||||
@@ -798,7 +795,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* <dt>For advised methods:</dt>
|
||||
* <dd>If the target is static and the advice chain is frozen then a
|
||||
* FixedChainStaticTargetInterceptor specific to the method is used to
|
||||
* invoke the advice chain. Otherwise a DynamicAdvisedInterceptor is
|
||||
* invoke the advice chain. Otherwise a DyanmicAdvisedInterceptor is
|
||||
* used.</dd>
|
||||
* <dt>For non-advised methods:</dt>
|
||||
* <dd>Where it can be determined that the method will not return {@code this}
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -133,7 +133,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
|
||||
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
|
||||
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
|
||||
|
||||
@@ -236,7 +236,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
this.earlyProxyReferences.put(cacheKey, bean);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
}
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
|
||||
@@ -295,7 +297,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
|
||||
if (bean != null) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
|
||||
/**
|
||||
* The {@code $[targetClassName]} placeholder.
|
||||
* Replaced with the fully-qualified name of the {@code Class}
|
||||
* Replaced with the fully-qualifed name of the {@code Class}
|
||||
* of the method invocation target.
|
||||
*/
|
||||
public static final String PLACEHOLDER_TARGET_CLASS_NAME = "$[targetClassName]";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -77,7 +77,8 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this if it's possible to filter out some candidate classes.
|
||||
* Subclasses can override this if it's possible to filter out
|
||||
* some candidate classes.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
|
||||
+5
-5
@@ -758,7 +758,7 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
@Around(value="setAge(age)",argNames="age")
|
||||
// @ArgNames({"age"}) // AMC needs more work here? ignoring pjp arg... ok??
|
||||
// argNames should be supported in Around as it is in Pointcut
|
||||
// argNames should be suported in Around as it is in Pointcut
|
||||
public void changeReturnType(ProceedingJoinPoint pjp, int age) throws Throwable {
|
||||
pjp.proceed(new Object[] {age*2});
|
||||
}
|
||||
@@ -884,12 +884,12 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
@Aspect
|
||||
abstract class AbstractMakeModifiable {
|
||||
|
||||
public interface MutableModifiable extends Modifiable {
|
||||
public interface MutableModifable extends Modifiable {
|
||||
|
||||
void markDirty();
|
||||
}
|
||||
|
||||
public static class ModifiableImpl implements MutableModifiable {
|
||||
public static class ModifiableImpl implements MutableModifable {
|
||||
|
||||
private boolean modified;
|
||||
|
||||
@@ -911,7 +911,7 @@ abstract class AbstractMakeModifiable {
|
||||
|
||||
@Before(value="execution(void set*(*)) && this(modifiable) && args(newValue)", argNames="modifiable,newValue")
|
||||
public void recordModificationIfSetterArgumentDiffersFromOldValue(
|
||||
JoinPoint jp, MutableModifiable mixin, Object newValue) {
|
||||
JoinPoint jp, MutableModifable mixin, Object newValue) {
|
||||
|
||||
/*
|
||||
* We use the mixin to check and, if necessary, change,
|
||||
@@ -972,7 +972,7 @@ class MakeITestBeanModifiable extends AbstractMakeModifiable {
|
||||
|
||||
@DeclareParents(value = "org.springframework.tests.sample.beans.ITestBean+",
|
||||
defaultImpl=ModifiableImpl.class)
|
||||
public static MutableModifiable mixin;
|
||||
public static MutableModifable mixin;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -157,7 +157,7 @@ public class DelegatingIntroductionInterceptorTests {
|
||||
TimeStamped ts = (TimeStamped) pf.getProxy();
|
||||
|
||||
assertThat(ts, instanceOf(TimeStamped.class));
|
||||
// Shouldn't proxy framework interfaces
|
||||
// Shoulnd't proxy framework interfaces
|
||||
assertTrue(!(ts instanceof MethodInterceptor));
|
||||
assertTrue(!(ts instanceof IntroductionInterceptor));
|
||||
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ public class HotSwappableTargetSourceTests {
|
||||
@Test
|
||||
public void testRejectsSwapToNull() {
|
||||
IllegalArgumentException ex = testRejectsSwapToInvalidValue(null);
|
||||
assertTrue(ex.getMessage().contains("null"));
|
||||
assertTrue(ex.getMessage().indexOf("null") != -1);
|
||||
}
|
||||
|
||||
// TODO test reject swap to wrong interface or class?
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -166,7 +166,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a lazily initialized CachedIntrospectionResults instance
|
||||
* Obtain a lazily initializted CachedIntrospectionResults instance
|
||||
* for the wrapped object.
|
||||
*/
|
||||
private CachedIntrospectionResults getCachedIntrospectionResults() {
|
||||
|
||||
@@ -314,7 +314,6 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getPropertyType() {
|
||||
if (this.propertyType == null) {
|
||||
try {
|
||||
@@ -426,7 +425,6 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getPropertyType() {
|
||||
if (this.propertyType == null) {
|
||||
try {
|
||||
@@ -462,7 +460,6 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getIndexedPropertyType() {
|
||||
if (this.indexedPropertyType == null) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.beans;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -94,27 +93,4 @@ public interface TypeConverter {
|
||||
<T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
|
||||
throws TypeMismatchException;
|
||||
|
||||
/**
|
||||
* Convert the value to the required type (if necessary from a String).
|
||||
* <p>Conversions from String to any type will typically use the {@code setAsText}
|
||||
* method of the PropertyEditor class, or a Spring Converter in a ConversionService.
|
||||
* @param value the value to convert
|
||||
* @param requiredType the type we must convert to
|
||||
* (or {@code null} if not known, for example in case of a collection element)
|
||||
* @param typeDescriptor the type descriptor to use (may be {@code null}))
|
||||
* @return the new value, possibly the result of type conversion
|
||||
* @throws TypeMismatchException if type conversion failed
|
||||
* @since 5.1.4
|
||||
* @see java.beans.PropertyEditor#setAsText(String)
|
||||
* @see java.beans.PropertyEditor#getValue()
|
||||
* @see org.springframework.core.convert.ConversionService
|
||||
* @see org.springframework.core.convert.converter.Converter
|
||||
*/
|
||||
@Nullable
|
||||
default <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
|
||||
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
|
||||
|
||||
throw new UnsupportedOperationException("TypeDescriptor resolution not supported");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
@@ -81,6 +82,42 @@ class TypeConverterDelegate {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the value to the specified required type.
|
||||
* @param newValue the proposed new value
|
||||
* @param requiredType the type we must convert to
|
||||
* (or {@code null} if not known, for example in case of a collection element)
|
||||
* @param methodParam the method parameter that is the target of the conversion
|
||||
* (may be {@code null})
|
||||
* @return the new value, possibly the result of type conversion
|
||||
* @throws IllegalArgumentException if type conversion failed
|
||||
*/
|
||||
@Nullable
|
||||
public <T> T convertIfNecessary(@Nullable Object newValue, @Nullable Class<T> requiredType,
|
||||
@Nullable MethodParameter methodParam) throws IllegalArgumentException {
|
||||
|
||||
return convertIfNecessary(null, null, newValue, requiredType,
|
||||
(methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value to the specified required type.
|
||||
* @param newValue the proposed new value
|
||||
* @param requiredType the type we must convert to
|
||||
* (or {@code null} if not known, for example in case of a collection element)
|
||||
* @param field the reflective field that is the target of the conversion
|
||||
* (may be {@code null})
|
||||
* @return the new value, possibly the result of type conversion
|
||||
* @throws IllegalArgumentException if type conversion failed
|
||||
*/
|
||||
@Nullable
|
||||
public <T> T convertIfNecessary(@Nullable Object newValue, @Nullable Class<T> requiredType, @Nullable Field field)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
return convertIfNecessary(null, null, newValue, requiredType,
|
||||
(field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value to the required type for the specified property.
|
||||
* @param propertyName name of the property
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ import java.lang.reflect.Field;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -42,16 +41,15 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType) throws TypeMismatchException {
|
||||
return convertIfNecessary(value, requiredType, TypeDescriptor.valueOf(requiredType));
|
||||
return doConvert(value, requiredType, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
|
||||
@Nullable MethodParameter methodParam) throws TypeMismatchException {
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable MethodParameter methodParam)
|
||||
throws TypeMismatchException {
|
||||
|
||||
return convertIfNecessary(value, requiredType,
|
||||
(methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType)));
|
||||
return doConvert(value, requiredType, methodParam, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,18 +57,21 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
|
||||
throws TypeMismatchException {
|
||||
|
||||
return convertIfNecessary(value, requiredType,
|
||||
(field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType)));
|
||||
return doConvert(value, requiredType, null, field);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
|
||||
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
|
||||
private <T> T doConvert(@Nullable Object value,@Nullable Class<T> requiredType,
|
||||
@Nullable MethodParameter methodParam, @Nullable Field field) throws TypeMismatchException {
|
||||
|
||||
Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(null, null, value, requiredType, typeDescriptor);
|
||||
if (field != null) {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
|
||||
}
|
||||
else {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
|
||||
}
|
||||
}
|
||||
catch (ConverterNotFoundException | IllegalStateException ex) {
|
||||
throw new ConversionNotSupportedException(value, requiredType, ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2011 the original author 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.beans.factory;
|
||||
|
||||
/**
|
||||
* A marker superinterface indicating that a bean is eligible to be notified by the
|
||||
* Spring container of a particular framework object through a callback-style method.
|
||||
* The actual method signature is determined by individual subinterfaces but should
|
||||
* typically consist of just one void-returning method that accepts a single argument.
|
||||
* Marker superinterface indicating that a bean is eligible to be
|
||||
* notified by the Spring container of a particular framework object
|
||||
* through a callback-style method. Actual method signature is
|
||||
* determined by individual subinterfaces, but should typically
|
||||
* consist of just one void-returning method that accepts a single
|
||||
* argument.
|
||||
*
|
||||
* <p>Note that merely implementing {@link Aware} provides no default functionality.
|
||||
* Rather, processing must be done explicitly, for example in a
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor}.
|
||||
* <p>Note that merely implementing {@link Aware} provides no default
|
||||
* functionality. Rather, processing must be done explicitly, for example
|
||||
* in a {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessor}.
|
||||
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
|
||||
* for an example of processing specific {@code *Aware} interface callbacks.
|
||||
* and {@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory}
|
||||
* for examples of processing {@code *Aware} interface callbacks.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface Aware {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -133,7 +133,8 @@ public interface BeanFactory {
|
||||
* Will ask the parent factory if the bean cannot be found in this factory instance.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean definition
|
||||
* with the specified name
|
||||
* @throws BeansException if the bean could not be obtained
|
||||
*/
|
||||
Object getBean(String name) throws BeansException;
|
||||
@@ -224,12 +225,12 @@ public interface BeanFactory {
|
||||
* Note that collection types are not supported here, in contrast to reflective
|
||||
* injection points. For programmatically retrieving a list of beans matching a
|
||||
* specific type, specify the actual bean type as an argument here and subsequently
|
||||
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
|
||||
* use {@link ObjectProvider#toList()} or its lazy streaming/iteration options.
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.1
|
||||
* @see ObjectProvider#iterator()
|
||||
* @see ObjectProvider#stream()
|
||||
* @see ObjectProvider#orderedStream()
|
||||
* @see ObjectProvider#iterator()
|
||||
* @see ObjectProvider#toList()
|
||||
*/
|
||||
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
|
||||
|
||||
|
||||
@@ -294,9 +294,9 @@ public abstract class BeanFactoryUtils {
|
||||
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
||||
Map<String, T> parentResult = beansOfTypeIncludingAncestors(
|
||||
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
|
||||
parentResult.forEach((beanName, beanInstance) -> {
|
||||
parentResult.forEach((beanName, beanType) -> {
|
||||
if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
result.put(beanName, beanInstance);
|
||||
result.put(beanName, beanType);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -343,9 +343,9 @@ public abstract class BeanFactoryUtils {
|
||||
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
||||
Map<String, T> parentResult = beansOfTypeIncludingAncestors(
|
||||
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
|
||||
parentResult.forEach((beanName, beanInstance) -> {
|
||||
parentResult.forEach((beanName, beanType) -> {
|
||||
if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
result.put(beanName, beanInstance);
|
||||
result.put(beanName, beanType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,8 +29,6 @@ import org.springframework.util.ObjectUtils;
|
||||
/**
|
||||
* A simple descriptor for an injection point, pointing to a method/constructor
|
||||
* parameter or a field. Exposed by {@link UnsatisfiedDependencyException}.
|
||||
* Also available as an argument for factory methods, reacting to the
|
||||
* requesting injection point for building a customized bean instance.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.3
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -244,9 +244,7 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
|
||||
/**
|
||||
* Find all names of beans whose {@code Class} has the supplied {@link Annotation}
|
||||
* type, without creating corresponding bean instances yet.
|
||||
* <p>Note that this method considers objects created by FactoryBeans, which means
|
||||
* that FactoryBeans will get initialized in order to determine their object type.
|
||||
* type, without creating any bean instances yet.
|
||||
* @param annotationType the type of annotation to look for
|
||||
* @return the names of all matching beans
|
||||
* @since 4.0
|
||||
@@ -256,8 +254,6 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
/**
|
||||
* Find all beans whose {@code Class} has the supplied {@link Annotation} type,
|
||||
* returning a Map of bean names with corresponding bean instances.
|
||||
* <p>Note that this method considers objects created by FactoryBeans, which means
|
||||
* that FactoryBeans will get initialized in order to determine their object type.
|
||||
* @param annotationType the type of annotation to look for
|
||||
* @return a Map with the matching beans, containing the bean names as
|
||||
* keys and the corresponding bean instances as values
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionExcepti
|
||||
public NoUniqueBeanDefinitionException(Class<?> type, Collection<String> beanNamesFound) {
|
||||
super(type, "expected single matching bean but found " + beanNamesFound.size() + ": " +
|
||||
StringUtils.collectionToCommaDelimitedString(beanNamesFound));
|
||||
this.numberOfBeansFound = beanNamesFound.size();
|
||||
this.numberOfBeansFound = beanNamesFound.size();
|
||||
this.beanNamesFound = beanNamesFound;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionExcepti
|
||||
public NoUniqueBeanDefinitionException(ResolvableType type, Collection<String> beanNamesFound) {
|
||||
super(type, "expected single matching bean but found " + beanNamesFound.size() + ": " +
|
||||
StringUtils.collectionToCommaDelimitedString(beanNamesFound));
|
||||
this.numberOfBeansFound = beanNamesFound.size();
|
||||
this.numberOfBeansFound = beanNamesFound.size();
|
||||
this.beanNamesFound = beanNamesFound;
|
||||
}
|
||||
|
||||
|
||||
+10
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,23 +46,24 @@ public class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the {@link BeanWiringInfo} for the given {@link Configurable} annotation.
|
||||
* Build the BeanWiringInfo for the given Configurable annotation.
|
||||
* @param beanInstance the bean instance
|
||||
* @param annotation the Configurable annotation found on the bean class
|
||||
* @return the resolved BeanWiringInfo
|
||||
*/
|
||||
protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) {
|
||||
if (!Autowire.NO.equals(annotation.autowire())) {
|
||||
// Autowiring by name or by type
|
||||
return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck());
|
||||
}
|
||||
else if (!"".equals(annotation.value())) {
|
||||
// Explicitly specified bean name for bean definition to take property values from
|
||||
return new BeanWiringInfo(annotation.value(), false);
|
||||
}
|
||||
else {
|
||||
// Default bean name for bean definition to take property values from
|
||||
return new BeanWiringInfo(getDefaultBeanName(beanInstance), true);
|
||||
if (!"".equals(annotation.value())) {
|
||||
// explicitly specified bean name
|
||||
return new BeanWiringInfo(annotation.value(), false);
|
||||
}
|
||||
else {
|
||||
// default bean name
|
||||
return new BeanWiringInfo(getDefaultBeanName(beanInstance), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,22 +23,15 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a constructor, field, setter method or config method as to be autowired by
|
||||
* Spring's dependency injection facilities. This is an alternative to the JSR-330
|
||||
* {@link javax.inject.Inject} annotation, adding required-vs-optional semantics.
|
||||
* Marks a constructor, field, setter method or config method as to be autowired
|
||||
* by Spring's dependency injection facilities.
|
||||
*
|
||||
* <p>Only one constructor (at max) of any given bean class may declare this annotation
|
||||
* with the 'required' parameter set to {@code true}, indicating <i>the</i> constructor
|
||||
* to autowire when used as a Spring bean. If multiple <i>non-required</i> constructors
|
||||
* declare the annotation, they will be considered as candidates for autowiring.
|
||||
* The constructor with the greatest number of dependencies that can be satisfied by
|
||||
* matching beans in the Spring container will be chosen. If none of the candidates
|
||||
* can be satisfied, then a primary/default constructor (if present) will be used.
|
||||
* If a class only declares a single constructor to begin with, it will always be used,
|
||||
* even if not annotated. An annotated constructor does not have to be public.
|
||||
* <p>Only one constructor (at max) of any given bean class may carry this annotation,
|
||||
* indicating the constructor to autowire when used as a Spring bean. Such a
|
||||
* constructor does not have to be public.
|
||||
*
|
||||
* <p>Fields are injected right after construction of a bean, before any config methods
|
||||
* are invoked. Such a config field does not have to be public.
|
||||
* <p>Fields are injected right after construction of a bean, before any config
|
||||
* methods are invoked. Such a config field does not have to be public.
|
||||
*
|
||||
* <p>Config methods may have an arbitrary name and any number of arguments; each of
|
||||
* those arguments will be autowired with a matching bean in the Spring container.
|
||||
|
||||
+23
-21
@@ -74,15 +74,15 @@ import org.springframework.util.StringUtils;
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
|
||||
* if available, as a direct alternative to Spring's own {@code @Autowired}.
|
||||
*
|
||||
* <p>Only one constructor (at max) of any given bean class may declare this annotation
|
||||
* with the 'required' parameter set to {@code true}, indicating <i>the</i> constructor
|
||||
* to autowire when used as a Spring bean. If multiple <i>non-required</i> constructors
|
||||
* declare the annotation, they will be considered as candidates for autowiring.
|
||||
* The constructor with the greatest number of dependencies that can be satisfied by
|
||||
* matching beans in the Spring container will be chosen. If none of the candidates
|
||||
* can be satisfied, then a primary/default constructor (if present) will be used.
|
||||
* If a class only declares a single constructor to begin with, it will always be used,
|
||||
* even if not annotated. An annotated constructor does not have to be public.
|
||||
* <p>Only one constructor (at max) of any given bean class may carry this
|
||||
* annotation with the 'required' parameter set to {@code true},
|
||||
* indicating <i>the</i> constructor to autowire when used as a Spring bean.
|
||||
* If multiple <i>non-required</i> constructors carry the annotation, they
|
||||
* will be considered as candidates for autowiring. The constructor with
|
||||
* the greatest number of dependencies that can be satisfied by matching
|
||||
* beans in the Spring container will be chosen. If none of the candidates
|
||||
* can be satisfied, then a default constructor (if present) will be used.
|
||||
* An annotated constructor does not have to be public.
|
||||
*
|
||||
* <p>Fields are injected right after construction of a bean, before any
|
||||
* config methods are invoked. Such a config field does not have to be public.
|
||||
@@ -161,11 +161,11 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
/**
|
||||
* Set the 'autowired' annotation type, to be used on constructors, fields,
|
||||
* setter methods and arbitrary config methods.
|
||||
* <p>The default autowired annotation type is the Spring-provided {@link Autowired}
|
||||
* annotation, as well as {@link Value}.
|
||||
* <p>The default autowired annotation type is the Spring-provided
|
||||
* {@link Autowired} annotation, as well as {@link Value}.
|
||||
* <p>This setter property exists so that developers can provide their own
|
||||
* (non-Spring-specific) annotation type to indicate that a member is supposed
|
||||
* to be autowired.
|
||||
* (non-Spring-specific) annotation type to indicate that a member is
|
||||
* supposed to be autowired.
|
||||
*/
|
||||
public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
|
||||
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
|
||||
@@ -176,11 +176,11 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
/**
|
||||
* Set the 'autowired' annotation types, to be used on constructors, fields,
|
||||
* setter methods and arbitrary config methods.
|
||||
* <p>The default autowired annotation type is the Spring-provided {@link Autowired}
|
||||
* annotation, as well as {@link Value}.
|
||||
* <p>The default autowired annotation type is the Spring-provided
|
||||
* {@link Autowired} annotation, as well as {@link Value}.
|
||||
* <p>This setter property exists so that developers can provide their own
|
||||
* (non-Spring-specific) annotation types to indicate that a member is supposed
|
||||
* to be autowired.
|
||||
* (non-Spring-specific) annotation types to indicate that a member is
|
||||
* supposed to be autowired.
|
||||
*/
|
||||
public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
|
||||
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
|
||||
@@ -189,7 +189,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of a parameter of the annotation that specifies whether it is required.
|
||||
* Set the name of a parameter of the annotation that specifies
|
||||
* whether it is required.
|
||||
* @see #setRequiredParameterValue(boolean)
|
||||
*/
|
||||
public void setRequiredParameterName(String requiredParameterName) {
|
||||
@@ -198,8 +199,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
/**
|
||||
* Set the boolean value that marks a dependency as required
|
||||
* <p>For example if using 'required=true' (the default), this value should be
|
||||
* {@code true}; but if using 'optional=false', this value should be {@code false}.
|
||||
* <p>For example if using 'required=true' (the default),
|
||||
* this value should be {@code true}; but if using
|
||||
* 'optional=false', this value should be {@code false}.
|
||||
* @see #setRequiredParameterName(String)
|
||||
*/
|
||||
public void setRequiredParameterValue(boolean requiredParameterValue) {
|
||||
@@ -707,7 +709,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
method.invoke(bean, arguments);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
catch (InvocationTargetException ex){
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
|
||||
+14
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,18 +17,16 @@
|
||||
package org.springframework.beans.factory.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
@@ -37,8 +35,8 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenience methods performing bean lookups related to Spring-specific annotations,
|
||||
* for example Spring's {@link Qualifier @Qualifier} annotation.
|
||||
* Convenience methods performing bean lookups related to annotations, for example
|
||||
* Spring's {@link Qualifier @Qualifier} annotation.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
@@ -47,52 +45,27 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class BeanFactoryAnnotationUtils {
|
||||
|
||||
/**
|
||||
* Retrieve all bean of type {@code T} from the given {@code BeanFactory} declaring a
|
||||
* qualifier (e.g. via {@code <qualifier>} or {@code @Qualifier}) matching the given
|
||||
* qualifier, or having a bean name matching the given qualifier.
|
||||
* @param beanFactory the factory to get the target beans from (also searching ancestors)
|
||||
* @param beanType the type of beans to retrieve
|
||||
* @param qualifier the qualifier for selecting among all type matches
|
||||
* @return the matching beans of type {@code T}
|
||||
* @throws BeansException if any of the matching beans could not be created
|
||||
* @since 5.1.1
|
||||
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
|
||||
*/
|
||||
public static <T> Map<String, T> qualifiedBeansOfType(
|
||||
ListableBeanFactory beanFactory, Class<T> beanType, String qualifier) throws BeansException {
|
||||
|
||||
String[] candidateBeans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, beanType);
|
||||
Map<String, T> result = new LinkedHashMap<>(4);
|
||||
for (String beanName : candidateBeans) {
|
||||
if (isQualifierMatch(qualifier::equals, beanName, beanFactory)) {
|
||||
result.put(beanName, beanFactory.getBean(beanName, beanType));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a bean of type {@code T} from the given {@code BeanFactory} declaring a
|
||||
* qualifier (e.g. via {@code <qualifier>} or {@code @Qualifier}) matching the given
|
||||
* qualifier, or having a bean name matching the given qualifier.
|
||||
* @param beanFactory the factory to get the target bean from (also searching ancestors)
|
||||
* @param beanFactory the BeanFactory to get the target bean from
|
||||
* @param beanType the type of bean to retrieve
|
||||
* @param qualifier the qualifier for selecting between multiple bean matches
|
||||
* @return the matching bean of type {@code T} (never {@code null})
|
||||
* @throws NoUniqueBeanDefinitionException if multiple matching beans of type {@code T} found
|
||||
* @throws NoSuchBeanDefinitionException if no matching bean of type {@code T} found
|
||||
* @throws BeansException if the bean could not be created
|
||||
* @see BeanFactoryUtils#beanOfTypeIncludingAncestors(ListableBeanFactory, Class)
|
||||
* @see BeanFactory#getBean(Class)
|
||||
*/
|
||||
public static <T> T qualifiedBeanOfType(BeanFactory beanFactory, Class<T> beanType, String qualifier)
|
||||
throws BeansException {
|
||||
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
|
||||
if (beanFactory instanceof ListableBeanFactory) {
|
||||
if (beanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
// Full qualifier matching supported.
|
||||
return qualifiedBeanOfType((ListableBeanFactory) beanFactory, beanType, qualifier);
|
||||
return qualifiedBeanOfType((ConfigurableListableBeanFactory) beanFactory, beanType, qualifier);
|
||||
}
|
||||
else if (beanFactory.containsBean(qualifier)) {
|
||||
// Fallback: target bean at least found by bean name.
|
||||
@@ -109,12 +82,12 @@ public abstract class BeanFactoryAnnotationUtils {
|
||||
/**
|
||||
* Obtain a bean of type {@code T} from the given {@code BeanFactory} declaring a qualifier
|
||||
* (e.g. {@code <qualifier>} or {@code @Qualifier}) matching the given qualifier).
|
||||
* @param bf the factory to get the target bean from
|
||||
* @param bf the BeanFactory to get the target bean from
|
||||
* @param beanType the type of bean to retrieve
|
||||
* @param qualifier the qualifier for selecting between multiple bean matches
|
||||
* @return the matching bean of type {@code T} (never {@code null})
|
||||
*/
|
||||
private static <T> T qualifiedBeanOfType(ListableBeanFactory bf, Class<T> beanType, String qualifier) {
|
||||
private static <T> T qualifiedBeanOfType(ConfigurableListableBeanFactory bf, Class<T> beanType, String qualifier) {
|
||||
String[] candidateBeans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(bf, beanType);
|
||||
String matchingBean = null;
|
||||
for (String beanName : candidateBeans) {
|
||||
@@ -142,14 +115,14 @@ public abstract class BeanFactoryAnnotationUtils {
|
||||
* Check whether the named bean declares a qualifier of the given name.
|
||||
* @param qualifier the qualifier to match
|
||||
* @param beanName the name of the candidate bean
|
||||
* @param beanFactory the factory from which to retrieve the named bean
|
||||
* @param beanFactory the {@code BeanFactory} from which to retrieve the named bean
|
||||
* @return {@code true} if either the bean definition (in the XML case)
|
||||
* or the bean's factory method (in the {@code @Bean} case) defines a matching
|
||||
* qualifier value (through {@code <qualifier>} or {@code @Qualifier})
|
||||
* @since 5.0
|
||||
*/
|
||||
public static boolean isQualifierMatch(
|
||||
Predicate<String> qualifier, String beanName, @Nullable BeanFactory beanFactory) {
|
||||
public static boolean isQualifierMatch(Predicate<String> qualifier, String beanName,
|
||||
@Nullable BeanFactory beanFactory) {
|
||||
|
||||
// Try quick bean name or alias match first...
|
||||
if (qualifier.test(beanName)) {
|
||||
@@ -162,7 +135,6 @@ public abstract class BeanFactoryAnnotationUtils {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class<?> beanType = beanFactory.getType(beanName);
|
||||
if (beanFactory instanceof ConfigurableBeanFactory) {
|
||||
BeanDefinition bd = ((ConfigurableBeanFactory) beanFactory).getMergedBeanDefinition(beanName);
|
||||
// Explicit qualifier metadata on bean definition? (typically in XML definition)
|
||||
@@ -188,6 +160,7 @@ public abstract class BeanFactoryAnnotationUtils {
|
||||
}
|
||||
}
|
||||
// Corresponding qualifier on bean implementation class? (for custom user types)
|
||||
Class<?> beanType = beanFactory.getType(beanName);
|
||||
if (beanType != null) {
|
||||
Qualifier targetAnnotation = AnnotationUtils.getAnnotation(beanType, Qualifier.class);
|
||||
if (targetAnnotation != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import java.lang.annotation.Target;
|
||||
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
|
||||
*
|
||||
* <p>A common use case is to assign default field values using
|
||||
* {@code #{systemProperties.myProp}} style expressions.
|
||||
* "#{systemProperties.myProp}" style expressions.
|
||||
*
|
||||
* <p>Note that actual processing of the {@code @Value} annotation is performed
|
||||
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||
@@ -55,7 +55,7 @@ import java.lang.annotation.Target;
|
||||
public @interface Value {
|
||||
|
||||
/**
|
||||
* The actual value expression: for example {@code #{systemProperties.myProp}}.
|
||||
* The actual value expression: e.g. "#{systemProperties.myProp}".
|
||||
*/
|
||||
String value();
|
||||
|
||||
|
||||
+5
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -289,8 +289,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
|
||||
* instance, invoking their {@code postProcessBeforeInitialization} methods.
|
||||
* The returned bean instance may be a wrapper around the original.
|
||||
* @param existingBean the existing bean instance
|
||||
* @param beanName the name of the bean, to be passed to it if necessary
|
||||
* @param existingBean the new bean instance
|
||||
* (only passed to {@link BeanPostProcessor BeanPostProcessors};
|
||||
* can follow the {@link #ORIGINAL_INSTANCE_SUFFIX} convention in order to
|
||||
* enforce the given instance to be returned, i.e. no proxies etc)
|
||||
@@ -306,8 +305,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
|
||||
* instance, invoking their {@code postProcessAfterInitialization} methods.
|
||||
* The returned bean instance may be a wrapper around the original.
|
||||
* @param existingBean the existing bean instance
|
||||
* @param beanName the name of the bean, to be passed to it if necessary
|
||||
* @param existingBean the new bean instance
|
||||
* (only passed to {@link BeanPostProcessor BeanPostProcessors};
|
||||
* can follow the {@link #ORIGINAL_INSTANCE_SUFFIX} convention in order to
|
||||
* enforce the given instance to be returned, i.e. no proxies etc)
|
||||
@@ -339,7 +337,8 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* including its bean name.
|
||||
* <p>This is effectively a variant of {@link #getBean(Class)} which preserves the
|
||||
* bean name of the matching instance.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* @return the bean name plus bean instance
|
||||
* @throws NoSuchBeanDefinitionException if no matching bean was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one matching bean was found
|
||||
@@ -349,22 +348,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
*/
|
||||
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
|
||||
|
||||
/**
|
||||
* Resolve a bean instance for the given bean name, providing a dependency descriptor
|
||||
* for exposure to target factory methods.
|
||||
* <p>This is effectively a variant of {@link #getBean(String, Class)} which supports
|
||||
* factory methods with an {@link org.springframework.beans.factory.InjectionPoint}
|
||||
* argument.
|
||||
* @param name the name of the bean to look up
|
||||
* @param descriptor the dependency descriptor for the requesting injection point
|
||||
* @return the corresponding bean instance
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
|
||||
* @throws BeansException if the bean could not be created
|
||||
* @since 5.1.5
|
||||
* @see #getBean(String, Class)
|
||||
*/
|
||||
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
|
||||
|
||||
/**
|
||||
* Resolve the specified dependency against the beans defined in this factory.
|
||||
* @param descriptor the descriptor for the dependency (field/method/constructor)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,7 +59,7 @@ public class BeanExpressionContext {
|
||||
if (this.beanFactory.containsBean(key)) {
|
||||
return this.beanFactory.getBean(key);
|
||||
}
|
||||
else if (this.scope != null) {
|
||||
else if (this.scope != null){
|
||||
return this.scope.resolveContextualObject(key);
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,6 @@ import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -78,9 +77,6 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
@Nullable
|
||||
private transient volatile ResolvableType resolvableType;
|
||||
|
||||
@Nullable
|
||||
private transient volatile TypeDescriptor typeDescriptor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new descriptor for a method or constructor parameter.
|
||||
@@ -305,7 +301,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link ResolvableType} object for the wrapped parameter/field.
|
||||
* Build a ResolvableType object for the wrapped parameter/field.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ResolvableType getResolvableType() {
|
||||
@@ -319,21 +315,6 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
return resolvableType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link TypeDescriptor} object for the wrapped parameter/field.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
public TypeDescriptor getTypeDescriptor() {
|
||||
TypeDescriptor typeDescriptor = this.typeDescriptor;
|
||||
if (typeDescriptor == null) {
|
||||
typeDescriptor = (this.field != null ?
|
||||
new TypeDescriptor(getResolvableType(), getDependencyType(), getAnnotations()) :
|
||||
new TypeDescriptor(obtainMethodParameter()));
|
||||
this.typeDescriptor = typeDescriptor;
|
||||
}
|
||||
return typeDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a fallback match is allowed.
|
||||
* <p>This is {@code false} by default but may be overridden to return {@code true} in order
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -121,7 +121,7 @@ public class PreferencesPlaceholderConfigurer extends PropertyPlaceholderConfigu
|
||||
@Nullable
|
||||
protected String resolvePlaceholder(@Nullable String path, String key, Preferences preferences) {
|
||||
if (path != null) {
|
||||
// Do not create the node if it does not exist...
|
||||
// Do not create the node if it does not exist...
|
||||
try {
|
||||
if (preferences.nodeExists(path)) {
|
||||
return preferences.node(path).get(key, null);
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||
"': expected 'beanName" + this.beanNameSeparator + "property'");
|
||||
}
|
||||
String beanName = key.substring(0, separatorIndex);
|
||||
String beanProperty = key.substring(separatorIndex + 1);
|
||||
String beanProperty = key.substring(separatorIndex+1);
|
||||
this.beanNames.add(beanName);
|
||||
applyPropertyValue(factory, beanName, beanProperty, value);
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
+24
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,26 +28,32 @@ import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* {@link PlaceholderConfigurerSupport} subclass that resolves ${...} placeholders against
|
||||
* {@link #setLocation local} {@link #setProperties properties} and/or system properties
|
||||
* {@link PlaceholderConfigurerSupport} subclass that resolves ${...} placeholders
|
||||
* against {@link #setLocation local} {@link #setProperties properties} and/or system properties
|
||||
* and environment variables.
|
||||
*
|
||||
* <p>As of Spring 3.1, {@link org.springframework.context.support.PropertySourcesPlaceholderConfigurer
|
||||
* PropertySourcesPlaceholderConfigurer} should be used preferentially over this implementation; it is
|
||||
* more flexible through taking advantage of the {@link org.springframework.core.env.Environment} and
|
||||
* {@link org.springframework.core.env.PropertySource} mechanisms also made available in Spring 3.1.
|
||||
* more flexible through taking advantage of the {@link org.springframework.core.env.Environment Environment} and
|
||||
* {@link org.springframework.core.env.PropertySource PropertySource} mechanisms also made available in Spring 3.1.
|
||||
*
|
||||
* <p>{@link PropertyPlaceholderConfigurer} is still appropriate for use when:
|
||||
* <ul>
|
||||
* <li>the {@code spring-context} module is not available (i.e., one is using Spring's
|
||||
* {@code BeanFactory} API as opposed to {@code ApplicationContext}).
|
||||
* <li>existing configuration makes use of the {@link #setSystemPropertiesMode(int) "systemPropertiesMode"}
|
||||
* and/or {@link #setSystemPropertiesModeName(String) "systemPropertiesModeName"} properties.
|
||||
* Users are encouraged to move away from using these settings, and rather configure property
|
||||
* source search order through the container's {@code Environment}; however, exact preservation
|
||||
* of functionality may be maintained by continuing to use {@code PropertyPlaceholderConfigurer}.
|
||||
* <li>existing configuration makes use of the {@link #setSystemPropertiesMode(int) "systemPropertiesMode"} and/or
|
||||
* {@link #setSystemPropertiesModeName(String) "systemPropertiesModeName"} properties. Users are encouraged to move
|
||||
* away from using these settings, and rather configure property source search order through the container's
|
||||
* {@code Environment}; however, exact preservation of functionality may be maintained by continuing to
|
||||
* use {@code PropertyPlaceholderConfigurer}.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Prior to Spring 3.1, the {@code <context:property-placeholder/>} namespace element
|
||||
* registered an instance of {@code PropertyPlaceholderConfigurer}. It will still do so if
|
||||
* using the {@code spring-context-3.0.xsd} definition of the namespace. That is, you can preserve
|
||||
* registration of {@code PropertyPlaceholderConfigurer} through the namespace, even if using Spring 3.1;
|
||||
* simply do not update your {@code xsi:schemaLocation} and continue using the 3.0 XSD.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 02.10.2003
|
||||
@@ -86,6 +92,7 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
|
||||
* Set the system property mode by the name of the corresponding constant,
|
||||
* e.g. "SYSTEM_PROPERTIES_MODE_OVERRIDE".
|
||||
* @param constantName name of the constant
|
||||
* @throws java.lang.IllegalArgumentException if an invalid constant was specified
|
||||
* @see #setSystemPropertiesMode
|
||||
*/
|
||||
public void setSystemPropertiesModeName(String constantName) throws IllegalArgumentException {
|
||||
@@ -117,9 +124,14 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
|
||||
* against system environment variables. Note that it is generally recommended
|
||||
* to pass external values in as JVM system properties: This can easily be
|
||||
* achieved in a startup script, even for existing environment variables.
|
||||
* <p><b>NOTE:</b> Access to environment variables does not work on the
|
||||
* Sun VM 1.4, where the corresponding {@link System#getenv} support was
|
||||
* disabled - before it eventually got re-enabled for the Sun VM 1.5.
|
||||
* Please upgrade to 1.5 (or higher) if you intend to rely on the
|
||||
* environment variable support.
|
||||
* @see #setSystemPropertiesMode
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
* @see java.lang.System#getProperty(String)
|
||||
* @see java.lang.System#getenv(String)
|
||||
*/
|
||||
public void setSearchSystemEnvironment(boolean searchSystemEnvironment) {
|
||||
this.searchSystemEnvironment = searchSystemEnvironment;
|
||||
|
||||
+9
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,7 +58,6 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.InjectionPoint;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -338,6 +337,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return initializeBean(beanName, existingBean, bd);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
|
||||
return resolveDependency(descriptor, requestingBeanName, null, null);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Specialized methods for fine-grained control over the bean lifecycle
|
||||
@@ -441,28 +446,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Delegate methods for resolving injection points
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Object resolveBeanByName(String name, DependencyDescriptor descriptor) {
|
||||
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
|
||||
try {
|
||||
return getBean(name, descriptor.getDependencyType());
|
||||
}
|
||||
finally {
|
||||
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
|
||||
return resolveDependency(descriptor, requestingBeanName, null, null);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of relevant AbstractBeanFactory template methods
|
||||
//---------------------------------------------------------------------
|
||||
@@ -792,7 +775,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
}
|
||||
|
||||
mbd.factoryMethodToIntrospect = uniqueCandidate;
|
||||
if (commonType == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -1140,7 +1122,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return obtainFromSupplier(instanceSupplier, beanName);
|
||||
}
|
||||
|
||||
if (mbd.getFactoryMethodName() != null) {
|
||||
if (mbd.getFactoryMethodName() != null) {
|
||||
return instantiateUsingFactoryMethod(beanName, mbd, args);
|
||||
}
|
||||
|
||||
@@ -1167,7 +1149,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// Candidate constructors for autowiring?
|
||||
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
|
||||
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
|
||||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
|
||||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
|
||||
return autowireConstructor(beanName, mbd, ctors, args);
|
||||
}
|
||||
|
||||
|
||||
+10
-37
@@ -510,21 +510,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
// Generics potentially only match on the target class, not on the proxy...
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
Class<?> targetType = mbd.getTargetType();
|
||||
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
|
||||
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance) &&
|
||||
typeToMatch.isAssignableFrom(targetType)) {
|
||||
// Check raw class match as well, making sure it's exposed on the proxy.
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
|
||||
return false;
|
||||
}
|
||||
if (typeToMatch.isAssignableFrom(targetType)) {
|
||||
return true;
|
||||
}
|
||||
return (classToMatch == null || classToMatch.isInstance(beanInstance));
|
||||
}
|
||||
ResolvableType resolvableType = mbd.targetType;
|
||||
if (resolvableType == null) {
|
||||
resolvableType = mbd.factoryMethodReturnType;
|
||||
}
|
||||
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1371,7 +1362,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
@Nullable
|
||||
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
|
||||
throws CannotLoadBeanClassException {
|
||||
|
||||
try {
|
||||
if (mbd.hasBeanClass()) {
|
||||
return mbd.getBeanClass();
|
||||
@@ -1401,16 +1391,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
throws ClassNotFoundException {
|
||||
|
||||
ClassLoader beanClassLoader = getBeanClassLoader();
|
||||
ClassLoader dynamicLoader = beanClassLoader;
|
||||
boolean freshResolve = false;
|
||||
|
||||
ClassLoader classLoaderToUse = beanClassLoader;
|
||||
if (!ObjectUtils.isEmpty(typesToMatch)) {
|
||||
// When just doing type checks (i.e. not creating an actual instance yet),
|
||||
// use the specified temporary class loader (e.g. in a weaving scenario).
|
||||
ClassLoader tempClassLoader = getTempClassLoader();
|
||||
if (tempClassLoader != null) {
|
||||
dynamicLoader = tempClassLoader;
|
||||
freshResolve = true;
|
||||
classLoaderToUse = tempClassLoader;
|
||||
if (tempClassLoader instanceof DecoratingClassLoader) {
|
||||
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
|
||||
for (Class<?> typeToMatch : typesToMatch) {
|
||||
@@ -1419,7 +1406,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String className = mbd.getBeanClassName();
|
||||
if (className != null) {
|
||||
Object evaluated = evaluateBeanDefinitionString(className, mbd);
|
||||
@@ -1429,31 +1415,18 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return (Class<?>) evaluated;
|
||||
}
|
||||
else if (evaluated instanceof String) {
|
||||
className = (String) evaluated;
|
||||
freshResolve = true;
|
||||
return ClassUtils.forName((String) evaluated, classLoaderToUse);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
|
||||
}
|
||||
}
|
||||
if (freshResolve) {
|
||||
// When resolving against a temporary class loader, exit early in order
|
||||
// to avoid storing the resolved Class in the bean definition.
|
||||
if (dynamicLoader != null) {
|
||||
try {
|
||||
return dynamicLoader.loadClass(className);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ClassUtils.forName(className, dynamicLoader);
|
||||
// When resolving against a temporary class loader, exit early in order
|
||||
// to avoid storing the resolved Class in the bean definition.
|
||||
if (classLoaderToUse != beanClassLoader) {
|
||||
return ClassUtils.forName(className, classLoaderToUse);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve regularly, caching the result in the BeanDefinition...
|
||||
return mbd.resolveBeanClass(beanClassLoader);
|
||||
}
|
||||
|
||||
|
||||
+22
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.beans.factory.support;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -29,7 +28,6 @@ import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
@@ -51,18 +49,6 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
abstract class AutowireUtils {
|
||||
|
||||
private static final Comparator<Executable> EXECUTABLE_COMPARATOR = (e1, e2) -> {
|
||||
boolean p1 = Modifier.isPublic(e1.getModifiers());
|
||||
boolean p2 = Modifier.isPublic(e2.getModifiers());
|
||||
if (p1 != p2) {
|
||||
return (p1 ? -1 : 1);
|
||||
}
|
||||
int c1pl = e1.getParameterCount();
|
||||
int c2pl = e2.getParameterCount();
|
||||
return Integer.compare(c2pl, c1pl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sort the given constructors, preferring public constructors and "greedy" ones with
|
||||
* a maximum number of arguments. The result will contain public constructors first,
|
||||
@@ -71,7 +57,16 @@ abstract class AutowireUtils {
|
||||
* @param constructors the constructor array to sort
|
||||
*/
|
||||
public static void sortConstructors(Constructor<?>[] constructors) {
|
||||
Arrays.sort(constructors, EXECUTABLE_COMPARATOR);
|
||||
Arrays.sort(constructors, (c1, c2) -> {
|
||||
boolean p1 = Modifier.isPublic(c1.getModifiers());
|
||||
boolean p2 = Modifier.isPublic(c2.getModifiers());
|
||||
if (p1 != p2) {
|
||||
return (p1 ? -1 : 1);
|
||||
}
|
||||
int c1pl = c1.getParameterCount();
|
||||
int c2pl = c2.getParameterCount();
|
||||
return (c1pl < c2pl ? 1 : (c1pl > c2pl ? -1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +77,16 @@ abstract class AutowireUtils {
|
||||
* @param factoryMethods the factory method array to sort
|
||||
*/
|
||||
public static void sortFactoryMethods(Method[] factoryMethods) {
|
||||
Arrays.sort(factoryMethods, EXECUTABLE_COMPARATOR);
|
||||
Arrays.sort(factoryMethods, (fm1, fm2) -> {
|
||||
boolean p1 = Modifier.isPublic(fm1.getModifiers());
|
||||
boolean p2 = Modifier.isPublic(fm2.getModifiers());
|
||||
if (p1 != p2) {
|
||||
return (p1 ? -1 : 1);
|
||||
}
|
||||
int c1pl = fm1.getParameterCount();
|
||||
int c2pl = fm2.getParameterCount();
|
||||
return (c1pl < c2pl ? 1 : (c1pl > c2pl ? -1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +158,7 @@ abstract class AutowireUtils {
|
||||
* on the given method itself.
|
||||
* <p>For example, given a factory method with the following signature, if
|
||||
* {@code resolveReturnTypeForFactoryMethod()} is invoked with the reflected
|
||||
* method for {@code createProxy()} and an {@code Object[]} array containing
|
||||
* method for {@code creatProxy()} and an {@code Object[]} array containing
|
||||
* {@code MyService.class}, {@code resolveReturnTypeForFactoryMethod()} will
|
||||
* infer that the target return type is {@code MyService}.
|
||||
* <pre class="code">{@code public static <T> T createProxy(Class<T> clazz)}</pre>
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ public final class BeanDefinitionBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dependency check mode for this definition.
|
||||
* Set the depency check mode for this definition.
|
||||
*/
|
||||
public BeanDefinitionBuilder setDependencyCheck(int dependencyCheck) {
|
||||
this.beanDefinition.setDependencyCheck(dependencyCheck);
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ class BeanDefinitionResource extends AbstractResource {
|
||||
|
||||
/**
|
||||
* Create a new BeanDefinitionResource.
|
||||
* @param beanDefinition the BeanDefinition object to wrap
|
||||
* @param beanDefinition the BeanDefinition objectto wrap
|
||||
*/
|
||||
public BeanDefinitionResource(BeanDefinition beanDefinition) {
|
||||
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
|
||||
|
||||
+7
-9
@@ -196,7 +196,7 @@ class ConstructorResolver {
|
||||
for (Constructor<?> candidate : candidates) {
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
|
||||
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
|
||||
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
|
||||
// Already found greedy constructor that can be satisfied ->
|
||||
// do not look any further, there are only less greedy constructors left.
|
||||
break;
|
||||
@@ -276,12 +276,11 @@ class ConstructorResolver {
|
||||
ambiguousConstructors);
|
||||
}
|
||||
|
||||
if (explicitArgs == null && argsHolderToUse != null) {
|
||||
if (explicitArgs == null) {
|
||||
argsHolderToUse.storeCache(mbd, constructorToUse);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.state(argsToUse != null, "Unresolved constructor arguments");
|
||||
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
|
||||
return bw;
|
||||
}
|
||||
@@ -338,7 +337,9 @@ class ConstructorResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
mbd.factoryMethodToIntrospect = uniqueCandidate;
|
||||
synchronized (mbd.constructorArgumentLock) {
|
||||
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -447,7 +448,6 @@ class ConstructorResolver {
|
||||
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
|
||||
Method uniqueCandidate = candidateList.get(0);
|
||||
if (uniqueCandidate.getParameterCount() == 0) {
|
||||
mbd.factoryMethodToIntrospect = uniqueCandidate;
|
||||
synchronized (mbd.constructorArgumentLock) {
|
||||
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
|
||||
mbd.constructorArgumentsResolved = true;
|
||||
@@ -598,18 +598,16 @@ class ConstructorResolver {
|
||||
}
|
||||
|
||||
if (explicitArgs == null && argsHolderToUse != null) {
|
||||
mbd.factoryMethodToIntrospect = factoryMethodToUse;
|
||||
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.state(argsToUse != null, "Unresolved factory method arguments");
|
||||
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
|
||||
return bw;
|
||||
}
|
||||
|
||||
private Object instantiate(String beanName, RootBeanDefinition mbd,
|
||||
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
private Object instantiate(
|
||||
String beanName, RootBeanDefinition mbd, Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
|
||||
+27
-35
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -382,13 +382,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType))
|
||||
return Arrays.stream(getBeanNamesForType(requiredType))
|
||||
.map(name -> (T) getBean(name))
|
||||
.filter(bean -> !(bean instanceof NullBean));
|
||||
}
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType);
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
Map<String, T> matchingBeans = new LinkedHashMap<>(beanNames.length);
|
||||
for (String beanName : beanNames) {
|
||||
Object beanInstance = getBean(beanName);
|
||||
@@ -424,10 +424,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of ListableBeanFactory interface
|
||||
@@ -665,7 +661,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
@Nullable
|
||||
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
throws NoSuchBeanDefinitionException{
|
||||
|
||||
A ann = null;
|
||||
Class<?> beanType = getType(beanName);
|
||||
@@ -677,10 +673,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (bd instanceof AbstractBeanDefinition) {
|
||||
AbstractBeanDefinition abd = (AbstractBeanDefinition) bd;
|
||||
if (abd.hasBeanClass()) {
|
||||
Class<?> beanClass = abd.getBeanClass();
|
||||
if (beanClass != beanType) {
|
||||
ann = AnnotationUtils.findAnnotation(beanClass, annotationType);
|
||||
}
|
||||
ann = AnnotationUtils.findAnnotation(abd.getBeanClass(), annotationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,8 +751,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
resolveBeanClass(mbd, beanDefinitionName);
|
||||
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
|
||||
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
|
||||
if (mbd.isFactoryMethodUnique) {
|
||||
boolean resolve;
|
||||
synchronized (mbd.constructorArgumentLock) {
|
||||
resolve = (mbd.resolvedConstructorOrFactoryMethod == null);
|
||||
}
|
||||
if (resolve) {
|
||||
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
|
||||
}
|
||||
}
|
||||
return resolver.isAutowireCandidate(
|
||||
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
|
||||
@@ -1096,6 +1095,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
|
||||
|
||||
Assert.notNull(requiredType, "Required type must not be null");
|
||||
Class<?> clazz = requiredType.getRawClass();
|
||||
Assert.notNull(clazz, "Required type must have a raw Class");
|
||||
String[] candidateNames = getBeanNamesForType(requiredType);
|
||||
|
||||
if (candidateNames.length > 1) {
|
||||
@@ -1112,7 +1113,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
if (candidateNames.length == 1) {
|
||||
String beanName = candidateNames[0];
|
||||
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
|
||||
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, clazz, args));
|
||||
}
|
||||
else if (candidateNames.length > 1) {
|
||||
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
|
||||
@@ -1125,14 +1126,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
candidates.put(beanName, getType(beanName));
|
||||
}
|
||||
}
|
||||
String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
|
||||
String candidateName = determinePrimaryCandidate(candidates, clazz);
|
||||
if (candidateName == null) {
|
||||
candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
|
||||
candidateName = determineHighestPriorityCandidate(candidates, clazz);
|
||||
}
|
||||
if (candidateName != null) {
|
||||
Object beanInstance = candidates.get(candidateName);
|
||||
if (beanInstance == null || beanInstance instanceof Class) {
|
||||
beanInstance = getBean(candidateName, requiredType.toClass(), args);
|
||||
beanInstance = getBean(candidateName, clazz, args);
|
||||
}
|
||||
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
|
||||
}
|
||||
@@ -1186,20 +1187,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (value != null) {
|
||||
if (value instanceof String) {
|
||||
String strVal = resolveEmbeddedValue((String) value);
|
||||
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
|
||||
getMergedBeanDefinition(beanName) : null);
|
||||
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
|
||||
value = evaluateBeanDefinitionString(strVal, bd);
|
||||
}
|
||||
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
|
||||
try {
|
||||
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
// A custom TypeConverter which does not support TypeDescriptor resolution...
|
||||
return (descriptor.getField() != null ?
|
||||
converter.convertIfNecessary(value, type, descriptor.getField()) :
|
||||
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
|
||||
}
|
||||
return (descriptor.getField() != null ?
|
||||
converter.convertIfNecessary(value, type, descriptor.getField()) :
|
||||
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
|
||||
}
|
||||
|
||||
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
|
||||
@@ -1697,8 +1691,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
super.resolveCandidate(beanName, requiredType, beanFactory));
|
||||
}
|
||||
};
|
||||
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
|
||||
return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
|
||||
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
|
||||
}
|
||||
|
||||
|
||||
@@ -1759,9 +1752,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
// Lenient fallback: dummy factory in case of original factory not found...
|
||||
DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory();
|
||||
dummyFactory.serializationId = this.id;
|
||||
return dummyFactory;
|
||||
return new DefaultListableBeanFactory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1926,7 +1917,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
private Stream<Object> resolveStream(boolean ordered) {
|
||||
DependencyDescriptor descriptorToUse = new StreamDependencyDescriptor(this.descriptor, ordered);
|
||||
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
return (result instanceof Stream ? (Stream<Object>) result : Stream.of(result));
|
||||
Assert.state(result instanceof Stream, "Stream expected");
|
||||
return (Stream<Object>) result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -510,7 +510,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
|
||||
* Reads the value of the entry. Correctly interprets bean references for
|
||||
* values that are prefixed with an asterisk.
|
||||
*/
|
||||
private Object readValue(Map.Entry<?, ?> entry) {
|
||||
private Object readValue(Map.Entry<? ,?> entry) {
|
||||
Object val = entry.getValue();
|
||||
if (val instanceof String) {
|
||||
String strVal = (String) val;
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -82,10 +82,9 @@ public class ReplaceOverride extends MethodOverride {
|
||||
if (this.typeIdentifiers.size() != method.getParameterCount()) {
|
||||
return false;
|
||||
}
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
for (int i = 0; i < this.typeIdentifiers.size(); i++) {
|
||||
String identifier = this.typeIdentifiers.get(i);
|
||||
if (!parameterTypes[i].getName().contains(identifier)) {
|
||||
if (!method.getParameterTypes()[i].getName().contains(identifier)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -75,10 +75,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
@Nullable
|
||||
volatile ResolvableType factoryMethodReturnType;
|
||||
|
||||
/** Package-visible field for caching a unique factory method candidate for introspection. */
|
||||
@Nullable
|
||||
volatile Method factoryMethodToIntrospect;
|
||||
|
||||
/** Common lock for the four constructor fields below. */
|
||||
final Object constructorArgumentLock = new Object();
|
||||
|
||||
@@ -374,7 +370,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
*/
|
||||
@Nullable
|
||||
public Method getResolvedFactoryMethod() {
|
||||
return this.factoryMethodToIntrospect;
|
||||
synchronized (this.constructorArgumentLock) {
|
||||
Executable candidate = this.resolvedConstructorOrFactoryMethod;
|
||||
return (candidate instanceof Method ? (Method) candidate : null);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
|
||||
}
|
||||
else {
|
||||
constructorToUse = clazz.getDeclaredConstructor();
|
||||
constructorToUse = clazz.getDeclaredConstructor();
|
||||
}
|
||||
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
|
||||
}
|
||||
|
||||
+1
-1
@@ -432,7 +432,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
@Override
|
||||
@Nullable
|
||||
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
throws NoSuchBeanDefinitionException{
|
||||
|
||||
Class<?> beanType = getType(beanName);
|
||||
return (beanType != null ? AnnotationUtils.findAnnotation(beanType, annotationType) : null);
|
||||
|
||||
+8
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -320,21 +320,21 @@ public class BeanDefinitionParserDelegate {
|
||||
*/
|
||||
protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable DocumentDefaultsDefinition parentDefaults, Element root) {
|
||||
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
|
||||
if (isDefaultValue(lazyInit)) {
|
||||
if (DEFAULT_VALUE.equals(lazyInit)) {
|
||||
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
|
||||
lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
|
||||
}
|
||||
defaults.setLazyInit(lazyInit);
|
||||
|
||||
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
|
||||
if (isDefaultValue(merge)) {
|
||||
if (DEFAULT_VALUE.equals(merge)) {
|
||||
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
|
||||
merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
|
||||
}
|
||||
defaults.setMerge(merge);
|
||||
|
||||
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
|
||||
if (isDefaultValue(autowire)) {
|
||||
if (DEFAULT_VALUE.equals(autowire)) {
|
||||
// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
|
||||
autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
|
||||
}
|
||||
@@ -572,7 +572,7 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
|
||||
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
|
||||
if (isDefaultValue(lazyInit)) {
|
||||
if (DEFAULT_VALUE.equals(lazyInit)) {
|
||||
lazyInit = this.defaults.getLazyInit();
|
||||
}
|
||||
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
|
||||
@@ -586,7 +586,7 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
|
||||
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
|
||||
if (isDefaultValue(autowireCandidate)) {
|
||||
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
|
||||
String candidatePattern = this.defaults.getAutowireCandidates();
|
||||
if (candidatePattern != null) {
|
||||
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
|
||||
@@ -661,7 +661,7 @@ public class BeanDefinitionParserDelegate {
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getAutowireMode(String attValue) {
|
||||
String att = attValue;
|
||||
if (isDefaultValue(att)) {
|
||||
if (DEFAULT_VALUE.equals(att)) {
|
||||
att = this.defaults.getAutowire();
|
||||
}
|
||||
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
|
||||
@@ -1341,7 +1341,7 @@ public class BeanDefinitionParserDelegate {
|
||||
*/
|
||||
public boolean parseMergeAttribute(Element collectionElement) {
|
||||
String value = collectionElement.getAttribute(MERGE_ATTRIBUTE);
|
||||
if (isDefaultValue(value)) {
|
||||
if (DEFAULT_VALUE.equals(value)) {
|
||||
value = this.defaults.getMerge();
|
||||
}
|
||||
return TRUE_VALUE.equals(value);
|
||||
@@ -1481,10 +1481,6 @@ public class BeanDefinitionParserDelegate {
|
||||
return isDefaultNamespace(getNamespaceURI(node));
|
||||
}
|
||||
|
||||
private boolean isDefaultValue(String value) {
|
||||
return (DEFAULT_VALUE.equals(value) || "".equals(value));
|
||||
}
|
||||
|
||||
private boolean isCandidateElement(Node node) {
|
||||
return (node instanceof Element && (isDefaultNamespace(node) || !isDefaultNamespace(node.getParentNode())));
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -118,7 +118,7 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
"Constructor argument '" + argName + "' specifies a negative index", attr);
|
||||
}
|
||||
|
||||
if (cvs.hasIndexedArgumentValue(index)) {
|
||||
if (cvs.hasIndexedArgumentValue(index)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
@@ -130,7 +130,7 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
// no escaping -> ctr name
|
||||
else {
|
||||
String name = Conventions.attributeNameToPropertyName(argName);
|
||||
if (containsArgWithName(name, cvs)) {
|
||||
if (containsArgWithName(name, cvs)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
|
||||
@@ -84,7 +84,7 @@ public class BeanWrapperGenericsTests {
|
||||
fail("Should have thrown TypeMismatchException");
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
assertTrue(ex.getMessage().contains("java.lang.Integer"));
|
||||
assertTrue(ex.getMessage().indexOf("java.lang.Integer") != -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
catch (PropertyBatchUpdateException ex) {
|
||||
assertTrue("Must contain 2 exceptions", ex.getExceptionCount() == 2);
|
||||
// Test validly set property matches
|
||||
assertTrue("Valid set property must stick", target.getName().equals(newName));
|
||||
assertTrue("Vaid set property must stick", target.getName().equals(newName));
|
||||
assertTrue("Invalid set property must retain old value", target.getAge() == 0);
|
||||
assertTrue("New value of dodgy setter must be available through exception",
|
||||
ex.getPropertyAccessException("touchy").getPropertyChangeEvent().getNewValue().equals(invalidTouchy));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ public class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void withShadowedField() {
|
||||
public void withShadowedField() throws Exception {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
|
||||
+1
-1
@@ -198,7 +198,7 @@ public class ServiceLocatorFactoryBeanTests {
|
||||
assertNotSame(testBean2, testBean4);
|
||||
assertNotSame(testBean3, testBean4);
|
||||
|
||||
assertTrue(factory.toString().contains("TestServiceLocator3"));
|
||||
assertTrue(factory.toString().indexOf("TestServiceLocator3") != -1);
|
||||
}
|
||||
|
||||
@Ignore @Test // worked when using an ApplicationContext (see commented), fails when using BeanFactory
|
||||
|
||||
+1
-47
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2013 the original author 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,21 +41,6 @@ public class NestedBeansElementAttributeRecursionTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
|
||||
|
||||
assertLazyInits(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultLazyInitWithNonValidatingParser() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
|
||||
xmlBeanDefinitionReader.setValidating(false);
|
||||
xmlBeanDefinitionReader.loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
|
||||
|
||||
assertLazyInits(bf);
|
||||
}
|
||||
|
||||
private void assertLazyInits(DefaultListableBeanFactory bf) {
|
||||
BeanDefinition foo = bf.getBeanDefinition("foo");
|
||||
BeanDefinition bar = bf.getBeanDefinition("bar");
|
||||
BeanDefinition baz = bf.getBeanDefinition("baz");
|
||||
@@ -76,22 +61,6 @@ public class NestedBeansElementAttributeRecursionTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
|
||||
|
||||
assertMerge(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void defaultMergeWithNonValidatingParser() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
|
||||
xmlBeanDefinitionReader.setValidating(false);
|
||||
xmlBeanDefinitionReader.loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
|
||||
|
||||
assertMerge(bf);
|
||||
}
|
||||
|
||||
private void assertMerge(DefaultListableBeanFactory bf) {
|
||||
TestBean topLevel = bf.getBean("topLevelConcreteTestBean", TestBean.class);
|
||||
// has the concrete child bean values
|
||||
assertThat((Iterable<String>) topLevel.getSomeList(), hasItems("charlie", "delta"));
|
||||
@@ -115,21 +84,6 @@ public class NestedBeansElementAttributeRecursionTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
|
||||
|
||||
assertAutowireCandidates(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultAutowireCandidatesWithNonValidatingParser() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
|
||||
xmlBeanDefinitionReader.setValidating(false);
|
||||
xmlBeanDefinitionReader.loadBeanDefinitions(
|
||||
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
|
||||
|
||||
assertAutowireCandidates(bf);
|
||||
}
|
||||
|
||||
private void assertAutowireCandidates(DefaultListableBeanFactory bf) {
|
||||
assertThat(bf.getBeanDefinition("fooService").isAutowireCandidate(), is(true));
|
||||
assertThat(bf.getBeanDefinition("fooRepository").isAutowireCandidate(), is(true));
|
||||
assertThat(bf.getBeanDefinition("other").isAutowireCandidate(), is(false));
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
+29
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,86 +84,87 @@ public class CandidateComponentsIndexerTests {
|
||||
this.compiler = new TestCompiler(this.temporaryFolder);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void noCandidate() {
|
||||
public void noCandidate() throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNone.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noAnnotation() {
|
||||
public void noAnnotation() throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(CandidateComponentsIndexerTests.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeComponent() {
|
||||
public void stereotypeComponent() throws IOException {
|
||||
testComponent(SampleComponent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeService() {
|
||||
public void stereotypeService() throws IOException {
|
||||
testComponent(SampleService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeController() {
|
||||
public void stereotypeController() throws IOException {
|
||||
testComponent(SampleController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeControllerMetaAnnotation() {
|
||||
public void stereotypeControllerMetaAnnotation() throws IOException {
|
||||
testComponent(SampleMetaController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeRepository() {
|
||||
public void stereotypeRepository() throws IOException {
|
||||
testSingleComponent(SampleRepository.class, Component.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeControllerMetaIndex() {
|
||||
public void stereotypeControllerMetaIndex() throws IOException {
|
||||
testSingleComponent(SampleMetaIndexedController.class,
|
||||
Component.class, MetaControllerIndexed.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeOnAbstractClass() {
|
||||
public void stereotypeOnAbstractClass() throws IOException {
|
||||
testComponent(AbstractController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cdiManagedBean() {
|
||||
public void cdiManagedBean() throws IOException {
|
||||
testSingleComponent(SampleManagedBean.class, ManagedBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cdiNamed() {
|
||||
public void cdiNamed() throws IOException {
|
||||
testSingleComponent(SampleNamed.class, Named.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceEntity() {
|
||||
public void persistenceEntity() throws IOException {
|
||||
testSingleComponent(SampleEntity.class, Entity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceMappedSuperClass() {
|
||||
public void persistenceMappedSuperClass() throws IOException {
|
||||
testSingleComponent(SampleMappedSuperClass.class, MappedSuperclass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceEmbeddable() {
|
||||
public void persistenceEmbeddable() throws IOException {
|
||||
testSingleComponent(SampleEmbeddable.class, Embeddable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceConverter() {
|
||||
public void persistenceConverter() throws IOException {
|
||||
testSingleComponent(SampleConverter.class, Converter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void packageInfo() {
|
||||
public void packageInfo() throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(
|
||||
"org/springframework/context/index/sample/jpa/package-info");
|
||||
assertThat(metadata, hasComponent(
|
||||
@@ -171,32 +172,32 @@ public class CandidateComponentsIndexerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromMetaInterface() {
|
||||
public void typeStereotypeFromMetaInterface() throws IOException {
|
||||
testSingleComponent(SampleSpecializedRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromInterfaceFromSuperClass() {
|
||||
public void typeStereotypeFromInterfaceFromSuperClass() throws IOException {
|
||||
testSingleComponent(SampleRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromSeveralInterfaces() {
|
||||
public void typeStereotypeFromSeveralInterfaces() throws IOException {
|
||||
testSingleComponent(SampleSmartRepo.class, Repo.class, SmartRepo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnInterface() {
|
||||
public void typeStereotypeOnInterface() throws IOException {
|
||||
testSingleComponent(SpecializedRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnInterfaceFromSeveralInterfaces() {
|
||||
public void typeStereotypeOnInterfaceFromSeveralInterfaces() throws IOException {
|
||||
testSingleComponent(SmartRepo.class, Repo.class, SmartRepo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnIndexedInterface() {
|
||||
public void typeStereotypeOnIndexedInterface() throws IOException {
|
||||
testSingleComponent(Repo.class, Repo.class);
|
||||
}
|
||||
|
||||
@@ -216,12 +217,12 @@ public class CandidateComponentsIndexerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedNonStaticCandidateAreIgnored() {
|
||||
public void embeddedNonStaticCandidateAreIgnored() throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNonStaticEmbedded.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
private void testComponent(Class<?>... classes) {
|
||||
private void testComponent(Class<?>... classes) throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(classes);
|
||||
for (Class<?> c : classes) {
|
||||
assertThat(metadata, hasComponent(c, Component.class));
|
||||
@@ -229,19 +230,19 @@ public class CandidateComponentsIndexerTests {
|
||||
assertThat(metadata.getItems(), hasSize(classes.length));
|
||||
}
|
||||
|
||||
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) {
|
||||
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) throws IOException {
|
||||
CandidateComponentsMetadata metadata = compile(target);
|
||||
assertThat(metadata, hasComponent(target, stereotypes));
|
||||
assertThat(metadata.getItems(), hasSize(1));
|
||||
}
|
||||
|
||||
private CandidateComponentsMetadata compile(Class<?>... types) {
|
||||
private CandidateComponentsMetadata compile(Class<?>... types) throws IOException {
|
||||
CandidateComponentsIndexer processor = new CandidateComponentsIndexer();
|
||||
this.compiler.getTask(types).call(processor);
|
||||
return readGeneratedMetadata(this.compiler.getOutputLocation());
|
||||
}
|
||||
|
||||
private CandidateComponentsMetadata compile(String... types) {
|
||||
private CandidateComponentsMetadata compile(String... types) throws IOException {
|
||||
CandidateComponentsIndexer processor = new CandidateComponentsIndexer();
|
||||
this.compiler.getTask(types).call(processor);
|
||||
return readGeneratedMetadata(this.compiler.getOutputLocation());
|
||||
|
||||
@@ -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.14.Final")
|
||||
testCompile("org.hibernate:hibernate-validator:6.0.13.Final")
|
||||
testCompile("javax.annotation:javax.annotation-api:1.3.2")
|
||||
testRuntime("org.ehcache:jcache:1.0.1")
|
||||
testRuntime("org.ehcache:ehcache:3.4.0")
|
||||
|
||||
+1
-3
@@ -24,7 +24,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.activation.FileTypeMap;
|
||||
import javax.mail.Address;
|
||||
import javax.mail.AuthenticationFailedException;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.NoSuchProviderException;
|
||||
@@ -460,8 +459,7 @@ public class JavaMailSenderImpl implements JavaMailSender {
|
||||
// Preserve explicitly specified message id...
|
||||
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
|
||||
}
|
||||
Address[] addresses = mimeMessage.getAllRecipients();
|
||||
transport.sendMessage(mimeMessage, (addresses != null ? addresses : new Address[0]));
|
||||
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
|
||||
|
||||
+2
-2
@@ -199,8 +199,8 @@ public class JobDetailFactoryBean
|
||||
if (this.applicationContextJobDataKey != null) {
|
||||
if (this.applicationContext == null) {
|
||||
throw new IllegalStateException(
|
||||
"JobDetailBean needs to be set up in an ApplicationContext " +
|
||||
"to be able to handle an 'applicationContextJobDataKey'");
|
||||
"JobDetailBean needs to be set up in an ApplicationContext " +
|
||||
"to be able to handle an 'applicationContextJobDataKey'");
|
||||
}
|
||||
getJobDataMap().put(this.applicationContextJobDataKey, this.applicationContext);
|
||||
}
|
||||
|
||||
-3
@@ -619,9 +619,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.jobFactory = new AdaptableJobFactory();
|
||||
}
|
||||
if (this.jobFactory != null) {
|
||||
if (this.applicationContext != null && this.jobFactory instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) this.jobFactory).setApplicationContext(this.applicationContext);
|
||||
}
|
||||
if (this.jobFactory instanceof SchedulerContextAware) {
|
||||
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
|
||||
}
|
||||
|
||||
+3
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,6 @@ import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyAccessorFactory;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -44,15 +41,11 @@ import org.springframework.lang.Nullable;
|
||||
* @see SchedulerFactoryBean#setJobFactory
|
||||
* @see QuartzJobBean
|
||||
*/
|
||||
public class SpringBeanJobFactory extends AdaptableJobFactory
|
||||
implements ApplicationContextAware, SchedulerContextAware {
|
||||
public class SpringBeanJobFactory extends AdaptableJobFactory implements SchedulerContextAware {
|
||||
|
||||
@Nullable
|
||||
private String[] ignoredUnknownProperties;
|
||||
|
||||
@Nullable
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Nullable
|
||||
private SchedulerContext schedulerContext;
|
||||
|
||||
@@ -69,11 +62,6 @@ public class SpringBeanJobFactory extends AdaptableJobFactory
|
||||
this.ignoredUnknownProperties = ignoredUnknownProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSchedulerContext(SchedulerContext schedulerContext) {
|
||||
this.schedulerContext = schedulerContext;
|
||||
@@ -86,11 +74,7 @@ public class SpringBeanJobFactory extends AdaptableJobFactory
|
||||
*/
|
||||
@Override
|
||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||
Object job = (this.applicationContext != null ?
|
||||
this.applicationContext.getAutowireCapableBeanFactory().createBean(
|
||||
bundle.getJobDetail().getJobClass(), AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false) :
|
||||
super.createJobInstance(bundle));
|
||||
|
||||
Object job = super.createJobInstance(bundle);
|
||||
if (isEligibleForPropertyPopulation(job)) {
|
||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
@@ -111,7 +95,6 @@ public class SpringBeanJobFactory extends AdaptableJobFactory
|
||||
bw.setPropertyValues(pvs, true);
|
||||
}
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,7 +58,7 @@ public class InternetAddressEditorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGoodAddress() {
|
||||
public void simpleGoodAddess() {
|
||||
editor.setAsText(SIMPLE);
|
||||
assertEquals("Simple email address failed", SIMPLE, editor.getAsText());
|
||||
}
|
||||
|
||||
+12
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,7 +56,6 @@ public class JavaMailSenderTests {
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void javaMailSenderWithSimpleMessage() throws MessagingException, IOException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
@@ -69,8 +68,8 @@ public class JavaMailSenderTests {
|
||||
simpleMessage.setFrom("me@mail.org");
|
||||
simpleMessage.setReplyTo("reply@mail.org");
|
||||
simpleMessage.setTo("you@mail.org");
|
||||
simpleMessage.setCc("he@mail.org", "she@mail.org");
|
||||
simpleMessage.setBcc("us@mail.org", "them@mail.org");
|
||||
simpleMessage.setCc(new String[] {"he@mail.org", "she@mail.org"});
|
||||
simpleMessage.setBcc(new String[] {"us@mail.org", "them@mail.org"});
|
||||
Date sentDate = new GregorianCalendar(2004, 1, 1).getTime();
|
||||
simpleMessage.setSentDate(sentDate);
|
||||
simpleMessage.setSubject("my subject");
|
||||
@@ -106,8 +105,7 @@ public class JavaMailSenderTests {
|
||||
assertEquals("my text", sentMessage.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void javaMailSenderWithSimpleMessages() throws MessagingException {
|
||||
public void testJavaMailSenderWithSimpleMessages() throws MessagingException, IOException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -135,8 +133,7 @@ public class JavaMailSenderTests {
|
||||
assertEquals("she@mail.org", ((InternetAddress) tos2.get(0)).getAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void javaMailSenderWithMimeMessage() throws MessagingException {
|
||||
public void testJavaMailSenderWithMimeMessage() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -397,7 +394,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedMailServerConnect() {
|
||||
public void failedMailServerConnect() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost(null);
|
||||
sender.setUsername("username");
|
||||
@@ -418,7 +415,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedMailServerClose() {
|
||||
public void failedMailServerClose() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("");
|
||||
sender.setUsername("username");
|
||||
@@ -437,7 +434,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedSimpleMessage() throws MessagingException {
|
||||
public void failedSimpleMessage() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -469,7 +466,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedMimeMessage() throws MessagingException {
|
||||
public void fFailedMimeMessage() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -501,14 +498,14 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnection() throws MessagingException {
|
||||
public void testConnection() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.testConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionWithFailure() throws MessagingException {
|
||||
public void testConnectionWithFailure() throws Exception {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost(null);
|
||||
|
||||
@@ -595,8 +592,7 @@ public class JavaMailSenderTests {
|
||||
if ("fail".equals(message.getSubject())) {
|
||||
throw new MessagingException("failed");
|
||||
}
|
||||
if (addresses == null || (message.getAllRecipients() == null ? addresses.length > 0 :
|
||||
!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients()))) {
|
||||
if (!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients())) {
|
||||
throw new MessagingException("addresses not correct");
|
||||
}
|
||||
if (message.getSentDate() == null) {
|
||||
|
||||
+3
-55
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -123,17 +122,8 @@ public class MethodValidationTests {
|
||||
@Test
|
||||
public void testLazyValidatorForMethodValidation() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LazyMethodValidationConfig.class, CustomValidatorBean.class,
|
||||
MyValidBean.class, MyValidFactoryBean.class);
|
||||
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
|
||||
MyValidBean.class, MyValidFactoryBean.class);
|
||||
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
|
||||
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class);
|
||||
ctx.getBean(MyValidInterface.class).myValidMethod("value", 5);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,35 +146,6 @@ public class MethodValidationTests {
|
||||
}
|
||||
|
||||
|
||||
@MyStereotype
|
||||
public static class MyValidFactoryBean implements FactoryBean<String>, MyValidInterface<String> {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object myValidMethod(String arg1, int arg2) {
|
||||
return (arg2 == 0 ? null : "value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void myValidAsyncMethod(String arg1, int arg2) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String myGenericMethod(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface MyValidInterface<T> {
|
||||
|
||||
@NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2);
|
||||
@@ -227,17 +188,4 @@ public class MethodValidationTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class LazyMethodValidationConfigWithProxyTargetClass {
|
||||
|
||||
@Bean
|
||||
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setValidator(validator);
|
||||
postProcessor.setProxyTargetClass(true);
|
||||
return postProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -15,21 +15,21 @@ dependencies {
|
||||
optional("javax.interceptor:javax.interceptor-api:1.2.2")
|
||||
optional("javax.money:money-api:1.0.3")
|
||||
optional("javax.validation:validation-api:1.1.0.Final")
|
||||
optional("javax.xml.ws:jaxws-api:2.3.1")
|
||||
optional("javax.xml.ws:jaxws-api:2.3.0")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy:${groovyVersion}")
|
||||
optional("org.beanshell:bsh:2.0b5")
|
||||
optional("joda-time:joda-time:2.10.1")
|
||||
optional("joda-time:joda-time:2.10")
|
||||
optional("org.hibernate:hibernate-validator:5.4.2.Final")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
testCompile("org.codehaus.groovy:groovy-xml:${groovyVersion}")
|
||||
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("javax.inject:javax.inject-tck:1")
|
||||
testCompile("org.awaitility:awaitility:3.1.3")
|
||||
testRuntime("javax.xml.bind:jaxb-api:2.3.1")
|
||||
testCompile("org.awaitility:awaitility:3.1.2")
|
||||
testRuntime("javax.xml.bind:jaxb-api:2.3.0")
|
||||
testRuntime("org.glassfish:javax.el:3.0.1-b08")
|
||||
testRuntime("org.javamoney:moneta:1.3")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ public interface MessageSourceAware extends Aware {
|
||||
* <p>Invoked after population of normal bean properties but before an init
|
||||
* callback like InitializingBean's afterPropertiesSet or a custom init-method.
|
||||
* Invoked before ApplicationContextAware's setApplicationContext.
|
||||
* @param messageSource message source to be used by this object
|
||||
* @param messageSource message sourceto be used by this object
|
||||
*/
|
||||
void setMessageSource(MessageSource messageSource);
|
||||
|
||||
|
||||
+8
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -512,19 +512,13 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
Set<String> autowiredBeanNames;
|
||||
String name = element.name;
|
||||
|
||||
if (factory instanceof AutowireCapableBeanFactory) {
|
||||
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
|
||||
DependencyDescriptor descriptor = element.getDependencyDescriptor();
|
||||
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
|
||||
autowiredBeanNames = new LinkedHashSet<>();
|
||||
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
|
||||
if (resource == null) {
|
||||
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
|
||||
}
|
||||
}
|
||||
else {
|
||||
resource = beanFactory.resolveBeanByName(name, descriptor);
|
||||
autowiredBeanNames = Collections.singleton(name);
|
||||
if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&
|
||||
factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {
|
||||
autowiredBeanNames = new LinkedHashSet<>();
|
||||
resource = ((AutowireCapableBeanFactory) factory).resolveDependency(
|
||||
element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);
|
||||
if (resource == null) {
|
||||
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
-1
@@ -393,7 +393,6 @@ class ConfigurationClassEnhancer {
|
||||
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
|
||||
beanFactory.getBean(beanName));
|
||||
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
|
||||
// Detect package-protected NullBean instance through equals(null) check
|
||||
if (beanInstance.equals(null)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("@Bean method %s.%s called as bean reference " +
|
||||
|
||||
+55
-102
@@ -30,6 +30,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -137,7 +138,8 @@ class ConfigurationClassParser {
|
||||
|
||||
private final ImportStack importStack = new ImportStack();
|
||||
|
||||
private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();
|
||||
@Nullable
|
||||
private List<DeferredImportSelectorHolder> deferredImportSelectors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -160,6 +162,8 @@ class ConfigurationClassParser {
|
||||
|
||||
|
||||
public void parse(Set<BeanDefinitionHolder> configCandidates) {
|
||||
this.deferredImportSelectors = new LinkedList<>();
|
||||
|
||||
for (BeanDefinitionHolder holder : configCandidates) {
|
||||
BeanDefinition bd = holder.getBeanDefinition();
|
||||
try {
|
||||
@@ -182,7 +186,7 @@ class ConfigurationClassParser {
|
||||
}
|
||||
}
|
||||
|
||||
this.deferredImportSelectorHandler.process();
|
||||
processDeferredImportSelectors();
|
||||
}
|
||||
|
||||
protected final void parse(@Nullable String className, String beanName) throws IOException {
|
||||
@@ -539,7 +543,53 @@ class ConfigurationClassParser {
|
||||
}
|
||||
}
|
||||
|
||||
private void processDeferredImportSelectors() {
|
||||
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
|
||||
this.deferredImportSelectors = null;
|
||||
if (deferredImports == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
|
||||
Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
|
||||
Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
|
||||
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
|
||||
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
|
||||
DeferredImportSelectorGrouping grouping = groupings.computeIfAbsent(
|
||||
(group != null ? group : deferredImport),
|
||||
key -> new DeferredImportSelectorGrouping(createGroup(group)));
|
||||
grouping.add(deferredImport);
|
||||
configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
|
||||
deferredImport.getConfigurationClass());
|
||||
}
|
||||
for (DeferredImportSelectorGrouping grouping : groupings.values()) {
|
||||
grouping.getImports().forEach(entry -> {
|
||||
ConfigurationClass configurationClass = configurationClasses.get(entry.getMetadata());
|
||||
try {
|
||||
processImports(configurationClass, asSourceClass(configurationClass),
|
||||
asSourceClasses(entry.getImportClassName()), false);
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanDefinitionStoreException(
|
||||
"Failed to process import candidates for configuration class [" +
|
||||
configurationClass.getMetadata().getClassName() + "]", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private Group createGroup(@Nullable Class<? extends Group> type) {
|
||||
Class<? extends Group> effectiveType = (type != null ? type : DefaultDeferredImportSelectorGroup.class);
|
||||
Group group = BeanUtils.instantiateClass(effectiveType);
|
||||
ParserStrategyUtils.invokeAwareMethods(group,
|
||||
ConfigurationClassParser.this.environment,
|
||||
ConfigurationClassParser.this.resourceLoader,
|
||||
ConfigurationClassParser.this.registry);
|
||||
return group;
|
||||
}
|
||||
|
||||
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
|
||||
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
|
||||
@@ -561,9 +611,9 @@ class ConfigurationClassParser {
|
||||
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
|
||||
ParserStrategyUtils.invokeAwareMethods(
|
||||
selector, this.environment, this.resourceLoader, this.registry);
|
||||
if (selector instanceof DeferredImportSelector) {
|
||||
this.deferredImportSelectorHandler.handle(
|
||||
configClass, (DeferredImportSelector) selector);
|
||||
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
|
||||
this.deferredImportSelectors.add(
|
||||
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
|
||||
}
|
||||
else {
|
||||
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
|
||||
@@ -737,103 +787,6 @@ class ConfigurationClassParser {
|
||||
}
|
||||
|
||||
|
||||
private class DeferredImportSelectorHandler {
|
||||
|
||||
@Nullable
|
||||
private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Handle the specified {@link DeferredImportSelector}. If deferred import
|
||||
* selectors are being collected, this registers this instance to the list. If
|
||||
* they are being processed, the {@link DeferredImportSelector} is also processed
|
||||
* immediately according to its {@link DeferredImportSelector.Group}.
|
||||
* @param configClass the source configuration class
|
||||
* @param importSelector the selector to handle
|
||||
*/
|
||||
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
|
||||
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(
|
||||
configClass, importSelector);
|
||||
if (this.deferredImportSelectors == null) {
|
||||
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
|
||||
handler.register(holder);
|
||||
handler.processGroupImports();
|
||||
}
|
||||
else {
|
||||
this.deferredImportSelectors.add(holder);
|
||||
}
|
||||
}
|
||||
|
||||
public void process() {
|
||||
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
|
||||
this.deferredImportSelectors = null;
|
||||
try {
|
||||
if (deferredImports != null) {
|
||||
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
|
||||
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
|
||||
deferredImports.forEach(handler::register);
|
||||
handler.processGroupImports();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
this.deferredImportSelectors = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class DeferredImportSelectorGroupingHandler {
|
||||
|
||||
private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
|
||||
|
||||
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
|
||||
|
||||
public void register(DeferredImportSelectorHolder deferredImport) {
|
||||
Class<? extends Group> group = deferredImport.getImportSelector()
|
||||
.getImportGroup();
|
||||
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
|
||||
(group != null ? group : deferredImport),
|
||||
key -> new DeferredImportSelectorGrouping(createGroup(group)));
|
||||
grouping.add(deferredImport);
|
||||
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
|
||||
deferredImport.getConfigurationClass());
|
||||
}
|
||||
|
||||
public void processGroupImports() {
|
||||
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
|
||||
grouping.getImports().forEach(entry -> {
|
||||
ConfigurationClass configurationClass = this.configurationClasses.get(
|
||||
entry.getMetadata());
|
||||
try {
|
||||
processImports(configurationClass, asSourceClass(configurationClass),
|
||||
asSourceClasses(entry.getImportClassName()), false);
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanDefinitionStoreException(
|
||||
"Failed to process import candidates for configuration class [" +
|
||||
configurationClass.getMetadata().getClassName() + "]", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private Group createGroup(@Nullable Class<? extends Group> type) {
|
||||
Class<? extends Group> effectiveType = (type != null ? type
|
||||
: DefaultDeferredImportSelectorGroup.class);
|
||||
Group group = BeanUtils.instantiateClass(effectiveType);
|
||||
ParserStrategyUtils.invokeAwareMethods(group,
|
||||
ConfigurationClassParser.this.environment,
|
||||
ConfigurationClassParser.this.resourceLoader,
|
||||
ConfigurationClassParser.this.registry);
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class DeferredImportSelectorHolder {
|
||||
|
||||
private final ConfigurationClass configurationClass;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,12 +28,6 @@ import java.lang.annotation.Target;
|
||||
* does not explicitly depend on another through properties or constructor arguments,
|
||||
* but rather depends on the side effects of another bean's initialization.
|
||||
*
|
||||
* <p>A depends-on declaration can specify both an initialization-time dependency and,
|
||||
* in the case of singleton beans only, a corresponding destruction-time dependency.
|
||||
* Dependent beans that define a depends-on relationship with a given bean are destroyed
|
||||
* first, prior to the given bean itself being destroyed. Thus, a depends-on declaration
|
||||
* can also control shutdown order.
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated
|
||||
* with {@link Bean}.
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* last.
|
||||
*
|
||||
* <p>In certain situations, it may not be possible or practical to tightly control
|
||||
* property source ordering when using {@code @PropertySource} annotations. For example,
|
||||
* property source ordering when using {@code @ProperySource} annotations. For example,
|
||||
* if the {@code @Configuration} classes above were registered via component-scanning,
|
||||
* the ordering is difficult to predict. In such cases - and if overriding is important -
|
||||
* it is recommended that the user fall back to using the programmatic PropertySource API.
|
||||
|
||||
+6
-15
@@ -239,12 +239,7 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
|
||||
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
|
||||
if (retriever != null) {
|
||||
if (beanFactory.isSingleton(listenerBeanName)) {
|
||||
retriever.applicationListeners.add(listener);
|
||||
}
|
||||
else {
|
||||
retriever.applicationListenerBeans.add(listenerBeanName);
|
||||
}
|
||||
retriever.applicationListenerBeans.add(listenerBeanName);
|
||||
}
|
||||
allListeners.add(listener);
|
||||
}
|
||||
@@ -257,10 +252,6 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
}
|
||||
}
|
||||
AnnotationAwareOrderComparator.sort(allListeners);
|
||||
if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
|
||||
retriever.applicationListeners.clear();
|
||||
retriever.applicationListeners.addAll(allListeners);
|
||||
}
|
||||
return allListeners;
|
||||
}
|
||||
|
||||
@@ -365,13 +356,15 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
*/
|
||||
private class ListenerRetriever {
|
||||
|
||||
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
|
||||
public final Set<ApplicationListener<?>> applicationListeners;
|
||||
|
||||
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
|
||||
public final Set<String> applicationListenerBeans;
|
||||
|
||||
private final boolean preFiltered;
|
||||
|
||||
public ListenerRetriever(boolean preFiltered) {
|
||||
this.applicationListeners = new LinkedHashSet<>();
|
||||
this.applicationListenerBeans = new LinkedHashSet<>();
|
||||
this.preFiltered = preFiltered;
|
||||
}
|
||||
|
||||
@@ -394,9 +387,7 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
|
||||
AnnotationAwareOrderComparator.sort(allListeners);
|
||||
}
|
||||
AnnotationAwareOrderComparator.sort(allListeners);
|
||||
return allListeners;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -94,10 +94,11 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(this.targetMethod, EventListener.class);
|
||||
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
|
||||
this.condition = (ann != null ? ann.condition() : null);
|
||||
this.order = resolveOrder(this.targetMethod);
|
||||
this.order = resolveOrder(method);
|
||||
}
|
||||
|
||||
private static List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
|
||||
|
||||
private List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
|
||||
int count = method.getParameterCount();
|
||||
if (count > 1) {
|
||||
throw new IllegalStateException(
|
||||
@@ -122,12 +123,11 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0));
|
||||
}
|
||||
|
||||
private static int resolveOrder(Method method) {
|
||||
private int resolveOrder(Method method) {
|
||||
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class);
|
||||
return (ann != null ? ann.value() : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
@@ -148,7 +148,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
if (declaredEventType.isAssignableFrom(eventType)) {
|
||||
return true;
|
||||
}
|
||||
if (PayloadApplicationEvent.class.isAssignableFrom(eventType.toClass())) {
|
||||
Class<?> eventClass = eventType.getRawClass();
|
||||
if (eventClass != null && PayloadApplicationEvent.class.isAssignableFrom(eventClass)) {
|
||||
ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
|
||||
if (declaredEventType.isAssignableFrom(payloadType)) {
|
||||
return true;
|
||||
@@ -201,7 +202,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
if (this.method.getParameterCount() == 0) {
|
||||
return new Object[0];
|
||||
}
|
||||
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.toClass()) &&
|
||||
Class<?> eventClass = declaredEventType.getRawClass();
|
||||
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
|
||||
event instanceof PayloadApplicationEvent) {
|
||||
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
|
||||
}
|
||||
@@ -356,12 +358,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
}
|
||||
}
|
||||
for (ResolvableType declaredEventType : this.declaredEventTypes) {
|
||||
Class<?> eventClass = declaredEventType.toClass();
|
||||
if (!ApplicationEvent.class.isAssignableFrom(eventClass) &&
|
||||
Class<?> eventClass = declaredEventType.getRawClass();
|
||||
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
|
||||
payloadType != null && declaredEventType.isAssignableFrom(payloadType)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
if (eventClass.isInstance(event)) {
|
||||
if (eventClass != null && eventClass.isInstance(event)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -101,7 +101,7 @@ public class MethodBasedEvaluationContext extends StandardEvaluationContext {
|
||||
}
|
||||
setVariable("a" + i, value);
|
||||
setVariable("p" + i, value);
|
||||
if (paramNames != null && paramNames[i] != null) {
|
||||
if (paramNames != null) {
|
||||
setVariable(paramNames[i], value);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -212,11 +212,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
/** Statically specified listeners. */
|
||||
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
|
||||
|
||||
/** Local listeners registered before refresh. */
|
||||
@Nullable
|
||||
private Set<ApplicationListener<?>> earlyApplicationListeners;
|
||||
|
||||
/** ApplicationEvents published before the multicaster setup. */
|
||||
/** ApplicationEvents published early. */
|
||||
@Nullable
|
||||
private Set<ApplicationEvent> earlyApplicationEvents;
|
||||
|
||||
@@ -487,6 +483,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
this.beanFactoryPostProcessors.add(postProcessor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the list of BeanFactoryPostProcessors that will get applied
|
||||
* to the internal BeanFactory.
|
||||
@@ -501,7 +498,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
if (this.applicationEventMulticaster != null) {
|
||||
this.applicationEventMulticaster.addApplicationListener(listener);
|
||||
}
|
||||
this.applicationListeners.add(listener);
|
||||
else {
|
||||
this.applicationListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -581,7 +580,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
* active flag as well as performing any initialization of property sources.
|
||||
*/
|
||||
protected void prepareRefresh() {
|
||||
// Switch to active.
|
||||
this.startupDate = System.currentTimeMillis();
|
||||
this.closed.set(false);
|
||||
this.active.set(true);
|
||||
@@ -595,23 +593,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize any placeholder property sources in the context environment.
|
||||
// Initialize any placeholder property sources in the context environment
|
||||
initPropertySources();
|
||||
|
||||
// Validate that all properties marked as required are resolvable:
|
||||
// Validate that all properties marked as required are resolvable
|
||||
// see ConfigurablePropertyResolver#setRequiredProperties
|
||||
getEnvironment().validateRequiredProperties();
|
||||
|
||||
// Store pre-refresh ApplicationListeners...
|
||||
if (this.earlyApplicationListeners == null) {
|
||||
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
|
||||
}
|
||||
else {
|
||||
// Reset local application listeners to pre-refresh state.
|
||||
this.applicationListeners.clear();
|
||||
this.applicationListeners.addAll(this.earlyApplicationListeners);
|
||||
}
|
||||
|
||||
// Allow for the collection of early ApplicationEvents,
|
||||
// to be published once the multicaster is available...
|
||||
this.earlyApplicationEvents = new LinkedHashSet<>();
|
||||
@@ -996,7 +984,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
* @see #registerShutdownHook()
|
||||
*/
|
||||
protected void doClose() {
|
||||
// Check whether an actual close attempt is necessary...
|
||||
if (this.active.get() && this.closed.compareAndSet(false, true)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Closing " + this);
|
||||
@@ -1031,13 +1018,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
// Let subclasses do some final clean-up if they wish...
|
||||
onClose();
|
||||
|
||||
// Reset local application listeners to pre-refresh state.
|
||||
if (this.earlyApplicationListeners != null) {
|
||||
this.applicationListeners.clear();
|
||||
this.applicationListeners.addAll(this.earlyApplicationListeners);
|
||||
}
|
||||
|
||||
// Switch to inactive.
|
||||
this.active.set(false);
|
||||
}
|
||||
}
|
||||
@@ -1324,7 +1304,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
@Nullable
|
||||
protected MessageSource getInternalParentMessageSource() {
|
||||
return (getParent() instanceof AbstractApplicationContext ?
|
||||
((AbstractApplicationContext) getParent()).messageSource : getParent());
|
||||
((AbstractApplicationContext) getParent()).messageSource : getParent());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator
|
||||
|
||||
|
||||
/**
|
||||
* Prepares the thread context if necessary, and delegates to
|
||||
* Prepares the thread context if necessar, and delegates to
|
||||
* {@link #invokeInContext}.
|
||||
*/
|
||||
@Override
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
|
||||
* Declares that a field or method parameter should be formatted as a date or time.
|
||||
*
|
||||
* <p>Supports formatting by style pattern, ISO date time pattern, or custom format pattern string.
|
||||
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code Long} (for
|
||||
* millisecond timestamps) as well as JSR-310 <code>java.time</code> and Joda-Time value types.
|
||||
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code java.lang.Long},
|
||||
* Joda-Time value types; and as of Spring 4 and JDK 8, to JSR-310 <code>java.time</code> types too.
|
||||
*
|
||||
* <p>For style-based formatting, set the {@link #style} attribute to be the style pattern code.
|
||||
* The first character of the code is the date style, and the second character is the time style.
|
||||
@@ -48,7 +48,6 @@ import java.lang.annotation.Target;
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.time.format.DateTimeFormatter
|
||||
* @see org.joda.time.format.DateTimeFormat
|
||||
*/
|
||||
@Documented
|
||||
@@ -98,13 +97,13 @@ public @interface DateTimeFormat {
|
||||
DATE,
|
||||
|
||||
/**
|
||||
* The most common ISO Time Format {@code HH:mm:ss.SSSXXX},
|
||||
* The most common ISO Time Format {@code HH:mm:ss.SSSZ},
|
||||
* e.g. "01:30:00.000-05:00".
|
||||
*/
|
||||
TIME,
|
||||
|
||||
/**
|
||||
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX},
|
||||
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSZ},
|
||||
* e.g. "2000-10-31T01:30:00.000-05:00".
|
||||
* <p>This is the default if no annotation value is specified.
|
||||
*/
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,8 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Declares that a field or method parameter should be formatted as a number.
|
||||
*
|
||||
* <p>Supports formatting by style or custom pattern string. Can be applied
|
||||
* to any JDK {@code Number} type such as {@code Double} and {@code Long}.
|
||||
* <p>Supports formatting by style or custom pattern string.
|
||||
* Can be applied to any JDK {@code java.lang.Number} type.
|
||||
*
|
||||
* <p>For style-based formatting, set the {@link #style} attribute to be the
|
||||
* desired {@link Style}. For custom formatting, set the {@link #pattern}
|
||||
|
||||
+4
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,6 @@ import org.springframework.util.ReflectionUtils;
|
||||
* Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
|
||||
*
|
||||
* <p>As of Spring Framework 5.0, this weaver supports WildFly 8+.
|
||||
* As of Spring Framework 5.1.5, it also supports WildFly 13+.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
@@ -43,9 +42,6 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||
private static final String DELEGATING_TRANSFORMER_CLASS_NAME =
|
||||
"org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
|
||||
|
||||
private static final String WRAPPER_TRANSFORMER_CLASS_NAME =
|
||||
"org.jboss.modules.JLIClassTransformer";
|
||||
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
@@ -80,23 +76,12 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||
}
|
||||
transformer.setAccessible(true);
|
||||
|
||||
Object suggestedTransformer = transformer.get(classLoader);
|
||||
if (suggestedTransformer.getClass().getName().equals(WRAPPER_TRANSFORMER_CLASS_NAME)) {
|
||||
Field wrappedTransformer = ReflectionUtils.findField(suggestedTransformer.getClass(), "transformer");
|
||||
if (wrappedTransformer == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not find 'transformer' field on JBoss JLIClassTransformer: " +
|
||||
suggestedTransformer.getClass().getName());
|
||||
}
|
||||
wrappedTransformer.setAccessible(true);
|
||||
suggestedTransformer = wrappedTransformer.get(suggestedTransformer);
|
||||
}
|
||||
if (!suggestedTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
|
||||
this.delegatingTransformer = transformer.get(classLoader);
|
||||
if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
|
||||
throw new IllegalStateException(
|
||||
"Transformer not of the expected type DelegatingClassFileTransformer: " +
|
||||
suggestedTransformer.getClass().getName());
|
||||
this.delegatingTransformer.getClass().getName());
|
||||
}
|
||||
this.delegatingTransformer = suggestedTransformer;
|
||||
|
||||
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
|
||||
"addTransformer", ClassFileTransformer.class);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import javax.management.ObjectName;
|
||||
* accessed by application developers during application runtime.
|
||||
*
|
||||
* <p>This interface should be used to export application resources to JMX using Spring's
|
||||
* management interface generation capabilities and, optionally, it's {@link ObjectName}
|
||||
* management interface generation capabilties and, optionally, it's {@link ObjectName}
|
||||
* generation capabilities.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
|
||||
@@ -509,7 +509,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
/**
|
||||
* Register the defined beans with the {@link MBeanServer}.
|
||||
* <p>Each bean is exposed to the {@code MBeanServer} via a
|
||||
* {@code ModelMBean}. The actual implementation of the
|
||||
* {@code ModelMBean}. The actual implemetation of the
|
||||
* {@code ModelMBean} interface used depends on the implementation of
|
||||
* the {@code ModelMBeanProvider} interface that is configured. By
|
||||
* default the {@code RequiredModelMBean} class that is supplied with
|
||||
@@ -939,9 +939,9 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
* {@link org.springframework.jmx.export.notification.NotificationPublisher} is injected.
|
||||
*/
|
||||
private void injectNotificationPublisherIfNecessary(
|
||||
Object managedResource, @Nullable ModelMBean modelMBean, @Nullable ObjectName objectName) {
|
||||
Object managedResource, ModelMBean modelMBean, ObjectName objectName) {
|
||||
|
||||
if (managedResource instanceof NotificationPublisherAware && modelMBean != null && objectName != null) {
|
||||
if (managedResource instanceof NotificationPublisherAware) {
|
||||
((NotificationPublisherAware) managedResource).setNotificationPublisher(
|
||||
new ModelMBeanNotificationPublisher(modelMBean, objectName, managedResource));
|
||||
}
|
||||
@@ -1112,6 +1112,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
|
||||
@Override
|
||||
protected void postProcessTargetObject(Object targetObject) {
|
||||
Assert.state(this.modelMBean != null && this.objectName != null, "Not initialized");
|
||||
injectNotificationPublisherIfNecessary(targetObject, this.modelMBean, this.objectName);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,7 +84,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
|
||||
* The property key should match the bean key and the property value should match
|
||||
* the list of method names. When searching for method names for a bean, Spring
|
||||
* will check these mappings first.
|
||||
* @param mappings the mappings of bean keys to method names
|
||||
* @param mappings the mappins of bean keys to method names
|
||||
*/
|
||||
public void setMethodMappings(Properties mappings) {
|
||||
this.methodMappings = new HashMap<>();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,7 @@ import javax.management.Notification;
|
||||
* implementing the {@link NotificationPublisherAware} interface. After a particular
|
||||
* managed resource instance is registered with the {@link javax.management.MBeanServer},
|
||||
* Spring will inject a {@code NotificationPublisher} instance into it if that
|
||||
* resource implements the {@link NotificationPublisherAware} interface.
|
||||
* resource implements the {@link NotificationPublisherAware} inteface.
|
||||
*
|
||||
* <p>Each managed resource instance will have a distinct instance of a
|
||||
* {@code NotificationPublisher} implementation. This instance will keep
|
||||
|
||||
+1
-2
@@ -170,12 +170,11 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
|
||||
try {
|
||||
if (this.threaded) {
|
||||
// Start the connector server asynchronously (in a separate thread).
|
||||
final JMXConnectorServer serverToStart = this.connectorServer;
|
||||
Thread connectorThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
serverToStart.start();
|
||||
connectorServer.start();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new JmxException("Could not start JMX connector server after delay", ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -103,7 +103,7 @@ public abstract class JndiObjectLocator extends JndiLocatorSupport implements In
|
||||
* Perform the actual JNDI lookup for this locator's target resource.
|
||||
* @return the located target object
|
||||
* @throws NamingException if the JNDI lookup failed or if the
|
||||
* located JNDI object is not assignable to the expected type
|
||||
* located JNDI object is not assigable to the expected type
|
||||
* @see #setJndiName
|
||||
* @see #setExpectedType
|
||||
* @see #lookup(String, Class)
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ import org.springframework.core.Ordered;
|
||||
*
|
||||
* @Override
|
||||
* public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
||||
* return new MyAsyncUncaughtExceptionHandler();
|
||||
* return MyAsyncUncaughtExceptionHandler();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,7 +41,6 @@ import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.support.FormatterPropertyEditorAdapter;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -701,14 +700,6 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
return getTypeConverter().convertIfNecessary(value, requiredType, field);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
|
||||
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
|
||||
|
||||
return getTypeConverter().convertIfNecessary(value, requiredType, typeDescriptor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind the given property values to this binder's target.
|
||||
|
||||
@@ -71,7 +71,6 @@ public abstract class ValidationUtils {
|
||||
Validator validator, Object target, Errors errors, @Nullable Object... validationHints) {
|
||||
|
||||
Assert.notNull(validator, "Validator must not be null");
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
Assert.notNull(errors, "Errors object must not be null");
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
+1
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,6 @@ import javax.validation.executable.ExecutableValidator;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -88,11 +86,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())) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
Class<?>[] groups = determineValidationGroups(invocation);
|
||||
|
||||
// Standard Bean Validation 1.1 API
|
||||
@@ -126,27 +119,6 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private boolean isFactoryBeanMetadataMethod(Method method) {
|
||||
Class<?> clazz = method.getDeclaringClass();
|
||||
|
||||
// Call from interface-based proxy handle, allowing for an efficient check?
|
||||
if (clazz.isInterface()) {
|
||||
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
|
||||
!method.getName().equals("getObject"));
|
||||
}
|
||||
|
||||
// Call from CGLIB proxy handle, potentially implementing a FactoryBean method?
|
||||
Class<?> factoryBeanType = null;
|
||||
if (SmartFactoryBean.class.isAssignableFrom(clazz)) {
|
||||
factoryBeanType = SmartFactoryBean.class;
|
||||
}
|
||||
else if (FactoryBean.class.isAssignableFrom(clazz)) {
|
||||
factoryBeanType = FactoryBean.class;
|
||||
}
|
||||
return (factoryBeanType != null && !method.getName().equals("getObject") &&
|
||||
ClassUtils.hasMethod(factoryBeanType, method.getName(), method.getParameterTypes()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the validation groups to validate against for the given method invocation.
|
||||
* <p>Default are the validation groups as specified in the {@link Validated} annotation
|
||||
|
||||
+3
-14
@@ -16,10 +16,8 @@
|
||||
|
||||
package org.springframework.context.support
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider
|
||||
import org.springframework.beans.factory.config.BeanDefinition
|
||||
import org.springframework.beans.factory.config.BeanDefinitionCustomizer
|
||||
import org.springframework.beans.factory.getBeanProvider
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils
|
||||
import org.springframework.context.ApplicationContextInitializer
|
||||
import org.springframework.core.env.ConfigurableEnvironment
|
||||
@@ -83,10 +81,10 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit,
|
||||
internal val children = arrayListOf<BeanDefinitionDsl>()
|
||||
|
||||
/**
|
||||
* @see provider
|
||||
* Access to the context for advanced use-cases.
|
||||
* @since 5.1
|
||||
*/
|
||||
@PublishedApi
|
||||
internal lateinit var context: GenericApplicationContext
|
||||
lateinit var context: GenericApplicationContext
|
||||
|
||||
/**
|
||||
* Shortcut for `context.environment`
|
||||
@@ -247,15 +245,6 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit,
|
||||
else -> context.getBean(name, T::class.java)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* @since 5.1.1
|
||||
* @see org.springframework.beans.factory.BeanFactory.getBeanProvider
|
||||
*/
|
||||
inline fun <reified T : Any> provider() : ObjectProvider<T> = context.getBeanProvider()
|
||||
|
||||
/**
|
||||
* Take in account bean definitions enclosed in the provided lambda only when the
|
||||
* specified profile is active.
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ public class OverloadedAdviceTests {
|
||||
Throwable cause = ex.getRootCause();
|
||||
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
|
||||
assertTrue("invalidAbsoluteTypeName should be detected by AJ",
|
||||
cause.getMessage().contains("invalidAbsoluteTypeName"));
|
||||
cause.getMessage().indexOf("invalidAbsoluteTypeName") != -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class OverloadedAdviceTests {
|
||||
Throwable cause = ex.getRootCause();
|
||||
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
|
||||
assertTrue("Cannot resolve method 'myBeforeAdvice' to a unique method",
|
||||
cause.getMessage().contains("Cannot resolve method 'myBeforeAdvice' to a unique method"));
|
||||
cause.getMessage().indexOf("Cannot resolve method 'myBeforeAdvice' to a unique method") != -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class AtAspectJAnnotationBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointcutEvaluatedAgainstArray() {
|
||||
public void testPointcutEvaulatedAgainstArray() {
|
||||
ctx.getBean("arrayFactoryBean");
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user