mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
307 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45eb23bd21 | |||
| d703ca95d7 | |||
| 106a757098 | |||
| 8637540678 | |||
| 5bb1c3e1e3 | |||
| 2a0a002bd3 | |||
| 514f7e3328 | |||
| cdd0456aa4 | |||
| 9f03d158ce | |||
| ba0c48b933 | |||
| 82dbde13b6 | |||
| a698adf125 | |||
| 50e4308779 | |||
| 07bac70c09 | |||
| cc740dfd93 | |||
| 15af0d9787 | |||
| 2b974da395 | |||
| e7c038f2d2 | |||
| b8e663c531 | |||
| 0f73a69033 | |||
| e9626779ee | |||
| 5f4c461d4f | |||
| ef8652615c | |||
| d1e5a3af9f | |||
| 9895e44d73 | |||
| 643a68f81b | |||
| ac4525ddf8 | |||
| 17caac8f1f | |||
| 165d2511b9 | |||
| d27bae245a | |||
| 0ebc020b21 | |||
| 59a9c8e004 | |||
| ca7634dfe8 | |||
| 5eca512c46 | |||
| 99da6e9723 | |||
| 1241c3b2d1 | |||
| 7c62d7cfe2 | |||
| 6507b09c7f | |||
| 229f354df1 | |||
| 43ea25e413 | |||
| 4560dc2818 | |||
| d0033f12d0 | |||
| 85ec9b9df2 | |||
| 4732f83d70 | |||
| 7cc700435b | |||
| 493e9c1ff0 | |||
| edadb9efb6 | |||
| 810b615471 | |||
| 51f9e0aaca | |||
| d6aa589c50 | |||
| fc6cff53bb | |||
| 20f4022e7b | |||
| 020c537c03 | |||
| e373b46660 | |||
| 5dcde9e7d7 | |||
| ef72ef54fa | |||
| a77eee899a | |||
| 9837ec5904 | |||
| bdac937a43 | |||
| 6ca3884759 | |||
| 189e1afc6e | |||
| d1862a26dd | |||
| 2b65d0e51f | |||
| 86fb43900e | |||
| e1e6224acb | |||
| cf565067fe | |||
| 2159518252 | |||
| 754ad4d0d3 | |||
| 72dddfbc7b | |||
| dc3f953f4b | |||
| 4058361e84 | |||
| 952045c216 | |||
| 815f151448 | |||
| 605e2477b9 | |||
| 304c85ec70 | |||
| f56fa91430 | |||
| 9cb5369cb9 | |||
| a82f049083 | |||
| b219c6ce15 | |||
| 17a4193810 | |||
| 29ab38acb2 | |||
| 4938dab0ae | |||
| b94e8c4bef | |||
| abc68ef8ea | |||
| d37a18ff03 | |||
| 11976fa949 | |||
| 6e3f974951 | |||
| 1faeeaea14 | |||
| dc2535516c | |||
| 673a20cb10 | |||
| f52f3a2f35 | |||
| 77129f5a2b | |||
| d289befa2b | |||
| b802c28d27 | |||
| 556656b35a | |||
| 74630a1b0c | |||
| 63984800e4 | |||
| 4b24bcb799 | |||
| 1cb9f2c7b2 | |||
| 72fbbb2403 | |||
| d459e1ad61 | |||
| 78a6429c32 | |||
| bd6432cb79 | |||
| fced4e1f9c | |||
| 56d93bac89 | |||
| 8d1de75b60 | |||
| b2756f5bd2 | |||
| 31a24720a6 | |||
| 7a7958f275 | |||
| ca9c34710f | |||
| 9cbd585c30 | |||
| a218bf40cd | |||
| 93e7a0a59d | |||
| b83ceab88a | |||
| c15bbd675f | |||
| 5a8b8b11e4 | |||
| a00be62b04 | |||
| 4955d08f28 | |||
| 6361b0cb23 | |||
| 5e4a8966ee | |||
| 09da10cc6c | |||
| 44f39d4ce0 | |||
| 1d593a970a | |||
| e42cf9dc56 | |||
| 65cb935333 | |||
| 0e8ed5931d | |||
| a240cfcf2f | |||
| 199be6aec5 | |||
| 99da8e1477 | |||
| 2f04cbba51 | |||
| fc9d1760be | |||
| aab421167b | |||
| 112cc70231 | |||
| 93189a6733 | |||
| 81d77b9872 | |||
| ee95a110bd | |||
| c48672c4c7 | |||
| ef72baad3a | |||
| 14e87d2733 | |||
| 388ce92861 | |||
| 38ae282c3b | |||
| 05d616240a | |||
| 8eef97da33 | |||
| 270099383b | |||
| 0ad35053fb | |||
| 058608021e | |||
| 106ae0cc5b | |||
| 7b7a8196f5 | |||
| 2c98c1b81a | |||
| 7b9c30f26e | |||
| 474ac2d975 | |||
| 6eb0a60df9 | |||
| 5bbbc82e19 | |||
| 4b4503085a | |||
| 73a96c5152 | |||
| 9a13d93a6b | |||
| 894044cea0 | |||
| 0550c08f86 | |||
| 073f304db9 | |||
| 58a99e3983 | |||
| 62f2a6352f | |||
| 528b9c17ec | |||
| 31318652ea | |||
| f15bd88211 | |||
| 220951707b | |||
| 18ac86ae16 | |||
| 3258ac1ec4 | |||
| 54f5b7d0ee | |||
| aaaf81ed99 | |||
| 6a012147c4 | |||
| 9abd4ed33d | |||
| cf7ee0739f | |||
| db63f7dd4a | |||
| 7a5f8e03bc | |||
| 50e5bdb813 | |||
| 9efea7eb73 | |||
| d3cdecc621 | |||
| c024bdcc6f | |||
| 6d7827e36b | |||
| d5dab12909 | |||
| 7854b7ac40 | |||
| 26b1c848b8 | |||
| 5e153e4a77 | |||
| 16e9b83d43 | |||
| 516c01c438 | |||
| 43077072ad | |||
| 0841dc5f99 | |||
| 15f8863f19 | |||
| bc3b95db92 | |||
| 66f822e600 | |||
| dfc193b85e | |||
| 029101c79a | |||
| 3eee118b44 | |||
| 959cf61647 | |||
| 82eb82a040 | |||
| 80b8382f00 | |||
| ebbe14c363 | |||
| c2e545776d | |||
| 97ac1c22c5 | |||
| a528407d0c | |||
| 58cde3c2e6 | |||
| fedbb09ad9 | |||
| 81fde5ec41 | |||
| aa7f69a5d1 | |||
| 91de8d265e | |||
| 77ab88b144 | |||
| 738097def2 | |||
| b90553db5c | |||
| 56234fe877 | |||
| c16f36b537 | |||
| ae8f680d2e | |||
| bf272b0b21 | |||
| b1b28d4641 | |||
| 17b2b8af86 | |||
| 262c702da4 | |||
| 548126ddd8 | |||
| 7e9857a663 | |||
| 0134c9d608 | |||
| 5fe628a811 | |||
| 759013eb17 | |||
| a55ca56e34 | |||
| d6a5c3428b | |||
| 24848ec1bc | |||
| fef0e21d8b | |||
| 8c7579eba8 | |||
| a3d763d137 | |||
| 2a5d7690b6 | |||
| f5aeb81473 | |||
| 02d3cfa42d | |||
| 12f168290d | |||
| 88cb126511 | |||
| f3c29fe2e6 | |||
| abf9ce8a34 | |||
| 63275ae2b7 | |||
| 3203d39821 | |||
| ce5c65c0b0 | |||
| afa38f5f97 | |||
| 7b6f2f8fb3 | |||
| bfb49c7249 | |||
| 729ce4108d | |||
| 1a37345e84 | |||
| c89e6c616a | |||
| 539cfc24c6 | |||
| 39ce989d1a | |||
| 0f2d9df79f | |||
| b9603680bc | |||
| 7bbd4c681f | |||
| ba3fef3e8a | |||
| f4b05dc2e7 | |||
| 46a5fb7a91 | |||
| 093254b2b3 | |||
| 9f857c1f16 | |||
| 75b1396768 | |||
| 4182935b7a | |||
| 445b76bbe8 | |||
| 3bab3515b1 | |||
| 0c0de851f4 | |||
| e31914bada | |||
| 40148c0560 | |||
| 3a66927bd2 | |||
| c58da71006 | |||
| 818c2aa3b9 | |||
| d96a7b4bfc | |||
| b3aad549c9 | |||
| 865f1f692a | |||
| 93df24af16 | |||
| a5339d71ea | |||
| e4c84ec757 | |||
| f5da737bd4 | |||
| c187cb2fa1 | |||
| ed1d63dcc3 | |||
| e26ae9853e | |||
| 362c59c310 | |||
| b6e8674700 | |||
| db8a94ce5f | |||
| 3232825a55 | |||
| e71ff2901a | |||
| d9c1811d21 | |||
| 5e7a8b275d | |||
| ea3250c8d6 | |||
| b1f5f51503 | |||
| 2ce03f34d9 | |||
| 9280e32d5d | |||
| 5cd525a2b0 | |||
| 2ac4355ec0 | |||
| a3cd7af72d | |||
| 6a9f91081e | |||
| f65408f646 | |||
| 59fa647e2d | |||
| 0a7dcf14f9 | |||
| 86846507e2 | |||
| 133b8b0b5a | |||
| dc8f6f7177 | |||
| c2b55e60cd | |||
| 48654c6483 | |||
| 47aec50917 | |||
| 6f36514369 | |||
| 9da9bb9652 | |||
| 3f42e16172 | |||
| 7c36549e3a | |||
| 991e9f4269 | |||
| 2a41067a17 | |||
| 42a95b8f35 | |||
| 76d203fc61 | |||
| 9fc7bfde99 | |||
| a999c4aa7e | |||
| a82d726f76 |
+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
|
||||
[JIRA issue tracker](https://jira.spring.io/browse/SPR), using a few different keywords.
|
||||
[Github issue tracker](https://github.com/spring-projects/spring-framework/issues), 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 [JIRA issue tracker](https://jira.spring.io/browse/SPR).
|
||||
When ready create a ticket in the [Github issue tracker](https://github.com/spring-projects/spring-framework/issues).
|
||||
|
||||
#### 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 JIRA issue tracker as the preferred place of record for conversations and
|
||||
We use the GitHub 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 JIRA issue (e.g. `SPR-1234`), or
|
||||
1. Use short branch names, preferably based on the GitHub issue (e.g. `22276`), 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 related issues, e.g. `Issues: SPR-1234, SPR-1235`.
|
||||
description, followed by the issue fixed, e.g. `Fixes #22276`.
|
||||
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 JIRA issue number in the PR description.
|
||||
1. List the GitHub 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,48 +1,30 @@
|
||||
# <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). Together the Spring Framework and the family of Spring projects make up what we call "Spring".
|
||||
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".
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## 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.
|
||||
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 of conduct. 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 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.
|
||||
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.
|
||||
|
||||
## Build from Source
|
||||
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
|
||||
wiki page and also [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
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.
|
||||
|
||||
## 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).
|
||||
|
||||
+22
-18
@@ -19,7 +19,7 @@ plugins {
|
||||
ext {
|
||||
linkHomepage = "https://projects.spring.io/spring-framework"
|
||||
linkCi = "https://build.spring.io/browse/SPR"
|
||||
linkIssue = "https://jira.spring.io/browse/SPR"
|
||||
linkIssue = "https://github.com/spring-projects/spring-framework/issues"
|
||||
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"
|
||||
@@ -30,22 +30,22 @@ ext {
|
||||
|
||||
aspectjVersion = "1.9.2"
|
||||
freemarkerVersion = "2.3.28"
|
||||
groovyVersion = "2.5.3"
|
||||
groovyVersion = "2.5.6"
|
||||
hsqldbVersion = "2.4.1"
|
||||
jackson2Version = "2.9.7"
|
||||
jettyVersion = "9.4.12.v20180830"
|
||||
junit5Version = "5.3.1"
|
||||
jackson2Version = "2.9.8"
|
||||
jettyVersion = "9.4.14.v20181114"
|
||||
junit5Version = "5.3.2"
|
||||
kotlinVersion = "1.2.71"
|
||||
log4jVersion = "2.11.1"
|
||||
nettyVersion = "4.1.30.Final"
|
||||
reactorVersion = "Californium-SR2"
|
||||
log4jVersion = "2.11.2"
|
||||
nettyVersion = "4.1.33.Final"
|
||||
reactorVersion = "Californium-SR5"
|
||||
rxjavaVersion = "1.3.8"
|
||||
rxjavaAdapterVersion = "1.2.1"
|
||||
rxjava2Version = "2.2.3"
|
||||
rxjava2Version = "2.2.6"
|
||||
slf4jVersion = "1.7.25" // spring-jcl + consistent 3rd party deps
|
||||
tiles3Version = "3.0.8"
|
||||
tomcatVersion = "9.0.12"
|
||||
undertowVersion = "2.0.14.Final"
|
||||
tomcatVersion = "9.0.16"
|
||||
undertowVersion = "2.0.17.Final"
|
||||
|
||||
gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
withoutJclOverSlf4J = {
|
||||
@@ -132,6 +132,7 @@ 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
|
||||
@@ -142,19 +143,20 @@ configure(allprojects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.14"
|
||||
toolVersion = "8.17"
|
||||
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.23.0") {
|
||||
testCompile("org.mockito:mockito-core:2.24.0") {
|
||||
exclude group: "org.hamcrest", module: "hamcrest-core"
|
||||
}
|
||||
testCompile("com.nhaarman:mockito-kotlin:1.6.0") {
|
||||
@@ -185,10 +187,12 @@ 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.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/"
|
||||
"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/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
@@ -276,7 +280,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.16.Final")
|
||||
testCompile("org.hibernate:hibernate-core:5.1.17.Final")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=5.1.2.BUILD-SNAPSHOT
|
||||
version=5.1.5.RELEASE
|
||||
|
||||
@@ -52,8 +52,8 @@ def customizePom(pom, gradleProject) {
|
||||
}
|
||||
}
|
||||
issueManagement {
|
||||
system = "Jira"
|
||||
url = "https://jira.springsource.org/browse/SPR"
|
||||
system = "GitHub"
|
||||
url = "https://github.com/spring-projects/spring-framework/issues"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-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 constuctor, given to an
|
||||
* Description of an invocation to a constructor, 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 frienly implementation of the
|
||||
* <p>This method is a friendly 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 userAtributes map for the current joinpoint.
|
||||
* Key used in ReflectiveMethodInvocation userAttributes map for the current joinpoint.
|
||||
*/
|
||||
protected static final String JOIN_POINT_KEY = JoinPoint.class.getName();
|
||||
|
||||
|
||||
+1
-9
@@ -272,15 +272,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AmbiguousBindingException ambigEx) {
|
||||
if (this.raiseExceptions) {
|
||||
throw ambigEx;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
catch (AmbiguousBindingException | IllegalArgumentException ex) {
|
||||
if (this.raiseExceptions) {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
@@ -723,17 +723,20 @@ 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);
|
||||
this.methodProxy = methodProxy;
|
||||
this.publicMethod = Modifier.isPublic(method.getModifiers());
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -742,7 +745,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.publicMethod && getMethod().getDeclaringClass() != Object.class) {
|
||||
if (this.methodProxy != null) {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
else {
|
||||
@@ -795,7 +798,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* <dt>For advised methods:</dt>
|
||||
* <dd>If the target is static and the advice chain is frozen then a
|
||||
* FixedChainStaticTargetInterceptor specific to the method is used to
|
||||
* invoke the advice chain. Otherwise a DyanmicAdvisedInterceptor is
|
||||
* invoke the advice chain. Otherwise a DynamicAdvisedInterceptor is
|
||||
* used.</dd>
|
||||
* <dt>For non-advised methods:</dt>
|
||||
* <dd>Where it can be determined that the method will not return {@code this}
|
||||
|
||||
+4
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -133,7 +133,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
|
||||
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
|
||||
|
||||
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
|
||||
|
||||
@@ -236,9 +236,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
}
|
||||
this.earlyProxyReferences.put(cacheKey, bean);
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
|
||||
@@ -297,7 +295,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.contains(cacheKey)) {
|
||||
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
|
||||
/**
|
||||
* The {@code $[targetClassName]} placeholder.
|
||||
* Replaced with the fully-qualifed name of the {@code Class}
|
||||
* Replaced with the fully-qualified 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-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -77,8 +77,7 @@ 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 suported in Around as it is in Pointcut
|
||||
// argNames should be supported 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 MutableModifable extends Modifiable {
|
||||
public interface MutableModifiable extends Modifiable {
|
||||
|
||||
void markDirty();
|
||||
}
|
||||
|
||||
public static class ModifiableImpl implements MutableModifable {
|
||||
public static class ModifiableImpl implements MutableModifiable {
|
||||
|
||||
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, MutableModifable mixin, Object newValue) {
|
||||
JoinPoint jp, MutableModifiable 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 MutableModifable mixin;
|
||||
public static MutableModifiable mixin;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -157,7 +157,7 @@ public class DelegatingIntroductionInterceptorTests {
|
||||
TimeStamped ts = (TimeStamped) pf.getProxy();
|
||||
|
||||
assertThat(ts, instanceOf(TimeStamped.class));
|
||||
// Shoulnd't proxy framework interfaces
|
||||
// Shouldn'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().indexOf("null") != -1);
|
||||
assertTrue(ex.getMessage().contains("null"));
|
||||
}
|
||||
|
||||
// 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{36} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %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{36} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -166,7 +166,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a lazily initializted CachedIntrospectionResults instance
|
||||
* Obtain a lazily initialized CachedIntrospectionResults instance
|
||||
* for the wrapped object.
|
||||
*/
|
||||
private CachedIntrospectionResults getCachedIntrospectionResults() {
|
||||
|
||||
@@ -314,6 +314,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getPropertyType() {
|
||||
if (this.propertyType == null) {
|
||||
try {
|
||||
@@ -425,6 +426,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getPropertyType() {
|
||||
if (this.propertyType == null) {
|
||||
try {
|
||||
@@ -460,6 +462,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getIndexedPropertyType() {
|
||||
if (this.indexedPropertyType == null) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -93,4 +94,27 @@ 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-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,6 @@ 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;
|
||||
@@ -82,42 +81,6 @@ 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-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ 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;
|
||||
|
||||
@@ -41,15 +42,16 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType) throws TypeMismatchException {
|
||||
return doConvert(value, requiredType, null, null);
|
||||
return convertIfNecessary(value, requiredType, TypeDescriptor.valueOf(requiredType));
|
||||
}
|
||||
|
||||
@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 doConvert(value, requiredType, methodParam, null);
|
||||
return convertIfNecessary(value, requiredType,
|
||||
(methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,21 +59,18 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
|
||||
throws TypeMismatchException {
|
||||
|
||||
return doConvert(value, requiredType, null, field);
|
||||
return convertIfNecessary(value, requiredType,
|
||||
(field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T> T doConvert(@Nullable Object value,@Nullable Class<T> requiredType,
|
||||
@Nullable MethodParameter methodParam, @Nullable Field field) throws TypeMismatchException {
|
||||
@Override
|
||||
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
|
||||
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
|
||||
|
||||
Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
|
||||
try {
|
||||
if (field != null) {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
|
||||
}
|
||||
else {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
|
||||
}
|
||||
return this.typeConverterDelegate.convertIfNecessary(null, null, value, requiredType, typeDescriptor);
|
||||
}
|
||||
catch (ConverterNotFoundException | IllegalStateException ex) {
|
||||
throw new ConversionNotSupportedException(value, requiredType, ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -133,8 +133,7 @@ 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 definition
|
||||
* with the specified name
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
|
||||
* @throws BeansException if the bean could not be obtained
|
||||
*/
|
||||
Object getBean(String name) throws BeansException;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,8 @@ 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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
|
||||
* "#{systemProperties.myProp}" style expressions.
|
||||
* {@code #{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: e.g. "#{systemProperties.myProp}".
|
||||
* The actual value expression: for example {@code #{systemProperties.myProp}}.
|
||||
*/
|
||||
String value();
|
||||
|
||||
|
||||
+22
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -289,7 +289,8 @@ 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 new bean instance
|
||||
* @param existingBean the existing bean instance
|
||||
* @param beanName the name of the bean, to be passed to it if necessary
|
||||
* (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)
|
||||
@@ -305,7 +306,8 @@ 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 new bean instance
|
||||
* @param existingBean the existing bean instance
|
||||
* @param beanName the name of the bean, to be passed to it if necessary
|
||||
* (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)
|
||||
@@ -337,8 +339,7 @@ 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.
|
||||
* {@code null} is disallowed.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @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
|
||||
@@ -348,6 +349,22 @@ 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)
|
||||
|
||||
+21
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,6 +38,7 @@ 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;
|
||||
|
||||
@@ -77,6 +78,9 @@ 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.
|
||||
@@ -301,7 +305,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ResolvableType object for the wrapped parameter/field.
|
||||
* Build a {@link ResolvableType} object for the wrapped parameter/field.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ResolvableType getResolvableType() {
|
||||
@@ -315,6 +319,21 @@ 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
|
||||
|
||||
+12
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,32 +28,26 @@ 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 Environment} and
|
||||
* {@link org.springframework.core.env.PropertySource PropertySource} mechanisms also made available in Spring 3.1.
|
||||
* 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.
|
||||
*
|
||||
* <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
|
||||
@@ -92,7 +86,6 @@ 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 {
|
||||
@@ -124,14 +117,9 @@ 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 java.lang.System#getProperty(String)
|
||||
* @see java.lang.System#getenv(String)
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public void setSearchSystemEnvironment(boolean searchSystemEnvironment) {
|
||||
this.searchSystemEnvironment = searchSystemEnvironment;
|
||||
|
||||
+24
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,6 +58,7 @@ 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;
|
||||
@@ -337,12 +338,6 @@ 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
|
||||
@@ -446,6 +441,28 @@ 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
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
+37
-10
@@ -510,12 +510,21 @@ 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) &&
|
||||
typeToMatch.isAssignableFrom(targetType)) {
|
||||
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
|
||||
// Check raw class match as well, making sure it's exposed on the proxy.
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
return (classToMatch == null || classToMatch.isInstance(beanInstance));
|
||||
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
|
||||
return false;
|
||||
}
|
||||
if (typeToMatch.isAssignableFrom(targetType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ResolvableType resolvableType = mbd.targetType;
|
||||
if (resolvableType == null) {
|
||||
resolvableType = mbd.factoryMethodReturnType;
|
||||
}
|
||||
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1362,6 +1371,7 @@ 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();
|
||||
@@ -1391,13 +1401,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
throws ClassNotFoundException {
|
||||
|
||||
ClassLoader beanClassLoader = getBeanClassLoader();
|
||||
ClassLoader classLoaderToUse = beanClassLoader;
|
||||
ClassLoader dynamicLoader = beanClassLoader;
|
||||
boolean freshResolve = false;
|
||||
|
||||
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) {
|
||||
classLoaderToUse = tempClassLoader;
|
||||
dynamicLoader = tempClassLoader;
|
||||
freshResolve = true;
|
||||
if (tempClassLoader instanceof DecoratingClassLoader) {
|
||||
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
|
||||
for (Class<?> typeToMatch : typesToMatch) {
|
||||
@@ -1406,6 +1419,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String className = mbd.getBeanClassName();
|
||||
if (className != null) {
|
||||
Object evaluated = evaluateBeanDefinitionString(className, mbd);
|
||||
@@ -1415,18 +1429,31 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return (Class<?>) evaluated;
|
||||
}
|
||||
else if (evaluated instanceof String) {
|
||||
return ClassUtils.forName((String) evaluated, classLoaderToUse);
|
||||
className = (String) evaluated;
|
||||
freshResolve = true;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve regularly, caching the result in the BeanDefinition...
|
||||
return mbd.resolveBeanClass(beanClassLoader);
|
||||
}
|
||||
|
||||
|
||||
+18
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ 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;
|
||||
@@ -28,6 +29,7 @@ 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;
|
||||
@@ -49,6 +51,18 @@ 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,
|
||||
@@ -57,16 +71,7 @@ abstract class AutowireUtils {
|
||||
* @param constructors the constructor array to sort
|
||||
*/
|
||||
public static void sortConstructors(Constructor<?>[] constructors) {
|
||||
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));
|
||||
});
|
||||
Arrays.sort(constructors, EXECUTABLE_COMPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,16 +82,7 @@ abstract class AutowireUtils {
|
||||
* @param factoryMethods the factory method array to sort
|
||||
*/
|
||||
public static void sortFactoryMethods(Method[] factoryMethods) {
|
||||
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));
|
||||
});
|
||||
Arrays.sort(factoryMethods, EXECUTABLE_COMPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +154,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 creatProxy()} and an {@code Object[]} array containing
|
||||
* method for {@code createProxy()} 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 depency check mode for this definition.
|
||||
* Set the dependency 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 objectto wrap
|
||||
* @param beanDefinition the BeanDefinition object to wrap
|
||||
*/
|
||||
public BeanDefinitionResource(BeanDefinition beanDefinition) {
|
||||
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
|
||||
|
||||
+6
-4
@@ -196,7 +196,7 @@ class ConstructorResolver {
|
||||
for (Constructor<?> candidate : candidates) {
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
|
||||
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
|
||||
if (constructorToUse != null && argsToUse != 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,11 +276,12 @@ class ConstructorResolver {
|
||||
ambiguousConstructors);
|
||||
}
|
||||
|
||||
if (explicitArgs == null) {
|
||||
if (explicitArgs == null && argsHolderToUse != null) {
|
||||
argsHolderToUse.storeCache(mbd, constructorToUse);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.state(argsToUse != null, "Unresolved constructor arguments");
|
||||
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
|
||||
return bw;
|
||||
}
|
||||
@@ -602,12 +603,13 @@ class ConstructorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
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, Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
private Object instantiate(String beanName, RootBeanDefinition mbd,
|
||||
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
|
||||
+26
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -677,7 +677,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (bd instanceof AbstractBeanDefinition) {
|
||||
AbstractBeanDefinition abd = (AbstractBeanDefinition) bd;
|
||||
if (abd.hasBeanClass()) {
|
||||
ann = AnnotationUtils.findAnnotation(abd.getBeanClass(), annotationType);
|
||||
Class<?> beanClass = abd.getBeanClass();
|
||||
if (beanClass != beanType) {
|
||||
ann = AnnotationUtils.findAnnotation(beanClass, annotationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1093,8 +1096,6 @@ 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) {
|
||||
@@ -1111,7 +1112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
if (candidateNames.length == 1) {
|
||||
String beanName = candidateNames[0];
|
||||
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, clazz, args));
|
||||
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
|
||||
}
|
||||
else if (candidateNames.length > 1) {
|
||||
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
|
||||
@@ -1124,14 +1125,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
candidates.put(beanName, getType(beanName));
|
||||
}
|
||||
}
|
||||
String candidateName = determinePrimaryCandidate(candidates, clazz);
|
||||
String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
|
||||
if (candidateName == null) {
|
||||
candidateName = determineHighestPriorityCandidate(candidates, clazz);
|
||||
candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
|
||||
}
|
||||
if (candidateName != null) {
|
||||
Object beanInstance = candidates.get(candidateName);
|
||||
if (beanInstance == null || beanInstance instanceof Class) {
|
||||
beanInstance = getBean(candidateName, clazz, args);
|
||||
beanInstance = getBean(candidateName, requiredType.toClass(), args);
|
||||
}
|
||||
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
|
||||
}
|
||||
@@ -1185,13 +1186,20 @@ 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());
|
||||
return (descriptor.getField() != null ?
|
||||
converter.convertIfNecessary(value, type, descriptor.getField()) :
|
||||
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
|
||||
@@ -1689,7 +1697,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
super.resolveCandidate(beanName, requiredType, beanFactory));
|
||||
}
|
||||
};
|
||||
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
|
||||
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
|
||||
return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
|
||||
}
|
||||
|
||||
|
||||
@@ -1750,7 +1759,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
// Lenient fallback: dummy factory in case of original factory not found...
|
||||
return new DefaultListableBeanFactory();
|
||||
DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory();
|
||||
dummyFactory.serializationId = this.id;
|
||||
return dummyFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1915,8 +1926,7 @@ 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);
|
||||
Assert.state(result instanceof Stream, "Stream expected");
|
||||
return (Stream<Object>) result;
|
||||
return (result instanceof Stream ? (Stream<Object>) result : Stream.of(result));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -82,9 +82,10 @@ 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 (!method.getParameterTypes()[i].getName().contains(identifier)) {
|
||||
if (!parameterTypes[i].getName().contains(identifier)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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 (DEFAULT_VALUE.equals(lazyInit)) {
|
||||
if (isDefaultValue(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 (DEFAULT_VALUE.equals(merge)) {
|
||||
if (isDefaultValue(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 (DEFAULT_VALUE.equals(autowire)) {
|
||||
if (isDefaultValue(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 (DEFAULT_VALUE.equals(lazyInit)) {
|
||||
if (isDefaultValue(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 ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
|
||||
if (isDefaultValue(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 (DEFAULT_VALUE.equals(att)) {
|
||||
if (isDefaultValue(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 (DEFAULT_VALUE.equals(value)) {
|
||||
if (isDefaultValue(value)) {
|
||||
value = this.defaults.getMerge();
|
||||
}
|
||||
return TRUE_VALUE.equals(value);
|
||||
@@ -1481,6 +1481,10 @@ 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())));
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class BeanWrapperGenericsTests {
|
||||
fail("Should have thrown TypeMismatchException");
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("java.lang.Integer") != -1);
|
||||
assertTrue(ex.getMessage().contains("java.lang.Integer"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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("Vaid set property must stick", target.getName().equals(newName));
|
||||
assertTrue("Valid 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-2015 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ public class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void withShadowedField() throws Exception {
|
||||
public void withShadowedField() {
|
||||
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().indexOf("TestServiceLocator3") != -1);
|
||||
assertTrue(factory.toString().contains("TestServiceLocator3"));
|
||||
}
|
||||
|
||||
@Ignore @Test // worked when using an ApplicationContext (see commented), fails when using BeanFactory
|
||||
|
||||
+47
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,21 @@ 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");
|
||||
@@ -61,6 +76,22 @@ 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"));
|
||||
@@ -84,6 +115,21 @@ 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{36} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
+28
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,87 +84,86 @@ public class CandidateComponentsIndexerTests {
|
||||
this.compiler = new TestCompiler(this.temporaryFolder);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void noCandidate() throws IOException {
|
||||
public void noCandidate() {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNone.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noAnnotation() throws IOException {
|
||||
public void noAnnotation() {
|
||||
CandidateComponentsMetadata metadata = compile(CandidateComponentsIndexerTests.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeComponent() throws IOException {
|
||||
public void stereotypeComponent() {
|
||||
testComponent(SampleComponent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeService() throws IOException {
|
||||
public void stereotypeService() {
|
||||
testComponent(SampleService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeController() throws IOException {
|
||||
public void stereotypeController() {
|
||||
testComponent(SampleController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeControllerMetaAnnotation() throws IOException {
|
||||
public void stereotypeControllerMetaAnnotation() {
|
||||
testComponent(SampleMetaController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeRepository() throws IOException {
|
||||
public void stereotypeRepository() {
|
||||
testSingleComponent(SampleRepository.class, Component.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeControllerMetaIndex() throws IOException {
|
||||
public void stereotypeControllerMetaIndex() {
|
||||
testSingleComponent(SampleMetaIndexedController.class,
|
||||
Component.class, MetaControllerIndexed.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stereotypeOnAbstractClass() throws IOException {
|
||||
public void stereotypeOnAbstractClass() {
|
||||
testComponent(AbstractController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cdiManagedBean() throws IOException {
|
||||
public void cdiManagedBean() {
|
||||
testSingleComponent(SampleManagedBean.class, ManagedBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cdiNamed() throws IOException {
|
||||
public void cdiNamed() {
|
||||
testSingleComponent(SampleNamed.class, Named.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceEntity() throws IOException {
|
||||
public void persistenceEntity() {
|
||||
testSingleComponent(SampleEntity.class, Entity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceMappedSuperClass() throws IOException {
|
||||
public void persistenceMappedSuperClass() {
|
||||
testSingleComponent(SampleMappedSuperClass.class, MappedSuperclass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceEmbeddable() throws IOException {
|
||||
public void persistenceEmbeddable() {
|
||||
testSingleComponent(SampleEmbeddable.class, Embeddable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceConverter() throws IOException {
|
||||
public void persistenceConverter() {
|
||||
testSingleComponent(SampleConverter.class, Converter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void packageInfo() throws IOException {
|
||||
public void packageInfo() {
|
||||
CandidateComponentsMetadata metadata = compile(
|
||||
"org/springframework/context/index/sample/jpa/package-info");
|
||||
assertThat(metadata, hasComponent(
|
||||
@@ -172,32 +171,32 @@ public class CandidateComponentsIndexerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromMetaInterface() throws IOException {
|
||||
public void typeStereotypeFromMetaInterface() {
|
||||
testSingleComponent(SampleSpecializedRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromInterfaceFromSuperClass() throws IOException {
|
||||
public void typeStereotypeFromInterfaceFromSuperClass() {
|
||||
testSingleComponent(SampleRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeFromSeveralInterfaces() throws IOException {
|
||||
public void typeStereotypeFromSeveralInterfaces() {
|
||||
testSingleComponent(SampleSmartRepo.class, Repo.class, SmartRepo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnInterface() throws IOException {
|
||||
public void typeStereotypeOnInterface() {
|
||||
testSingleComponent(SpecializedRepo.class, Repo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnInterfaceFromSeveralInterfaces() throws IOException {
|
||||
public void typeStereotypeOnInterfaceFromSeveralInterfaces() {
|
||||
testSingleComponent(SmartRepo.class, Repo.class, SmartRepo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeStereotypeOnIndexedInterface() throws IOException {
|
||||
public void typeStereotypeOnIndexedInterface() {
|
||||
testSingleComponent(Repo.class, Repo.class);
|
||||
}
|
||||
|
||||
@@ -217,12 +216,12 @@ public class CandidateComponentsIndexerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedNonStaticCandidateAreIgnored() throws IOException {
|
||||
public void embeddedNonStaticCandidateAreIgnored() {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNonStaticEmbedded.class);
|
||||
assertThat(metadata.getItems(), hasSize(0));
|
||||
}
|
||||
|
||||
private void testComponent(Class<?>... classes) throws IOException {
|
||||
private void testComponent(Class<?>... classes) {
|
||||
CandidateComponentsMetadata metadata = compile(classes);
|
||||
for (Class<?> c : classes) {
|
||||
assertThat(metadata, hasComponent(c, Component.class));
|
||||
@@ -230,19 +229,19 @@ public class CandidateComponentsIndexerTests {
|
||||
assertThat(metadata.getItems(), hasSize(classes.length));
|
||||
}
|
||||
|
||||
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) throws IOException {
|
||||
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) {
|
||||
CandidateComponentsMetadata metadata = compile(target);
|
||||
assertThat(metadata, hasComponent(target, stereotypes));
|
||||
assertThat(metadata.getItems(), hasSize(1));
|
||||
}
|
||||
|
||||
private CandidateComponentsMetadata compile(Class<?>... types) throws IOException {
|
||||
private CandidateComponentsMetadata compile(Class<?>... types) {
|
||||
CandidateComponentsIndexer processor = new CandidateComponentsIndexer();
|
||||
this.compiler.getTask(types).call(processor);
|
||||
return readGeneratedMetadata(this.compiler.getOutputLocation());
|
||||
}
|
||||
|
||||
private CandidateComponentsMetadata compile(String... types) throws IOException {
|
||||
private CandidateComponentsMetadata compile(String... types) {
|
||||
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.13.Final")
|
||||
testCompile("org.hibernate:hibernate-validator:6.0.14.Final")
|
||||
testCompile("javax.annotation:javax.annotation-api:1.3.2")
|
||||
testRuntime("org.ehcache:jcache:1.0.1")
|
||||
testRuntime("org.ehcache:ehcache:3.4.0")
|
||||
|
||||
+3
-1
@@ -24,6 +24,7 @@ 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;
|
||||
@@ -459,7 +460,8 @@ public class JavaMailSenderImpl implements JavaMailSender {
|
||||
// Preserve explicitly specified message id...
|
||||
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
|
||||
}
|
||||
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
|
||||
Address[] addresses = mimeMessage.getAllRecipients();
|
||||
transport.sendMessage(mimeMessage, (addresses != null ? addresses : new Address[0]));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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,7 @@ public class InternetAddressEditorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGoodAddess() {
|
||||
public void simpleGoodAddress() {
|
||||
editor.setAsText(SIMPLE);
|
||||
assertEquals("Simple email address failed", SIMPLE, editor.getAsText());
|
||||
}
|
||||
|
||||
+16
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,6 +56,7 @@ public class JavaMailSenderTests {
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void javaMailSenderWithSimpleMessage() throws MessagingException, IOException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
@@ -68,8 +69,8 @@ public class JavaMailSenderTests {
|
||||
simpleMessage.setFrom("me@mail.org");
|
||||
simpleMessage.setReplyTo("reply@mail.org");
|
||||
simpleMessage.setTo("you@mail.org");
|
||||
simpleMessage.setCc(new String[] {"he@mail.org", "she@mail.org"});
|
||||
simpleMessage.setBcc(new String[] {"us@mail.org", "them@mail.org"});
|
||||
simpleMessage.setCc("he@mail.org", "she@mail.org");
|
||||
simpleMessage.setBcc("us@mail.org", "them@mail.org");
|
||||
Date sentDate = new GregorianCalendar(2004, 1, 1).getTime();
|
||||
simpleMessage.setSentDate(sentDate);
|
||||
simpleMessage.setSubject("my subject");
|
||||
@@ -105,7 +106,8 @@ public class JavaMailSenderTests {
|
||||
assertEquals("my text", sentMessage.getContent());
|
||||
}
|
||||
|
||||
public void testJavaMailSenderWithSimpleMessages() throws MessagingException, IOException {
|
||||
@Test
|
||||
public void javaMailSenderWithSimpleMessages() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -133,7 +135,8 @@ public class JavaMailSenderTests {
|
||||
assertEquals("she@mail.org", ((InternetAddress) tos2.get(0)).getAddress());
|
||||
}
|
||||
|
||||
public void testJavaMailSenderWithMimeMessage() throws MessagingException {
|
||||
@Test
|
||||
public void javaMailSenderWithMimeMessage() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -394,7 +397,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedMailServerConnect() throws Exception {
|
||||
public void failedMailServerConnect() {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost(null);
|
||||
sender.setUsername("username");
|
||||
@@ -415,7 +418,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedMailServerClose() throws Exception {
|
||||
public void failedMailServerClose() {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("");
|
||||
sender.setUsername("username");
|
||||
@@ -434,7 +437,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedSimpleMessage() throws Exception {
|
||||
public void failedSimpleMessage() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -466,7 +469,7 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fFailedMimeMessage() throws Exception {
|
||||
public void failedMimeMessage() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.setUsername("username");
|
||||
@@ -498,14 +501,14 @@ public class JavaMailSenderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnection() throws Exception {
|
||||
public void testConnection() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost("host");
|
||||
sender.testConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionWithFailure() throws Exception {
|
||||
public void testConnectionWithFailure() throws MessagingException {
|
||||
MockJavaMailSender sender = new MockJavaMailSender();
|
||||
sender.setHost(null);
|
||||
|
||||
@@ -592,7 +595,8 @@ public class JavaMailSenderTests {
|
||||
if ("fail".equals(message.getSubject())) {
|
||||
throw new MessagingException("failed");
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients())) {
|
||||
if (addresses == null || (message.getAllRecipients() == null ? addresses.length > 0 :
|
||||
!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients()))) {
|
||||
throw new MessagingException("addresses not correct");
|
||||
}
|
||||
if (message.getSentDate() == null) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %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.0")
|
||||
optional("javax.xml.ws:jaxws-api:2.3.1")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy:${groovyVersion}")
|
||||
optional("org.beanshell:bsh:2.0b5")
|
||||
optional("joda-time:joda-time:2.10")
|
||||
optional("joda-time:joda-time:2.10.1")
|
||||
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.2")
|
||||
testRuntime("javax.xml.bind:jaxb-api:2.3.0")
|
||||
testCompile("org.awaitility:awaitility:3.1.3")
|
||||
testRuntime("javax.xml.bind:jaxb-api:2.3.1")
|
||||
testRuntime("org.glassfish:javax.el:3.0.1-b08")
|
||||
testRuntime("org.javamoney:moneta:1.3")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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,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 sourceto be used by this object
|
||||
* @param messageSource message source to be used by this object
|
||||
*/
|
||||
void setMessageSource(MessageSource messageSource);
|
||||
|
||||
|
||||
+14
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -512,13 +512,19 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
Set<String> autowiredBeanNames;
|
||||
String name = element.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");
|
||||
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);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+1
@@ -393,6 +393,7 @@ 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 " +
|
||||
|
||||
+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 @ProperySource} annotations. For example,
|
||||
* property source ordering when using {@code @PropertySource} annotations. For example,
|
||||
* if the {@code @Configuration} classes above were registered via component-scanning,
|
||||
* the ordering is difficult to predict. In such cases - and if overriding is important -
|
||||
* it is recommended that the user fall back to using the programmatic PropertySource API.
|
||||
|
||||
+10
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -94,11 +94,10 @@ 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(method);
|
||||
this.order = resolveOrder(this.targetMethod);
|
||||
}
|
||||
|
||||
|
||||
private List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
|
||||
private static List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
|
||||
int count = method.getParameterCount();
|
||||
if (count > 1) {
|
||||
throw new IllegalStateException(
|
||||
@@ -123,11 +122,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0));
|
||||
}
|
||||
|
||||
private int resolveOrder(Method method) {
|
||||
private static int resolveOrder(Method method) {
|
||||
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class);
|
||||
return (ann != null ? ann.value() : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
@@ -148,8 +148,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
if (declaredEventType.isAssignableFrom(eventType)) {
|
||||
return true;
|
||||
}
|
||||
Class<?> eventClass = eventType.getRawClass();
|
||||
if (eventClass != null && PayloadApplicationEvent.class.isAssignableFrom(eventClass)) {
|
||||
if (PayloadApplicationEvent.class.isAssignableFrom(eventType.toClass())) {
|
||||
ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
|
||||
if (declaredEventType.isAssignableFrom(payloadType)) {
|
||||
return true;
|
||||
@@ -202,8 +201,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
if (this.method.getParameterCount() == 0) {
|
||||
return new Object[0];
|
||||
}
|
||||
Class<?> eventClass = declaredEventType.getRawClass();
|
||||
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
|
||||
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.toClass()) &&
|
||||
event instanceof PayloadApplicationEvent) {
|
||||
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
|
||||
}
|
||||
@@ -358,12 +356,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
}
|
||||
}
|
||||
for (ResolvableType declaredEventType : this.declaredEventTypes) {
|
||||
Class<?> eventClass = declaredEventType.getRawClass();
|
||||
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
|
||||
Class<?> eventClass = declaredEventType.toClass();
|
||||
if (!ApplicationEvent.class.isAssignableFrom(eventClass) &&
|
||||
payloadType != null && declaredEventType.isAssignableFrom(payloadType)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
if (eventClass != null && eventClass.isInstance(event)) {
|
||||
if (eventClass.isInstance(event)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -101,7 +101,7 @@ public class MethodBasedEvaluationContext extends StandardEvaluationContext {
|
||||
}
|
||||
setVariable("a" + i, value);
|
||||
setVariable("p" + i, value);
|
||||
if (paramNames != null) {
|
||||
if (paramNames != null && paramNames[i] != null) {
|
||||
setVariable(paramNames[i], value);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -212,7 +212,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
/** Statically specified listeners. */
|
||||
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
|
||||
|
||||
/** ApplicationEvents published early. */
|
||||
/** Local listeners registered before refresh. */
|
||||
@Nullable
|
||||
private Set<ApplicationListener<?>> earlyApplicationListeners;
|
||||
|
||||
/** ApplicationEvents published before the multicaster setup. */
|
||||
@Nullable
|
||||
private Set<ApplicationEvent> earlyApplicationEvents;
|
||||
|
||||
@@ -483,7 +487,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
this.beanFactoryPostProcessors.add(postProcessor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the list of BeanFactoryPostProcessors that will get applied
|
||||
* to the internal BeanFactory.
|
||||
@@ -578,6 +581,7 @@ 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);
|
||||
@@ -591,13 +595,23 @@ 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<>();
|
||||
@@ -982,6 +996,7 @@ 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);
|
||||
@@ -1016,6 +1031,13 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -1302,7 +1324,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 necessar, and delegates to
|
||||
* Prepares the thread context if necessary, and delegates to
|
||||
* {@link #invokeInContext}.
|
||||
*/
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -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 java.lang.Long},
|
||||
* Joda-Time value types; and as of Spring 4 and JDK 8, to JSR-310 <code>java.time</code> types too.
|
||||
* 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.
|
||||
*
|
||||
* <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,6 +48,7 @@ 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
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -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 java.lang.Number} type.
|
||||
* <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>For style-based formatting, set the {@link #style} attribute to be the
|
||||
* desired {@link Style}. For custom formatting, set the {@link #pattern}
|
||||
|
||||
+19
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,6 +32,7 @@ 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
|
||||
@@ -42,6 +43,9 @@ 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;
|
||||
|
||||
@@ -76,12 +80,23 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||
}
|
||||
transformer.setAccessible(true);
|
||||
|
||||
this.delegatingTransformer = transformer.get(classLoader);
|
||||
if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
|
||||
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)) {
|
||||
throw new IllegalStateException(
|
||||
"Transformer not of the expected type DelegatingClassFileTransformer: " +
|
||||
this.delegatingTransformer.getClass().getName());
|
||||
suggestedTransformer.getClass().getName());
|
||||
}
|
||||
this.delegatingTransformer = suggestedTransformer;
|
||||
|
||||
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
|
||||
"addTransformer", ClassFileTransformer.class);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -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 capabilties and, optionally, it's {@link ObjectName}
|
||||
* management interface generation capabilities 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 implemetation of the
|
||||
* {@code ModelMBean}. The actual implementation 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, ModelMBean modelMBean, ObjectName objectName) {
|
||||
Object managedResource, @Nullable ModelMBean modelMBean, @Nullable ObjectName objectName) {
|
||||
|
||||
if (managedResource instanceof NotificationPublisherAware) {
|
||||
if (managedResource instanceof NotificationPublisherAware && modelMBean != null && objectName != null) {
|
||||
((NotificationPublisherAware) managedResource).setNotificationPublisher(
|
||||
new ModelMBeanNotificationPublisher(modelMBean, objectName, managedResource));
|
||||
}
|
||||
@@ -1112,7 +1112,6 @@ 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-2017 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,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 mappins of bean keys to method names
|
||||
* @param mappings the mappings of bean keys to method names
|
||||
*/
|
||||
public void setMethodMappings(Properties mappings) {
|
||||
this.methodMappings = new HashMap<>();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -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} inteface.
|
||||
* resource implements the {@link NotificationPublisherAware} interface.
|
||||
*
|
||||
* <p>Each managed resource instance will have a distinct instance of a
|
||||
* {@code NotificationPublisher} implementation. This instance will keep
|
||||
|
||||
+2
-1
@@ -170,11 +170,12 @@ 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 {
|
||||
connectorServer.start();
|
||||
serverToStart.start();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new JmxException("Could not start JMX connector server after delay", ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -103,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 assigable to the expected type
|
||||
* located JNDI object is not assignable 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 MyAsyncUncaughtExceptionHandler();
|
||||
* return new MyAsyncUncaughtExceptionHandler();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,7 @@ 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;
|
||||
@@ -700,6 +701,14 @@ 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,6 +71,7 @@ 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()) {
|
||||
|
||||
+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().indexOf("invalidAbsoluteTypeName") != -1);
|
||||
cause.getMessage().contains("invalidAbsoluteTypeName"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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().indexOf("Cannot resolve method 'myBeforeAdvice' to a unique method") != -1);
|
||||
cause.getMessage().contains("Cannot resolve method 'myBeforeAdvice' to a unique method"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class AtAspectJAnnotationBindingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointcutEvaulatedAgainstArray() {
|
||||
public void testPointcutEvaluatedAgainstArray() {
|
||||
ctx.getBean("arrayFactoryBean");
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -365,7 +365,7 @@ public abstract class AbstractAopProxyTests {
|
||||
assertEquals("Only one invocation via AOP as use of this wasn't proxied", 1, di.getCount());
|
||||
// 1 invocation
|
||||
assertEquals("Increment happened", 1, proxied.getCount());
|
||||
proxied.incrementViaProxy(); // 2 invoocations
|
||||
proxied.incrementViaProxy(); // 2 invocations
|
||||
assertEquals("Increment happened", 2, target.getCount());
|
||||
assertEquals("3 more invocations via AOP as the first call was reentrant through the proxy", 4, di.getCount());
|
||||
}
|
||||
@@ -511,7 +511,7 @@ public abstract class AbstractAopProxyTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUndeclaredUnheckedException() throws Throwable {
|
||||
public void testUndeclaredUncheckedException() throws Throwable {
|
||||
final RuntimeException unexpectedException = new RuntimeException();
|
||||
// Test return value
|
||||
MethodInterceptor mi = new MethodInterceptor() {
|
||||
@@ -736,7 +736,7 @@ public abstract class AbstractAopProxyTests {
|
||||
fail("Shouldn't be able to add introduction interceptor except via introduction advice");
|
||||
}
|
||||
catch (AopConfigException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("ntroduction") > -1);
|
||||
assertTrue(ex.getMessage().contains("ntroduction"));
|
||||
}
|
||||
// Check it still works: proxy factory state shouldn't have been corrupted
|
||||
ITestBean proxied = (ITestBean) createProxy(pc);
|
||||
@@ -786,7 +786,7 @@ public abstract class AbstractAopProxyTests {
|
||||
|
||||
/**
|
||||
* Note that an introduction can't throw an unexpected checked exception,
|
||||
* as it's constained by the interface.
|
||||
* as it's constrained by the interface.
|
||||
*/
|
||||
@Test
|
||||
public void testIntroductionThrowsUncheckedException() throws Throwable {
|
||||
@@ -849,7 +849,7 @@ public abstract class AbstractAopProxyTests {
|
||||
fail("Shouldn't be able to add interceptor when frozen");
|
||||
}
|
||||
catch (AopConfigException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("frozen") > -1);
|
||||
assertTrue(ex.getMessage().contains("frozen"));
|
||||
}
|
||||
// Check it still works: proxy factory state shouldn't have been corrupted
|
||||
assertEquals(target.getAge(), proxied.getAge());
|
||||
|
||||
@@ -74,6 +74,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNullConfig() {
|
||||
new CglibAopProxy(null);
|
||||
@@ -153,6 +154,20 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringInvocation() {
|
||||
PrivateCglibTestBean bean = new PrivateCglibTestBean();
|
||||
bean.setName("Rob Harrop");
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTarget(bean);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
|
||||
PrivateCglibTestBean proxy = (PrivateCglibTestBean) aop.getProxy();
|
||||
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnadvisedProxyCreationWithCallDuringConstructor() {
|
||||
CglibTestBean target = new CglibTestBean();
|
||||
@@ -480,6 +495,29 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PrivateCglibTestBean {
|
||||
|
||||
private String name;
|
||||
|
||||
public PrivateCglibTestBean() {
|
||||
setName("Some Default");
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -498,6 +536,11 @@ class CglibTestBean {
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,6 @@ import java.io.Serializable;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
||||
@@ -60,7 +59,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyIsJustInterface() throws Throwable {
|
||||
public void testProxyIsJustInterface() {
|
||||
TestBean raw = new TestBean();
|
||||
raw.setAge(32);
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
@@ -73,7 +72,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterceptorIsInvokedWithNoTarget() throws Throwable {
|
||||
public void testInterceptorIsInvokedWithNoTarget() {
|
||||
// Test return value
|
||||
final int age = 25;
|
||||
MethodInterceptor mi = (invocation -> age);
|
||||
@@ -87,7 +86,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetCanGetInvocationWithPrivateClass() throws Throwable {
|
||||
public void testTargetCanGetInvocationWithPrivateClass() {
|
||||
final ExposedInvocationTestBean expectedTarget = new ExposedInvocationTestBean() {
|
||||
@Override
|
||||
protected void assertions(MethodInvocation invocation) {
|
||||
@@ -128,7 +127,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsAndHashCodeDefined() throws Exception {
|
||||
public void testEqualsAndHashCodeDefined() {
|
||||
AdvisedSupport as = new AdvisedSupport(Named.class);
|
||||
as.setTarget(new Person());
|
||||
JdkDynamicAopProxy aopProxy = new JdkDynamicAopProxy(as);
|
||||
@@ -139,7 +138,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
|
||||
@Test // SPR-13328
|
||||
public void testVarargsWithEnumArray() throws Exception {
|
||||
public void testVarargsWithEnumArray() {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(new VarargTestBean());
|
||||
VarargTestInterface proxy = (VarargTestInterface) proxyFactory.getProxy();
|
||||
assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C));
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public class ProxyFactoryBeanTests {
|
||||
catch (BeanCreationException ex) {
|
||||
// Root cause of the problem must be an AOP exception
|
||||
AopConfigException aex = (AopConfigException) ex.getCause();
|
||||
assertTrue(aex.getMessage().indexOf("TargetSource") != -1);
|
||||
assertTrue(aex.getMessage().contains("TargetSource"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -161,7 +161,7 @@ public class CommonsPool2TargetSourceTests {
|
||||
// desired
|
||||
}
|
||||
|
||||
// lets now release an object and try to accquire a new one
|
||||
// lets now release an object and try to acquire a new one
|
||||
targetSource.releaseTarget(pooledInstances[9]);
|
||||
pooledInstances[9] = targetSource.getTarget();
|
||||
|
||||
@@ -194,7 +194,7 @@ public class CommonsPool2TargetSourceTests {
|
||||
// desired
|
||||
}
|
||||
|
||||
// lets now release an object and try to accquire a new one
|
||||
// lets now release an object and try to acquire a new one
|
||||
targetSource.releaseTarget(pooledInstances[9]);
|
||||
pooledInstances[9] = targetSource.getTarget();
|
||||
|
||||
|
||||
+8
-8
@@ -482,7 +482,7 @@ public class XmlBeanFactoryTests {
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
// check exception message contains the name
|
||||
assertTrue(ex.getMessage().indexOf("bogusParent") != -1);
|
||||
assertTrue(ex.getMessage().contains("bogusParent"));
|
||||
assertTrue(ex.getCause() instanceof NoSuchBeanDefinitionException);
|
||||
}
|
||||
}
|
||||
@@ -678,7 +678,7 @@ public class XmlBeanFactoryTests {
|
||||
fail();
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getResourceDescription().indexOf("initializers.xml") != -1);
|
||||
assertTrue(ex.getResourceDescription().contains("initializers.xml"));
|
||||
assertEquals("init-method2", ex.getBeanName());
|
||||
assertTrue(ex.getCause() instanceof IOException);
|
||||
}
|
||||
@@ -694,9 +694,9 @@ public class XmlBeanFactoryTests {
|
||||
}
|
||||
catch (FatalBeanException ex) {
|
||||
// check message is helpful
|
||||
assertTrue(ex.getMessage().indexOf("initializers.xml") != -1);
|
||||
assertTrue(ex.getMessage().indexOf("init-method3") != -1);
|
||||
assertTrue(ex.getMessage().indexOf("init") != -1);
|
||||
assertTrue(ex.getMessage().contains("initializers.xml"));
|
||||
assertTrue(ex.getMessage().contains("init-method3"));
|
||||
assertTrue(ex.getMessage().contains("init"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +934,7 @@ public class XmlBeanFactoryTests {
|
||||
xbf.getBean("rod2Accessor");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertTrue(ex.toString().indexOf("touchy") != -1);
|
||||
assertTrue(ex.toString().contains("touchy"));
|
||||
ex.printStackTrace();
|
||||
assertNull(ex.getRelatedCauses());
|
||||
}
|
||||
@@ -1115,7 +1115,7 @@ public class XmlBeanFactoryTests {
|
||||
fail("Must have thrown a CannotLoadBeanClassException");
|
||||
}
|
||||
catch (CannotLoadBeanClassException ex) {
|
||||
assertTrue(ex.getResourceDescription().indexOf("classNotFound.xml") != -1);
|
||||
assertTrue(ex.getResourceDescription().contains("classNotFound.xml"));
|
||||
assertTrue(ex.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
@@ -1367,7 +1367,7 @@ public class XmlBeanFactoryTests {
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
// Check that the bogus method name was included in the error message
|
||||
assertTrue("Bogus method name correctly reported", ex.getMessage().indexOf("bogusMethod") != -1);
|
||||
assertTrue("Bogus method name correctly reported", ex.getMessage().contains("bogusMethod"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class BeanThatBroadcasts implements ApplicationContextAware {
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
if (applicationContext.getDisplayName().indexOf("listener") != -1) {
|
||||
if (applicationContext.getDisplayName().contains("listener")) {
|
||||
applicationContext.getBean("listener");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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,7 @@ public class LifecycleContextBean extends LifecycleBean implements ApplicationCo
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
if (this.owningContext == null)
|
||||
throw new RuntimeException("Factory didn't call setAppliationContext before afterPropertiesSet on lifecycle bean");
|
||||
throw new RuntimeException("Factory didn't call setApplicationContext before afterPropertiesSet on lifecycle bean");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -33,7 +33,7 @@ public class ComponentScanAnnotationTests {
|
||||
|
||||
@Test
|
||||
public void noop() {
|
||||
// no-op; the @ComponentScan-annotated MyConfig class below simply excercises
|
||||
// no-op; the @ComponentScan-annotated MyConfig class below simply exercises
|
||||
// available attributes of the annotation.
|
||||
}
|
||||
}
|
||||
|
||||
+191
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -184,6 +184,20 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertSupportForComposedAnnotationWithExclude(beanDefinition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingReflection() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(
|
||||
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class);
|
||||
assertSupportForComposedAnnotationWithExclude(beanDefinition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingAsm() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(
|
||||
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class.getName());
|
||||
assertSupportForComposedAnnotationWithExclude(beanDefinition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingReflection() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(
|
||||
@@ -571,6 +585,10 @@ public class ConfigurationClassPostProcessorTests {
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -585,6 +603,78 @@ public class ConfigurationClassPostProcessorTests {
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawFactoryMethod() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(0, beanNames.length);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(0, beanNames.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingAndRawFactoryMethod() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
beanFactory.preInstantiateSingletons();
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawInstance() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingAndRawInstance() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
beanFactory.preInstantiateSingletons();
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -604,6 +694,10 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@@ -625,12 +719,16 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawFactoryMethod() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class));
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setProxyTargetClass(true);
|
||||
@@ -646,6 +744,35 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawInstance() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setProxyTargetClass(true);
|
||||
autoProxyCreator.setBeanFactory(beanFactory);
|
||||
beanFactory.addBeanPostProcessor(autoProxyCreator);
|
||||
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
|
||||
beanFactory.preInstantiateSingletons();
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@@ -665,6 +792,10 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@@ -685,12 +816,16 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawFactoryMethod() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class));
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setBeanFactory(beanFactory);
|
||||
@@ -705,6 +840,34 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawInstance() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setBeanFactory(beanFactory);
|
||||
beanFactory.addBeanPostProcessor(autoProxyCreator);
|
||||
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
|
||||
beanFactory.preInstantiateSingletons();
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
|
||||
}
|
||||
|
||||
@@ -1125,7 +1288,7 @@ public class ConfigurationClassPostProcessorTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class RawRepositoryConfiguration {
|
||||
public static class RawFactoryMethodRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
public Repository stringRepo() {
|
||||
@@ -1138,6 +1301,21 @@ public class ConfigurationClassPostProcessorTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class RawInstanceRepositoryConfiguration {
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
public Repository<String> stringRepo() {
|
||||
return new Repository() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Repository<String>";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ScopedRepositoryConfiguration {
|
||||
|
||||
@@ -1351,6 +1529,15 @@ public class ConfigurationClassPostProcessorTests {
|
||||
public static class ComposedConfigurationWithAttributeOverrideForExcludeFilter {
|
||||
}
|
||||
|
||||
@ComponentScan(basePackages = "org.springframework.context.annotation.componentscan.base", excludeFilters = {})
|
||||
public static class BaseConfigurationWithEmptyExcludeFilters {
|
||||
}
|
||||
|
||||
@ComponentScan(basePackages = "org.springframework.context.annotation.componentscan.simple",
|
||||
excludeFilters = @ComponentScan.Filter(Component.class))
|
||||
public static class ExtendedConfigurationWithAttributeOverrideForExcludeFilter extends BaseConfigurationWithEmptyExcludeFilters {
|
||||
}
|
||||
|
||||
@ComposedConfigurationWithAttributeOverrides
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
+33
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.junit.Rule;
|
||||
@@ -228,6 +229,22 @@ public class ConfigurationClassProcessingTests {
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithAdaptiveResourcePrototypes() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithPrototypeBean.class, AdaptiveResourceInjectionPoints.class);
|
||||
ctx.refresh();
|
||||
|
||||
AdaptiveResourceInjectionPoints adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
|
||||
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
|
||||
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
|
||||
|
||||
adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
|
||||
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
|
||||
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithPostProcessor() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
@@ -444,6 +461,21 @@ public class ConfigurationClassProcessingTests {
|
||||
}
|
||||
|
||||
|
||||
@Scope("prototype")
|
||||
static class AdaptiveResourceInjectionPoints {
|
||||
|
||||
@Resource(name = "adaptive1")
|
||||
public TestBean adaptiveInjectionPoint1;
|
||||
|
||||
public TestBean adaptiveInjectionPoint2;
|
||||
|
||||
@Resource(name = "adaptive2")
|
||||
public void setAdaptiveInjectionPoint2(TestBean adaptiveInjectionPoint2) {
|
||||
this.adaptiveInjectionPoint2 = adaptiveInjectionPoint2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class ConfigWithPostProcessor extends ConfigWithPrototypeBean {
|
||||
|
||||
@Value("${myProp}")
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Reproduces SPR-8756, which has been marked as "won't fix" for reasons
|
||||
* described in the JIRA issue. Also demonstrates the suggested workaround.
|
||||
* described in the issue. Also demonstrates the suggested workaround.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
|
||||
+20
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,11 +25,11 @@ import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.Permission;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
@@ -46,7 +46,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -102,6 +102,8 @@ public class ApplicationContextExpressionTests {
|
||||
}
|
||||
});
|
||||
|
||||
ac.getBeanFactory().setConversionService(new DefaultConversionService());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties placeholders = new Properties();
|
||||
placeholders.setProperty("code", "123");
|
||||
@@ -176,6 +178,9 @@ public class ApplicationContextExpressionTests {
|
||||
System.getProperties().put("country", "UK");
|
||||
assertEquals("123 UK", tb3.country);
|
||||
assertEquals("123 UK", tb3.countryFactory.getObject());
|
||||
assertEquals("123", tb3.optionalValue1.get());
|
||||
assertEquals("123", tb3.optionalValue2.get());
|
||||
assertFalse(tb3.optionalValue3.isPresent());
|
||||
assertSame(tb0, tb3.tb);
|
||||
|
||||
tb3 = (ValueTestBean) SerializationTestUtils.serializeAndDeserialize(tb3);
|
||||
@@ -209,12 +214,7 @@ public class ApplicationContextExpressionTests {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
||||
GenericConversionService cs = new GenericConversionService();
|
||||
cs.addConverter(String.class, String.class, new Converter<String, String>() {
|
||||
@Override
|
||||
public String convert(String source) {
|
||||
return source.trim();
|
||||
}
|
||||
});
|
||||
cs.addConverter(String.class, String.class, String::trim);
|
||||
ac.getBeanFactory().registerSingleton(GenericApplicationContext.CONVERSION_SERVICE_BEAN_NAME, cs);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class);
|
||||
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
@@ -276,8 +276,7 @@ public class ApplicationContextExpressionTests {
|
||||
|
||||
@Test
|
||||
public void systemPropertiesSecurityManager() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
||||
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
||||
|
||||
GenericBeanDefinition bd = new GenericBeanDefinition();
|
||||
bd.setBeanClass(TestBean.class);
|
||||
@@ -313,8 +312,7 @@ public class ApplicationContextExpressionTests {
|
||||
|
||||
@Test
|
||||
public void stringConcatenationWithDebugLogging() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
||||
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
||||
|
||||
GenericBeanDefinition bd = new GenericBeanDefinition();
|
||||
bd.setBeanClass(String.class);
|
||||
@@ -365,6 +363,15 @@ public class ApplicationContextExpressionTests {
|
||||
@Value("${code} #{systemProperties.country}")
|
||||
public ObjectFactory<String> countryFactory;
|
||||
|
||||
@Value("${code}")
|
||||
private transient Optional<String> optionalValue1;
|
||||
|
||||
@Value("${code:#{null}}")
|
||||
private transient Optional<String> optionalValue2;
|
||||
|
||||
@Value("${codeX:#{null}}")
|
||||
private transient Optional<String> optionalValue3;
|
||||
|
||||
@Autowired @Qualifier("original")
|
||||
public transient TestBean tb;
|
||||
}
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@ public class LiveBeansViewTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerUnregisterServeralContexts() throws MalformedObjectNameException {
|
||||
public void registerUnregisterSeveralContexts() throws MalformedObjectNameException {
|
||||
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME, this.name.getMethodName());
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
ConfigurableApplicationContext childContext = createApplicationContext("child");
|
||||
@@ -80,7 +80,7 @@ public class LiveBeansViewTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerUnregisterServeralContextsDifferentOrder() throws MalformedObjectNameException {
|
||||
public void registerUnregisterSeveralContextsDifferentOrder() throws MalformedObjectNameException {
|
||||
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME, this.name.getMethodName());
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
ConfigurableApplicationContext childContext = createApplicationContext("child");
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public class PropertyResourceConfigurerIntegrationTests {
|
||||
if (userDir.startsWith("/")) {
|
||||
userDir = userDir.substring(1);
|
||||
}
|
||||
assertTrue(ex.getMessage().indexOf(userDir) != -1);
|
||||
assertTrue(ex.getMessage().contains(userDir));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -109,8 +109,8 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
|
||||
|
||||
// Now msg better be as expected
|
||||
assertTrue("2nd search within MsgFormat cache returned expected message for Locale.US",
|
||||
sac.getMessage("message.format.example1", arguments, Locale.US).indexOf(
|
||||
"there was \"a disturbance in the Force\" on planet 7.") != -1);
|
||||
sac.getMessage("message.format.example1", arguments, Locale.US).
|
||||
contains("there was \"a disturbance in the Force\" on planet 7."));
|
||||
|
||||
Object[] newArguments = {
|
||||
new Integer(8), new Date(System.currentTimeMillis()),
|
||||
@@ -119,8 +119,8 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
|
||||
|
||||
// Now msg better be as expected even with different args
|
||||
assertTrue("2nd search within MsgFormat cache with different args returned expected message for Locale.US",
|
||||
sac.getMessage("message.format.example1", newArguments, Locale.US)
|
||||
.indexOf("there was \"a disturbance in the Force\" on planet 8.") != -1);
|
||||
sac.getMessage("message.format.example1", newArguments, Locale.US).
|
||||
contains("there was \"a disturbance in the Force\" on planet 8."));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,13 +142,13 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
|
||||
minutes of the time might not be the same.
|
||||
*/
|
||||
assertTrue("msg from staticMsgSource for Locale.US substituting args for placeholders is as expected",
|
||||
sac.getMessage("message.format.example1", arguments, Locale.US)
|
||||
.indexOf("there was \"a disturbance in the Force\" on planet 7.") != -1);
|
||||
sac.getMessage("message.format.example1", arguments, Locale.US).
|
||||
contains("there was \"a disturbance in the Force\" on planet 7."));
|
||||
|
||||
// Try with Locale.UK
|
||||
assertTrue("msg from staticMsgSource for Locale.UK substituting args for placeholders is as expected",
|
||||
sac.getMessage("message.format.example1", arguments, Locale.UK)
|
||||
.indexOf("there was \"a disturbance in the Force\" on station number 7.") != -1);
|
||||
sac.getMessage("message.format.example1", arguments, Locale.UK).
|
||||
contains("there was \"a disturbance in the Force\" on station number 7."));
|
||||
|
||||
// Try with Locale.US - Use a different test msg that requires no args
|
||||
assertTrue("msg from staticMsgSource for Locale.US that requires no args is as expected",
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -127,7 +127,7 @@ public class InterfaceBasedMBeanInfoAssemblerMappedTests extends AbstractJmxAsse
|
||||
private void assertNickName(MBeanAttributeInfo attr) {
|
||||
assertNotNull("Nick Name should not be null", attr);
|
||||
assertTrue("Nick Name should be writable", attr.isWritable());
|
||||
assertTrue("Nick Name should be readab;e", attr.isReadable());
|
||||
assertTrue("Nick Name should be readable", attr.isReadable());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -396,7 +396,7 @@ public class JndiObjectFactoryBeanTests {
|
||||
fail("Should have thrown NamingException");
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("org.springframework.tests.sample.beans.DerivedTestBean") != -1);
|
||||
assertTrue(ex.getMessage().contains("org.springframework.tests.sample.beans.DerivedTestBean"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@ public class EnableAsyncTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customExecutorConfig() throws InterruptedException {
|
||||
public void customExecutorConfig() {
|
||||
// Arrange
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(CustomExecutorConfig.class);
|
||||
|
||||
+13
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,28 +23,29 @@ import javax.naming.NamingException;
|
||||
import org.springframework.jndi.JndiTemplate;
|
||||
|
||||
/**
|
||||
* Simple extension of the JndiTemplate class that always returns
|
||||
* a given object. Very useful for testing. Effectively a mock object.
|
||||
* Simple extension of the JndiTemplate class that always returns a given object.
|
||||
*
|
||||
* <p>Very useful for testing. Effectively a mock object.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class ExpectedLookupTemplate extends JndiTemplate {
|
||||
|
||||
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>();
|
||||
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>(16);
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new JndiTemplate that will always return given objects
|
||||
* for given names. To be populated through {@code addObject} calls.
|
||||
* Construct a new JndiTemplate that will always return given objects for
|
||||
* given names. To be populated through {@code addObject} calls.
|
||||
* @see #addObject(String, Object)
|
||||
*/
|
||||
public ExpectedLookupTemplate() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new JndiTemplate that will always return the
|
||||
* given object, but honour only requests for the given name.
|
||||
* Construct a new JndiTemplate that will always return the given object,
|
||||
* but honour only requests for the given name.
|
||||
* @param name the name the client is expected to look up
|
||||
* @param object the object that will be returned
|
||||
*/
|
||||
@@ -54,8 +55,7 @@ public class ExpectedLookupTemplate extends JndiTemplate {
|
||||
|
||||
|
||||
/**
|
||||
* Add the given object to the list of JNDI objects that this
|
||||
* template will expose.
|
||||
* Add the given object to the list of JNDI objects that this template will expose.
|
||||
* @param name the name the client is expected to look up
|
||||
* @param object the object that will be returned
|
||||
*/
|
||||
@@ -63,11 +63,10 @@ public class ExpectedLookupTemplate extends JndiTemplate {
|
||||
this.jndiObjects.put(name, object);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the name is the expected name specified in the constructor,
|
||||
* return the object provided in the constructor. If the name is
|
||||
* unexpected, a respective NamingException gets thrown.
|
||||
* If the name is the expected name specified in the constructor, return the
|
||||
* object provided in the constructor. If the name is unexpected, a
|
||||
* respective NamingException gets thrown.
|
||||
*/
|
||||
@Override
|
||||
public Object lookup(String name) throws NamingException {
|
||||
|
||||
+9
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,7 @@ import javax.naming.OperationNotSupportedException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -80,7 +81,9 @@ public class SimpleNamingContext implements Context {
|
||||
* Create a new naming context with the given naming root,
|
||||
* the given name/object map, and the JNDI environment entries.
|
||||
*/
|
||||
public SimpleNamingContext(String root, Hashtable<String, Object> boundObjects, Hashtable<String, Object> env) {
|
||||
public SimpleNamingContext(
|
||||
String root, Hashtable<String, Object> boundObjects, @Nullable Hashtable<String, Object> env) {
|
||||
|
||||
this.root = root;
|
||||
this.boundObjects = boundObjects;
|
||||
if (env != null) {
|
||||
@@ -206,6 +209,7 @@ public class SimpleNamingContext implements Context {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object addToEnvironment(String propName, Object propVal) {
|
||||
return this.environment.put(propName, propVal);
|
||||
}
|
||||
@@ -293,7 +297,7 @@ public class SimpleNamingContext implements Context {
|
||||
}
|
||||
|
||||
|
||||
private static abstract class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
|
||||
private abstract static class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
|
||||
|
||||
private Iterator<T> iterator;
|
||||
|
||||
@@ -353,7 +357,7 @@ public class SimpleNamingContext implements Context {
|
||||
}
|
||||
|
||||
|
||||
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
|
||||
private static final class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
|
||||
|
||||
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException {
|
||||
super(context, root);
|
||||
@@ -366,7 +370,7 @@ public class SimpleNamingContext implements Context {
|
||||
}
|
||||
|
||||
|
||||
private static class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
|
||||
private static final class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
|
||||
|
||||
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
|
||||
super(context, root);
|
||||
|
||||
+20
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,10 @@ import javax.naming.spi.NamingManager;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of a JNDI naming context builder.
|
||||
@@ -42,7 +45,7 @@ import org.springframework.util.ClassUtils;
|
||||
* <ul>
|
||||
* <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls)
|
||||
* <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call)
|
||||
* <li>Apache's Jakarta Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
|
||||
* <li>Apache's Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Typical usage in bootstrap code:
|
||||
@@ -80,7 +83,8 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder {
|
||||
|
||||
/** An instance of this class bound to JNDI */
|
||||
/** An instance of this class bound to JNDI. */
|
||||
@Nullable
|
||||
private static volatile SimpleNamingContextBuilder activated;
|
||||
|
||||
private static boolean initialized = false;
|
||||
@@ -93,13 +97,14 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||
* @return the current SimpleNamingContextBuilder instance,
|
||||
* or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
|
||||
return activated;
|
||||
}
|
||||
|
||||
/**
|
||||
* If no SimpleNamingContextBuilder is already configuring JNDI,
|
||||
* create and activate one. Otherwise take the existing activate
|
||||
* create and activate one. Otherwise take the existing activated
|
||||
* SimpleNamingContextBuilder, clear it and return it.
|
||||
* <p>This is mainly intended for test suites that want to
|
||||
* reinitialize JNDI bindings from scratch repeatedly.
|
||||
@@ -107,17 +112,18 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||
* to control JNDI bindings
|
||||
*/
|
||||
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException {
|
||||
if (activated != null) {
|
||||
SimpleNamingContextBuilder builder = activated;
|
||||
if (builder != null) {
|
||||
// Clear already activated context builder.
|
||||
activated.clear();
|
||||
builder.clear();
|
||||
}
|
||||
else {
|
||||
// Create and activate new context builder.
|
||||
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
|
||||
builder = new SimpleNamingContextBuilder();
|
||||
// The activate() call will cause an assignment to the activated variable.
|
||||
builder.activate();
|
||||
}
|
||||
return activated;
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,12 +144,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||
logger.info("Activating simple JNDI environment");
|
||||
synchronized (initializationLock) {
|
||||
if (!initialized) {
|
||||
if (NamingManager.hasInitialContextFactoryBuilder()) {
|
||||
throw new IllegalStateException(
|
||||
Assert.state(!NamingManager.hasInitialContextFactoryBuilder(),
|
||||
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
|
||||
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
|
||||
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
|
||||
}
|
||||
NamingManager.setInitialContextFactoryBuilder(this);
|
||||
initialized = true;
|
||||
}
|
||||
@@ -192,7 +196,8 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||
* @see SimpleNamingContext
|
||||
*/
|
||||
@Override
|
||||
public InitialContextFactory createInitialContextFactory(Hashtable<?,?> environment) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public InitialContextFactory createInitialContextFactory(@Nullable Hashtable<?,?> environment) {
|
||||
if (activated == null && environment != null) {
|
||||
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
|
||||
if (icf != null) {
|
||||
@@ -212,22 +217,16 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf);
|
||||
}
|
||||
try {
|
||||
return (InitialContextFactory) icfClass.newInstance();
|
||||
return (InitialContextFactory) ReflectionUtils.accessibleConstructor(icfClass).newInstance();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf, ex);
|
||||
throw new IllegalStateException("Unable to instantiate specified InitialContextFactory: " + icf, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default case...
|
||||
return new InitialContextFactory() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Context getInitialContext(Hashtable<?,?> environment) {
|
||||
return new SimpleNamingContext("", boundObjects, (Hashtable<String, Object>) environment);
|
||||
}
|
||||
};
|
||||
return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable<String, Object>) env);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -7,11 +7,10 @@ dependencyManagement {
|
||||
}
|
||||
}
|
||||
|
||||
// As of Spring 5.1, spring-core includes asm 7.0 and repackages cglib 3.2.8, inlining
|
||||
// both into the spring-core jar. cglib 3.2.8 itself depends on asm 6+ and is therefore
|
||||
// further transformed by the JarJar task to depend on org.springframework.asm; this
|
||||
// avoids including two different copies of asm unnecessarily.
|
||||
def cglibVersion = "3.2.8"
|
||||
// spring-core includes asm and repackages cglib, inlining both into the spring-core jar.
|
||||
// cglib itself depends on asm and is therefore further transformed by the JarJar task to
|
||||
// depend on org.springframework.asm; this avoids including two different copies of asm.
|
||||
def cglibVersion = "3.2.10"
|
||||
def objenesisVersion = "3.0.1"
|
||||
|
||||
configurations {
|
||||
@@ -65,7 +64,7 @@ task objenesisRepackJar(type: Jar) { repackJar ->
|
||||
dependencies {
|
||||
cglib("cglib:cglib:${cglibVersion}@jar")
|
||||
objenesis("org.objenesis:objenesis:${objenesisVersion}@jar")
|
||||
jarjar("org.pantsbuild:jarjar:1.6.6")
|
||||
jarjar("org.pantsbuild:jarjar:1.7.2")
|
||||
|
||||
compile(files(cglibRepackJar))
|
||||
compile(files(objenesisRepackJar))
|
||||
@@ -82,8 +81,8 @@ dependencies {
|
||||
testCompile("io.projectreactor:reactor-test")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.xmlunit:xmlunit-matchers:2.6.2")
|
||||
testCompile("javax.xml.bind:jaxb-api:2.3.0")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:5.1.0") {
|
||||
testCompile("javax.xml.bind:jaxb-api:2.3.1")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:5.2.0") {
|
||||
exclude group: "stax", module: "stax-api"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2437,6 +2437,11 @@ public class ClassReader {
|
||||
* @return a non null Label, which must be equal to labels[bytecodeOffset].
|
||||
*/
|
||||
protected Label readLabel(final int bytecodeOffset, final Label[] labels) {
|
||||
// SPRING PATCH: leniently handle offset mismatch
|
||||
if (bytecodeOffset >= labels.length) {
|
||||
return new Label();
|
||||
}
|
||||
// END OF PATCH
|
||||
if (labels[bytecodeOffset] == null) {
|
||||
labels[bytecodeOffset] = new Label();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user