Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3b58bf678 |
@@ -1,10 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*.{adoc,bat,groovy,html,java,js,jsp,kt,kts,md,properties,py,rb,sh,sql,svg,txt,xml,xsd}]
|
||||
charset = utf-8
|
||||
|
||||
[*.{groovy,java,kt,kts,xml,xsd}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
continuation_indent_size = 8
|
||||
end_of_line = lf
|
||||
@@ -1,16 +0,0 @@
|
||||
# Normalize line endings to LF.
|
||||
* text eol=lf
|
||||
|
||||
# Ensure that line endings for multipart files in spring-web are not modified.
|
||||
*.multipart -text
|
||||
|
||||
# Ensure that line endings for DOS batch files are not modified.
|
||||
*.bat -text
|
||||
|
||||
# Ensure the following are treated as binary.
|
||||
*.gif binary
|
||||
*.jar binary
|
||||
*.jpeg binary
|
||||
*.jpg binary
|
||||
*.png binary
|
||||
*.vsd binary
|
||||
@@ -1,17 +0,0 @@
|
||||
<!--
|
||||
!!! For Security Vulnerabilities, please go to https://spring.io/security-policy !!!
|
||||
-->
|
||||
**Affects:** \<Spring Framework version>
|
||||
|
||||
---
|
||||
<!--
|
||||
Thanks for taking the time to create an issue. Please read the following:
|
||||
|
||||
- Questions should be asked on Stack Overflow.
|
||||
- For bugs, specify affected versions and explain what you are trying to do.
|
||||
- For enhancements, provide context and describe the problem.
|
||||
|
||||
Issue or Pull Request? Create only one, not both. GitHub treats them as the same.
|
||||
If unsure, start with an issue, and if you submit a pull request later, the
|
||||
issue will be closed as superseded.
|
||||
-->
|
||||
@@ -1,29 +0,0 @@
|
||||
name: Backport Bot
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
push:
|
||||
branches:
|
||||
- '*.x'
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Download BackportBot
|
||||
run: wget https://github.com/spring-io/backport-bot/releases/download/latest/backport-bot-0.0.1-SNAPSHOT.jar
|
||||
- name: Backport
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_EVENT: ${{ toJSON(github.event) }}
|
||||
run: java -jar backport-bot-0.0.1-SNAPSHOT.jar --github.accessToken="$GITHUB_TOKEN" --github.event_name "$GITHUB_EVENT_NAME" --github.event "$GITHUB_EVENT"
|
||||
@@ -1,13 +0,0 @@
|
||||
name: "Validate Gradle Wrapper"
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
@@ -1,52 +0,0 @@
|
||||
# Miscellaneous
|
||||
*.java.hsp
|
||||
*.sonarj
|
||||
*.sw*
|
||||
.DS_Store
|
||||
build.sh
|
||||
integration-repo
|
||||
ivy-cache
|
||||
argfile*
|
||||
activemq-data/
|
||||
classes/
|
||||
|
||||
# Log files
|
||||
jxl.log
|
||||
jmx.log
|
||||
derby.log
|
||||
|
||||
# Gradle artifacts
|
||||
.gradle
|
||||
.gradletasknamecache
|
||||
/build
|
||||
buildSrc/build
|
||||
/spring-*/build
|
||||
/framework-bom/build
|
||||
/framework-docs/build
|
||||
/integration-tests/build
|
||||
/src/asciidoc/build
|
||||
spring-test/test-output/
|
||||
|
||||
# Maven artifacts
|
||||
pom.xml
|
||||
target/
|
||||
|
||||
# Eclipse artifacts, including WTP generated manifests
|
||||
bin
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
spring-*/src/main/java/META-INF/MANIFEST.MF
|
||||
|
||||
# IDEA artifacts and output dirs
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea
|
||||
out
|
||||
test-output
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
@@ -1,34 +0,0 @@
|
||||
Juergen Hoeller <jhoeller@vmware.com>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
|
||||
Phillip Webb <pwebb@vmware.com>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
|
||||
Chris Beams <cbeams@vmware.com>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
|
||||
Arjen Poutsma <poutsmaa@vmware.com>
|
||||
Arjen Poutsma <poutsmaa@vmware.com> <apoutsma@pivotal.io>
|
||||
Arjen Poutsma <poutsmaa@vmware.com> <apoutsma@gopivotal.com>
|
||||
Arjen Poutsma <poutsmaa@vmware.com> <poutsma@mac.com>
|
||||
Arjen Poutsma <poutsmaa@vmware.com> <apoutsma@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
|
||||
Andy Clement <aclement@vmware.com>
|
||||
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
|
||||
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
|
||||
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
|
||||
Sam Brannen <sbrannen@vmware.com>
|
||||
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
|
||||
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
|
||||
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
|
||||
Nick Williams <nicholas@nicholaswilliams.net>
|
||||
@@ -1,3 +0,0 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=17.0.5-librca
|
||||
@@ -1,44 +0,0 @@
|
||||
= Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open
|
||||
and welcoming community, we pledge to respect all people who contribute through reporting
|
||||
issues, posting feature requests, updating documentation, submitting pull requests or
|
||||
patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for
|
||||
everyone, regardless of level of experience, gender, gender identity and expression,
|
||||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses,
|
||||
without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this
|
||||
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
|
||||
that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
|
||||
consistently applying these principles to every aspect of managing this project. Project
|
||||
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
|
||||
from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an
|
||||
individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
|
||||
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
|
||||
be reviewed and investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
|
||||
with regard to the reporter of an incident.
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
|
||||
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
|
||||
@@ -1,135 +0,0 @@
|
||||
# Contributing to the Spring Framework
|
||||
|
||||
First off, thank you for taking the time to contribute! :+1: :tada:
|
||||
|
||||
### Table of Contents
|
||||
|
||||
* [Code of Conduct](#code-of-conduct)
|
||||
* [How to Contribute](#how-to-contribute)
|
||||
* [Ask questions](#ask-questions)
|
||||
* [Create an Issue](#create-an-issue)
|
||||
* [Issue Lifecycle](#issue-lifecycle)
|
||||
* [Submit a Pull Request](#submit-a-pull-request)
|
||||
* [Build from Source](#build-from-source)
|
||||
* [Source Code Style](#source-code-style)
|
||||
* [Reference Docs](#reference-docs)
|
||||
|
||||
### 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.
|
||||
|
||||
### How to Contribute
|
||||
|
||||
#### Ask questions
|
||||
|
||||
If you have a question, check Stack Overflow using
|
||||
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest). Find an existing discussion, or start a new one if necessary.
|
||||
|
||||
If you believe there is an issue, search through
|
||||
[existing issues](https://github.com/spring-projects/spring-framework/issues) trying a
|
||||
few different ways to find discussions, past or current, that are related to the issue.
|
||||
Reading those discussions helps you to learn about the issue, and helps us to make a
|
||||
decision.
|
||||
|
||||
|
||||
#### Create an Issue
|
||||
|
||||
Reporting an issue or making a feature request is a great way to contribute. Your feedback
|
||||
and the conversations that result from it provide a continuous flow of ideas. However,
|
||||
before creating a ticket, please take the time to [ask and research](#ask-questions) first.
|
||||
|
||||
If you create an issue after a discussion on Stack Overflow, please provide a description
|
||||
in the issue instead of simply referring to Stack Overflow. The issue tracker is an
|
||||
important place of record for design discussions and should be self-sufficient.
|
||||
|
||||
Once you're ready, create an issue on [GitHub](https://github.com/spring-projects/spring-framework/issues).
|
||||
|
||||
Many issues are caused by subtle behavior, typos, and unintended configuration.
|
||||
Creating a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example)
|
||||
(starting with https://start.spring.io for example) of the problem helps the team
|
||||
quickly triage your issue and get to the core of the problem.
|
||||
|
||||
#### Issue Lifecycle
|
||||
|
||||
When an issue is first created, it is flagged `waiting-for-triage` waiting for a team
|
||||
member to triage it. Once the issue has been reviewed, the team may ask for further
|
||||
information if needed, and based on the findings, the issue is either assigned a target
|
||||
milestone or is closed with a specific status.
|
||||
|
||||
When a fix is ready, the issue is closed and may still be re-opened until the fix is
|
||||
released. After that the issue will typically no longer be reopened. In rare cases if the
|
||||
issue was not at all fixed, the issue may be re-opened. In most cases however any
|
||||
follow-up reports will need to be created as new issues with a fresh description.
|
||||
|
||||
#### Submit a Pull Request
|
||||
|
||||
1. If you have not previously done so, please sign the
|
||||
[Contributor License Agreement](https://cla.spring.io/sign/spring). You will be reminded
|
||||
automatically when you submit the PR.
|
||||
|
||||
1. Should you create an issue first? No, just create the pull request and use the
|
||||
description to provide context and motivation, as you would for an issue. If you want
|
||||
to start a discussion first or have already created an issue, once a pull request is
|
||||
created, we will close the issue as superseded by the pull request, and the discussion
|
||||
about the issue will continue under the pull request.
|
||||
|
||||
1. Always check out the `main` branch and submit pull requests against it
|
||||
(for target version see [settings.gradle](settings.gradle)).
|
||||
Backports to prior versions will be considered on a case-by-case basis and reflected as
|
||||
the fix version in the issue tracker.
|
||||
|
||||
1. Choose the granularity of your commits consciously and squash commits that represent
|
||||
multiple edits or corrections of the same logical change. See
|
||||
[Rewriting History section of Pro Git](https://git-scm.com/book/en/Git-Tools-Rewriting-History)
|
||||
for an overview of streamlining the commit history.
|
||||
|
||||
1. Format commit messages using 55 characters for the subject line, 72 characters per line
|
||||
for the description, followed by the issue fixed, e.g. `Closes gh-22276`. See the
|
||||
[Commit Guidelines section of Pro Git](https://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. If there is a prior issue, reference the GitHub issue number in the description of the
|
||||
pull request.
|
||||
|
||||
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
|
||||
your changes remain intact. You may also be asked to rework the submission.
|
||||
|
||||
If asked to make corrections, simply push the changes against the same branch, and your
|
||||
pull request will be updated. In other words, you do not need to create a new pull request
|
||||
when asked to make changes.
|
||||
|
||||
#### Participate in Reviews
|
||||
|
||||
Helping to review pull requests is another great way to contribute. Your feedback
|
||||
can help to shape the implementation of new features. When reviewing pull requests,
|
||||
however, please refrain from approving or rejecting a PR unless you are a core
|
||||
committer for the Spring Framework.
|
||||
|
||||
### Build from Source
|
||||
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
|
||||
wiki page for instructions on how to check out, build, and import the Spring Framework
|
||||
source code into your IDE.
|
||||
|
||||
### Source Code Style
|
||||
|
||||
The wiki pages
|
||||
[Code Style](https://github.com/spring-projects/spring-framework/wiki/Code-Style) and
|
||||
[IntelliJ IDEA Editor Settings](https://github.com/spring-projects/spring-framework/wiki/IntelliJ-IDEA-Editor-Settings)
|
||||
define the source file coding standards we use along with some IDEA editor settings we customize.
|
||||
|
||||
### Reference Docs
|
||||
|
||||
The reference documentation is in the [framework-docs/src/docs/asciidoc](framework-docs/src/docs/asciidoc) directory, in
|
||||
[Asciidoctor](https://asciidoctor.org/) format. For trivial changes, you may be able to browse,
|
||||
edit source files, and submit directly from GitHub.
|
||||
|
||||
When making changes locally, execute `./gradlew :framework-docs:asciidoctor` and then browse the result under
|
||||
`framework-docs/build/docs/ref-docs/html5/index.html`.
|
||||
|
||||
Asciidoctor also supports live editing. For more details see
|
||||
[AsciiDoc Tooling](https://docs.asciidoctor.org/asciidoctor/latest/tooling/).
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,38 +0,0 @@
|
||||
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=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 are often referred to simply as "Spring".
|
||||
|
||||
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## 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.
|
||||
|
||||
## Documentation
|
||||
|
||||
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](framework-docs/src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
|
||||
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
|
||||
|
||||
## Micro-Benchmarks
|
||||
|
||||
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
|
||||
|
||||
## Build from Source
|
||||
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
|
||||
## Continuous Integration Builds
|
||||
|
||||
Information regarding CI builds can be found in the [Spring Framework Concourse pipeline](ci/README.adoc) documentation.
|
||||
|
||||
## 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](https://spring.io/blog/), and releases are announced via our [news feed](https://spring.io/blog/category/news).
|
||||
|
||||
## License
|
||||
|
||||
The Spring Framework is released under version 2.0 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0).
|
||||
@@ -1,11 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Please see the
|
||||
[Spring Framework Versions](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions)
|
||||
wiki page.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please see https://spring.io/security-policy.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="build-spring-framework" default="precommit">
|
||||
|
||||
<path id="bundles">
|
||||
<pathelement location="../org.springframework.instrument"/>
|
||||
<pathelement location="../org.springframework.instrument.tomcat"/>
|
||||
<pathelement location="../org.springframework.asm"/>
|
||||
<pathelement location="../org.springframework.core"/>
|
||||
<pathelement location="../org.springframework.expression"/>
|
||||
<pathelement location="../org.springframework.beans"/>
|
||||
<pathelement location="../org.springframework.aop"/>
|
||||
<pathelement location="../org.springframework.context"/>
|
||||
<pathelement location="../org.springframework.transaction"/>
|
||||
<pathelement location="../org.springframework.oxm"/>
|
||||
<pathelement location="../org.springframework.jms"/>
|
||||
<pathelement location="../org.springframework.aspects"/>
|
||||
<pathelement location="../org.springframework.jdbc"/>
|
||||
<pathelement location="../org.springframework.web"/>
|
||||
<pathelement location="../org.springframework.orm"/>
|
||||
<pathelement location="../org.springframework.context.support"/>
|
||||
<pathelement location="../org.springframework.web.servlet"/>
|
||||
<pathelement location="../org.springframework.web.portlet"/>
|
||||
<pathelement location="../org.springframework.test"/>
|
||||
<pathelement location="../org.springframework.web.struts"/>
|
||||
<pathelement location="../org.springframework.spring-library"/>
|
||||
<pathelement location="../org.springframework.integration-tests"/>
|
||||
</path>
|
||||
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<import file="${basedir}/package-top-level.xml"/>
|
||||
<import file="${basedir}/publish-top-level.xml"/>
|
||||
<import file="${basedir}/publish-documentation.xml"/>
|
||||
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
|
||||
|
||||
<target name="precommit" depends="clean,clean-integration,test"/>
|
||||
|
||||
<presetdef name="javadoc.links">
|
||||
<javadoc>
|
||||
<link href="http://java.sun.com/javase/6/docs/api"/>
|
||||
<link href="http://java.sun.com/j2ee/1.4/docs/api"/>
|
||||
<link href="http://aopalliance.sourceforge.net/doc"/>
|
||||
<!-- Caucho Burlap/Hessian -->
|
||||
<link href="http://cglib.sourceforge.net/apidocs"/>
|
||||
<!-- EasyMock -->
|
||||
<link href="http://ehcache.sourceforge.net/apidocs"/>
|
||||
<link href="http://freemarker.sourceforge.net/docs/api/"/>
|
||||
<link href="http://www.hibernate.org/hib_docs/v3/api"/>
|
||||
<!-- iBATIS -->
|
||||
<!-- iText -->
|
||||
<!-- Commons Attributes -->
|
||||
<link href="http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/"/>
|
||||
<link href="http://jakarta.apache.org/commons/dbcp/apidocs/"/>
|
||||
<link href="http://jakarta.apache.org/commons/fileupload/apidocs/"/>
|
||||
<link href="http://jakarta.apache.org/commons/httpclient/apidocs/"/>
|
||||
<link href="http://jakarta.apache.org/commons/logging/apidocs/"/>
|
||||
<link href="http://jakarta.apache.org/commons/pool/apidocs/"/>
|
||||
<!-- JasperReports -->
|
||||
<!-- JDO -->
|
||||
<!-- JMX -->
|
||||
<!-- JOTM -->
|
||||
<!-- JPA -->
|
||||
<!-- JSF -->
|
||||
<link href="http://junit.sourceforge.net/javadoc_40/"/>
|
||||
<link href="http://logging.apache.org/log4j/docs/api/"/>
|
||||
<link href="http://jakarta.apache.org/regexp/apidocs/"/>
|
||||
<link href="http://jakarta.apache.org/poi/apidocs/"/>
|
||||
<link href="http://portals.apache.org/pluto/multiproject/portlet-api/apidocs/"/>
|
||||
<link href="http://www.opensymphony.com/quartz/api/"/>
|
||||
<link href="http://struts.apache.org/struts-doc-1.2.9/api/"/>
|
||||
<link href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/"/>
|
||||
<link href="http://tiles.apache.org/framework/apidocs/"/>
|
||||
<link href="http://velocity.apache.org/engine/devel/apidocs/"/>
|
||||
</javadoc>
|
||||
</presetdef>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="generate-poms" xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
|
||||
|
||||
|
||||
<path id="modules-to-process">
|
||||
<pathelement location="../org.springframework.instrument"/>
|
||||
<pathelement location="../org.springframework.instrument.tomcat"/>
|
||||
<pathelement location="../org.springframework.asm"/>
|
||||
<pathelement location="../org.springframework.core"/>
|
||||
<pathelement location="../org.springframework.expression"/>
|
||||
<pathelement location="../org.springframework.beans"/>
|
||||
<pathelement location="../org.springframework.aop"/>
|
||||
<pathelement location="../org.springframework.context"/>
|
||||
<pathelement location="../org.springframework.transaction"/>
|
||||
<pathelement location="../org.springframework.oxm"/>
|
||||
<pathelement location="../org.springframework.jms"/>
|
||||
<pathelement location="../org.springframework.aspects"/>
|
||||
<pathelement location="../org.springframework.jdbc"/>
|
||||
<pathelement location="../org.springframework.web"/>
|
||||
<pathelement location="../org.springframework.orm"/>
|
||||
<pathelement location="../org.springframework.context.support"/>
|
||||
<pathelement location="../org.springframework.web.servlet"/>
|
||||
<pathelement location="../org.springframework.web.portlet"/>
|
||||
<pathelement location="../org.springframework.test"/>
|
||||
<pathelement location="../org.springframework.web.struts"/>
|
||||
</path>
|
||||
|
||||
<condition property="maven.extension" value=".bat" else="">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
<property name="mvn.exe" value="mvn${maven.extension}"/>
|
||||
|
||||
|
||||
<target name="test">
|
||||
<echo message="pom version = ${project.version}"/>
|
||||
</target>
|
||||
|
||||
<target name="generate-pom" depends="ivy.init">
|
||||
<all-bundles target="do-generate-pom" buildpathRef="modules-to-process"/>
|
||||
</target>
|
||||
|
||||
<target name="generate-pom-test">
|
||||
<all-bundles target="do-generate-pom-test" buildpathRef="modules-to-process"/>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="do-generate-pom" depends="ivy.init">
|
||||
|
||||
|
||||
<delete file="pom.xml" quiet="true"/>
|
||||
<delete file="central-pom.xml" quiet="true"/>
|
||||
|
||||
<ivy:makepom ivyfile="ivy.xml" pomfile="pom.xml">
|
||||
<mapping conf="compile" scope="compile"/>
|
||||
<mapping conf="test" scope="test"/>
|
||||
<mapping conf="provided" scope="provided"/>
|
||||
<mapping conf="runtime" scope="runtime"/>
|
||||
</ivy:makepom>
|
||||
|
||||
<xmlproperty file="../org.springframework.spring-library/pom.xml"/>
|
||||
|
||||
<replaceregexp file="pom.xml"
|
||||
match="<version>.*?</version>"
|
||||
replace="<version>@project-version@</version>" />
|
||||
|
||||
|
||||
<exec executable="${mvn.exe}" failonerror="true">
|
||||
<arg line="org.springframework.build.repository:org.springframework.build.repository.maven:create-central"/>
|
||||
</exec>
|
||||
|
||||
<move file="pom.xml" tofile="pom-bundle.xml"/>
|
||||
<move file="central-pom.xml" tofile="pom.xml"/>
|
||||
|
||||
<replace file="pom.xml">
|
||||
<replacetoken><![CDATA[ <version>@project-version@</version>]]></replacetoken>
|
||||
<replacevalue><![CDATA[ <version>@project-version@</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>@project-version@</version>
|
||||
</parent>
|
||||
]]></replacevalue>
|
||||
</replace>
|
||||
|
||||
<replace file="pom.xml" token="@project-version@" value="${project.version}"/>
|
||||
<replace file="pom.xml" token="latest.integration" value="${project.version}"/>
|
||||
|
||||
|
||||
<fixcrlf srcDir="."
|
||||
eol="lf"
|
||||
eof="remove"
|
||||
includes="pom.xml"/>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="remove-unresolved-references">
|
||||
<!-- TODO in spring-context these are only found in S2 bundle repo, not maven central -->
|
||||
|
||||
<replace file="pom.xml">
|
||||
<replacetoken><![CDATA[<dependency>
|
||||
<groupId>com.oracle.oc4j</groupId>
|
||||
<artifactId>oracle.classloader</artifactId>
|
||||
<version>10.1.3.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.enterprise</groupId>
|
||||
<artifactId>com.sun.enterprise.loader</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
]]></replacetoken>
|
||||
<replacevalue><![CDATA[]]></replacevalue>
|
||||
</replace>
|
||||
|
||||
|
||||
</target>
|
||||
|
||||
<target name="do-generate-pom-test">
|
||||
<exec executable="${mvn.exe}" failonerror="true">
|
||||
<env key="MAVEN_TERMINATE_CMD" value="on" />
|
||||
<arg line="-P stage,fast install"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="package-bundle">
|
||||
|
||||
<import file="publish-maven.xml"/>
|
||||
|
||||
<target name="package" depends="ivy.init">
|
||||
<dist-jar/>
|
||||
<src-jar/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="package-library">
|
||||
|
||||
<import file="publish-maven.xml"/>
|
||||
|
||||
<target name="package" depends="ivy.init">
|
||||
<dist-jar/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="package-top-level">
|
||||
|
||||
<target name="package" description="Creates the release package for this project">
|
||||
<delete dir="${package.output.dir}" quiet="true"/>
|
||||
<mkdir dir="${package.output.dir}"/>
|
||||
<delete file="${package.output.file}" quiet="true"/>
|
||||
<mkdir dir="${artifacts.dir}"/>
|
||||
|
||||
<all-bundles target="package">
|
||||
<property name="package.output.dir" value="${package.output.dir}"/>
|
||||
</all-bundles>
|
||||
|
||||
<ant target="javadoc-api" inheritAll="false">
|
||||
<property name="target.dir" value="${package.docs.dir}"/>
|
||||
</ant>
|
||||
|
||||
<!-- Reference Document START-->
|
||||
<path id="doc.projects">
|
||||
<path location="${basedir}/../spring-framework-reference"/>
|
||||
</path>
|
||||
|
||||
<all-bundles target="doc" buildpathRef="doc.projects"/>
|
||||
|
||||
<delete>
|
||||
<fileset dir="${basedir}/../spring-framework-reference" includes="**/*.zip"/>
|
||||
</delete>
|
||||
|
||||
<all-bundles target="package" buildpathRef="doc.projects">
|
||||
<property name="package.output.dir" value="${package.output.dir}"/>
|
||||
</all-bundles>
|
||||
|
||||
<!-- Reference Document END-->
|
||||
|
||||
<copy todir="${package.output.dir}">
|
||||
<fileset dir="${basedir}/resources"/>
|
||||
</copy>
|
||||
|
||||
<copy todir="${package.output.dir}/projects">
|
||||
<fileset dir="${basedir}/..">
|
||||
<exclude name="*/target/**"/>
|
||||
<exclude name="integration-repo/**"/>
|
||||
<exclude name="ivy-cache/**"/>
|
||||
<exclude name="org.springframework.samples.petclinic/**"/>
|
||||
<!--exclude name="ivy-cache/repository/org.apache.velocity/org.apache.velocity.docbookframework.dist/**"/-->
|
||||
<exclude name="spring-build/lib/docbook/**" />
|
||||
<exclude name="**/*OLD*/**"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<replaceregexp match="build.stamp.*\n" replace="" flags="g"
|
||||
file="${package.output.dir}/projects/build.properties"/>
|
||||
|
||||
<replaceregexp match="release.type=.*" replace="release.type=integration" flags="g"
|
||||
file="${package.output.dir}/projects/build.properties"/>
|
||||
|
||||
<zip destfile="${package.output.file}">
|
||||
<zipfileset dir="${package.dir}">
|
||||
<exclude name="${package.basename}/docs/**"/>
|
||||
<exclude name="${package.basename}/projects/ivy-cache/**"/>
|
||||
</zipfileset>
|
||||
</zip>
|
||||
|
||||
<zip destfile="${artifacts.dir}/${package.basename}-with-docs.zip">
|
||||
<zipfileset dir="${package.dir}">
|
||||
<exclude name="${package.basename}/projects/ivy-cache/**"/>
|
||||
</zipfileset>
|
||||
</zip>
|
||||
|
||||
<!--zip destfile="${artifacts.dir}/${package.basename}-with-dependencies.zip">
|
||||
<zipfileset dir="${package.dir}"/>
|
||||
</zip-->
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<!--
|
||||
|
||||
This POM cannot be used to build Spring; it is a work in progress and should only be used as
|
||||
part of a Maven repository upload bundle using artifacts created by the spring build system.
|
||||
|
||||
-->
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.0.0.RC2</version>
|
||||
<name>Spring Framework</name>
|
||||
<description>Spring is a layered Java/J2EE application platform, based on code published in Expert
|
||||
One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002). </description>
|
||||
<url>http://www.springframework.org</url>
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>http://jira.springframework.org/browse/SPR</url>
|
||||
</issueManagement>
|
||||
<ciManagement>
|
||||
<system>Bamboo</system>
|
||||
<url>https://build.springframework.org/browse/SPR</url>
|
||||
</ciManagement>
|
||||
<inceptionYear>2003</inceptionYear>
|
||||
<organization>
|
||||
<name>SpringSource</name>
|
||||
<url>http://www.springsource.com</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<url>https://fisheye.springframework.org/browse/spring-framework</url>
|
||||
<connection>scm:svn:https://src.springframework.org/svn/spring-framework/trunk</connection>
|
||||
<developerConnection>scm:svn:https://src.springframework.org/svn/spring-framework/trunk</developerConnection>
|
||||
</scm>
|
||||
<mailingLists>
|
||||
<mailingList>
|
||||
<name> Spring Forum
|
||||
</name>
|
||||
<post>http://forum.springframework.org</post>
|
||||
<archive>http://forum.springframework.org</archive>
|
||||
</mailingList>
|
||||
</mailingLists>
|
||||
|
||||
<modules>
|
||||
<module>../org.springframework.spring-parent</module>
|
||||
<module>../org.springframework.instrument</module>
|
||||
<module>../org.springframework.instrument.tomcat</module>
|
||||
<module>../org.springframework.asm</module>
|
||||
<module>../org.springframework.core</module>
|
||||
<module>../org.springframework.expression</module>
|
||||
<module>../org.springframework.beans</module>
|
||||
<module>../org.springframework.aop</module>
|
||||
<module>../org.springframework.context</module>
|
||||
<module>../org.springframework.transaction</module>
|
||||
<module>../org.springframework.oxm</module>
|
||||
<module>../org.springframework.jms</module>
|
||||
<module>../org.springframework.aspects</module>
|
||||
<module>../org.springframework.jdbc</module>
|
||||
<module>../org.springframework.web</module>
|
||||
<module>../org.springframework.orm</module>
|
||||
<module>../org.springframework.context.support</module>
|
||||
<module>../org.springframework.web.servlet</module>
|
||||
<module>../org.springframework.web.portlet</module>
|
||||
<module>../org.springframework.test</module>
|
||||
<module>../org.springframework.web.struts</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>staging</id>
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="publish-documentation">
|
||||
|
||||
<!-- Main targets -->
|
||||
<target name="publish-documentation" depends="publish-documentation.init">
|
||||
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
command="mkdir /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"/>
|
||||
|
||||
<scp remoteToDir="${username}@spring02.managed.contegix.com:/opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"
|
||||
keyfile="${key.file}" passphrase="${passphrase}" sftp="true" verbose="true">
|
||||
<fileset dir="${package.output.dir}">
|
||||
<include name="changelog.txt" />
|
||||
<include name="license.txt" />
|
||||
<include name="readme.txt" />
|
||||
</fileset>
|
||||
<fileset dir="${package.docs.dir}" />
|
||||
</scp>
|
||||
|
||||
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
command="rm /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x ; ln -s /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version} /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x"/>
|
||||
</target>
|
||||
|
||||
<!-- Other targets -->
|
||||
<target name="publish-documentation.init">
|
||||
<fail message="The 'username' property must be set">
|
||||
<condition>
|
||||
<not>
|
||||
<isset property="username"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<fail message="The 'key.file' property must be set">
|
||||
<condition>
|
||||
<not>
|
||||
<isset property="key.file"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<fail message="The 'passphrase' property must be set">
|
||||
<condition>
|
||||
<not>
|
||||
<isset property="passphrase"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="publish-maven-central-only-pom" xmlns:maven="antlib:org.apache.maven.artifact.ant">
|
||||
|
||||
<description>
|
||||
This build file publishes to a maven repository and two ways.
|
||||
1. Publish jar, source-jar, and pom artifacts.
|
||||
2. Publish only the pom artifact.
|
||||
The additional complexity in the implementation is due to a bug in the maven ant tasks version 2.0.8 that
|
||||
prevents deploying to a local file repository on windows.
|
||||
</description>
|
||||
|
||||
|
||||
<condition property="is.windows" value="windows">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
|
||||
|
||||
<!-- top level targets -->
|
||||
|
||||
<target name="publish-maven-central-only-pom-artifacts" depends="publish-central-only-pom-windows,publish-central-only-pom-unix">
|
||||
</target>
|
||||
|
||||
<target name="publish-maven-central-code-artifacts" depends="publish-central-windows,publish-code-unix">
|
||||
</target>
|
||||
|
||||
|
||||
<target name="publish-maven-milestone-only-pom-artifacts" depends="maven.init">
|
||||
<maven:deploy>
|
||||
<remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}">
|
||||
<authentication username="${accessKey}" passphrase="${secretKey}"/>
|
||||
</remoteRepository>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
<target name="publish-maven-milestone-code-artifacts" depends="maven.init">
|
||||
<maven:deploy file="${jar.output.file}">
|
||||
<remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}">
|
||||
<authentication username="${accessKey}" passphrase="${secretKey}"/>
|
||||
</remoteRepository>
|
||||
<pom file="${pom.output.file}"/>
|
||||
<attach file="${source-jar.output.file}" classifier="sources"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="install-pom" depends="maven.init">
|
||||
<maven:install>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
</maven:install>
|
||||
</target>
|
||||
|
||||
<!-- Supporting targets -->
|
||||
|
||||
<!-- POM only deployment -->
|
||||
|
||||
<target name="publish-central-only-pom-windows" depends="maven.init" if="is.windows">
|
||||
<maven:deploy>
|
||||
<!-- Due to http://jira.codehaus.org/browse/MANTTASKS-103 in 2.0.8 on windows, fixed in 2.0.9 -->
|
||||
<!-- Assuming using local file, value of variable should be of the form L:\temp\maven-repo-test -->
|
||||
<remoteRepository id="localDisk" url="file:${maven.central.repository}"/>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
<target name="publish-central-only-pom-unix" depends="maven.init" unless="is.windows">
|
||||
<maven:deploy>
|
||||
<remoteRepository url="${maven.central.repository}"/>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- jar, source-jar and POM deployment -->
|
||||
|
||||
<target name="publish-central-windows" depends="maven.init">
|
||||
<maven:deploy file="${jar.output.file}">
|
||||
<!-- Due to http://jira.codehaus.org/browse/MANTTASKS-103 in 2.0.8 on windows, fixed in 2.0.9 -->
|
||||
<!-- Assuming using local file, value of variable should be of the form L:\temp\maven-repo-test -->
|
||||
<remoteRepository id="localDisk" url="file:${maven.central.repository}"/>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
<attach file="${source-jar.output.file}" classifier="sources"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="publish-code-unix" depends="maven.init" unless="is.windows">
|
||||
<maven:deploy file="${jar.output.file}">
|
||||
<remoteRepository url="${maven.central.repository}"/>
|
||||
<pom file="${local.pom.output.file}"/>
|
||||
<attach file="${source-jar.output.file}" classifier="sources"/>
|
||||
</maven:deploy>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="publish-top-level" xmlns:aws="antlib:org.springframework.build.aws">
|
||||
|
||||
<target name="publish" depends="publish-package, publish-multi-bundle.publish"
|
||||
description="Publish package, Ivy, and Maven artifacts"/>
|
||||
|
||||
<target name="publish-package" depends="aws.init">
|
||||
<checksum file="${package.output.file}" algorithm="sha1"/>
|
||||
<checksum file="${artifacts.dir}/${package.basename}-with-docs.zip" algorithm="sha1"/>
|
||||
<!--checksum file="${artifacts.dir}/${package.basename}-with-dependencies.zip" algorithm="sha1"/-->
|
||||
|
||||
<aws:s3 accessKey="${accessKey}" secretKey="${secretKey}">
|
||||
<upload bucketName="dist.${bucket.basename}" file="${package.output.file}"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.file.name}" publicRead="true">
|
||||
<metadata name="project.name" value="Spring Framework"/>
|
||||
<metadata name="release.type" value="${release.type}"/>
|
||||
<metadata name="bundle.version" value="${bundle.version}"/>
|
||||
<metadata name="package.file.name" value="${package.file.name}"/>
|
||||
</upload>
|
||||
<upload bucketName="dist.${bucket.basename}" file="${package.output.file}.sha1"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.file.name}.sha1" publicRead="true"/>
|
||||
|
||||
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-docs.zip"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-docs.zip" publicRead="true">
|
||||
<metadata name="project.name" value="Spring Framework"/>
|
||||
<metadata name="release.type" value="${release.type}"/>
|
||||
<metadata name="bundle.version" value="${bundle.version}"/>
|
||||
<metadata name="package.file.name" value="${package.basename}-with-docs.zip"/>
|
||||
</upload>
|
||||
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-docs.zip.sha1"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-docs.zip.sha1" publicRead="true"/>
|
||||
|
||||
<!--upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-dependencies.zip"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-dependencies.zip" publicRead="true">
|
||||
<metadata name="project.name" value="Spring Framework"/>
|
||||
<metadata name="release.type" value="${release.type}"/>
|
||||
<metadata name="bundle.version" value="${bundle.version}"/>
|
||||
<metadata name="package.file.name" value="${package.basename}-with-dependencies.zip"/>
|
||||
</upload>
|
||||
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-dependencies.zip.sha1"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-dependencies.zip.sha1" publicRead="true"/-->
|
||||
</aws:s3>
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="publish-spring-framework" xmlns:maven="antlib:org.apache.maven.artifact.ant">
|
||||
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
|
||||
|
||||
<path id="modules-with-code-artifacts">
|
||||
<pathelement location="../org.springframework.instrument"/>
|
||||
<pathelement location="../org.springframework.instrument.tomcat"/>
|
||||
<pathelement location="../org.springframework.asm"/>
|
||||
<pathelement location="../org.springframework.core"/>
|
||||
<pathelement location="../org.springframework.expression"/>
|
||||
<pathelement location="../org.springframework.beans"/>
|
||||
<pathelement location="../org.springframework.aop"/>
|
||||
<pathelement location="../org.springframework.context"/>
|
||||
<pathelement location="../org.springframework.transaction"/>
|
||||
<pathelement location="../org.springframework.oxm"/>
|
||||
<pathelement location="../org.springframework.jms"/>
|
||||
<pathelement location="../org.springframework.aspects"/>
|
||||
<pathelement location="../org.springframework.jdbc"/>
|
||||
<pathelement location="../org.springframework.web"/>
|
||||
<pathelement location="../org.springframework.orm"/>
|
||||
<pathelement location="../org.springframework.context.support"/>
|
||||
<pathelement location="../org.springframework.web.servlet"/>
|
||||
<pathelement location="../org.springframework.web.portlet"/>
|
||||
<pathelement location="../org.springframework.test"/>
|
||||
<pathelement location="../org.springframework.web.struts"/>
|
||||
</path>
|
||||
|
||||
<path id="modules-with-only-pom-artifacts">
|
||||
<pathelement location="../org.springframework.spring-library"/>
|
||||
<pathelement location="../org.springframework.spring-parent"/>
|
||||
</path>
|
||||
|
||||
<!-- for milestones -->
|
||||
|
||||
<target name="publish-maven-milestone" depends="publish-maven-milestone-only-pom">
|
||||
<all-bundles target="publish-maven-milestone-code-artifacts" buildpathRef="modules-with-code-artifacts"/>
|
||||
</target>
|
||||
|
||||
<target name="publish-maven-milestone-only-pom">
|
||||
<all-bundles target="publish-maven-milestone-only-pom-artifacts" buildpathRef="modules-with-only-pom-artifacts"/>
|
||||
</target>
|
||||
|
||||
<!-- for releases -->
|
||||
|
||||
<target name="publish-maven-central-release" depends="publish-maven-central-only-pom-release">
|
||||
<all-bundles target="publish-maven-central-code-artifacts" buildpathRef="modules-with-code-artifacts"/>
|
||||
</target>
|
||||
|
||||
<target name="publish-maven-central-only-pom-release">
|
||||
<all-bundles target="publish-maven-central-only-pom-artifacts" buildpathRef="modules-with-only-pom-artifacts"/>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
This is where the master build that creates releases of Spring Framework resides. The build system is based on spring-build, which is linked in using an SVN external to https://src.springframework.org/svn/spring-build.
|
||||
|
||||
USERS
|
||||
- To build all Spring Framework projects, including samples:
|
||||
|
||||
1. From this directory, run:
|
||||
ant
|
||||
|
||||
Build Pre-requisites:
|
||||
- javac 1.6 or > must be in your system path
|
||||
- ant 1.7 or > must be in your system path
|
||||
|
||||
DEVELOPERS
|
||||
- To build a new Spring Framework distribution for release:
|
||||
|
||||
1. Update the files containing the version number to reflect the new release version, if necessary.
|
||||
|
||||
build.properties
|
||||
build-spring-framework/resources/readme.txt
|
||||
spring-framework/src/spring-framework-reference.xml
|
||||
|
||||
2. From this directory, run:
|
||||
|
||||
ant jar package
|
||||
|
||||
The release archive will be created and placed in:
|
||||
target/artifacts
|
||||
@@ -0,0 +1,293 @@
|
||||
SPRING FRAMEWORK CHANGELOG
|
||||
==========================
|
||||
http://www.springsource.org
|
||||
|
||||
|
||||
Changes in version 3.0.0.RC2 (2009-11-13)
|
||||
-----------------------------------------
|
||||
|
||||
* updated to final versions of JSR-330 "javax.inject" and JSR-303 "javax.validation" APIs
|
||||
* full compliance with the JSR-330 TCK (i.e. full compliance with the final specification)
|
||||
* support for Hibernate Validator 4.0 GA (as the JSR-303 reference implementation)
|
||||
* added support for load-time weaving in JBoss 5.x
|
||||
* added support for recent EHCache 1.6 configuration properties to EHCacheFactoryBean
|
||||
* added AnnotatedBeanDefinitionReader helper for programmatic registration of annotated classes
|
||||
* added AnnotationConfig(Web)ApplicationContext for convenient registration/scanning of classes
|
||||
* added GenericXmlApplicationContext with flexible configuration options for its XML support
|
||||
* AbstractApplicationContext can also start up in case of system properties access failure
|
||||
* internal MergedBeanDefinitionPostProcessors apply after all other post-processors
|
||||
* inner beans detected as ApplicationListeners as well (only supported for inner singletons)
|
||||
* child bean definition's scope attribute can be inherited from parent bean definition now
|
||||
* introduced SmartLifecycle interface with auto-startup and shutdown order support
|
||||
* introduced LifecycleProcessor delegate, customizable through "lifecycleProcessor" bean
|
||||
* MessageListenerContainers and Quartz SchedulerFactoryBean start up on refresh instead of init
|
||||
* added initialize-database tag to jdbc namespace for populating external data sources with data
|
||||
* PathMatchingResourcePatternResolver leniently ignores non-existing root directories
|
||||
* DefaultConversionService understands "on"/"off", "yes"/"no", "1"/"0" as boolean values
|
||||
* CustomEditorConfigurer supports PropertyEditor instances again (with deprecation warning)
|
||||
* revised MethodParameter's annotation accessor methods
|
||||
* ClassUtils is now parameterized with Class<?> and Class<T> where appropriate
|
||||
* DataBinder now accepts var-args to set allowed, disallowed, and required fields
|
||||
* DataBinder auto-grows nested paths on traversal (avoiding NullValueInNestedPathException)
|
||||
* fixed enum binding regression with WebRequestDataBinder (as used by @MVC data binding now)
|
||||
* fixed FieldError to expose rejected input value as String value instead of as array
|
||||
* JSR-303 Validator will only register validation failures if no binding failure happened
|
||||
* ContentNegotiatingViewResolver works with ignoreAcceptHeader and defaultContentType as well
|
||||
* added Spring MVC namespace, with convenient mvc:annotation-driven configuration element
|
||||
* default number and datetime formatters configured when using the Spring MVC namespace
|
||||
* full support for datetime formatting using the Joda Time library (automatically enabled)
|
||||
* added convenient @NumberFormat and @DateTimeFormat annotations for declarative formatting
|
||||
* implicit T.valueOf(S) and constructor T(S) lookup if no explicit S->T converter matches
|
||||
* AbstractExcelView is compatible with Apache POI 3.0 as well as 3.5 now
|
||||
* TilesConfigurer only sets up EL support if JSP 2.1 is present (for JSP 2.0 compatibility)
|
||||
* re-introduced Struts 1.x support ("org.springframework.web.struts") in deprecated form
|
||||
* deprecated scheduling support for JDK 1.3 Timer ("org.springframework.scheduling.timer")
|
||||
* deprecated remoting support for JAX-RPC (in favor of JAX-WS)
|
||||
|
||||
|
||||
Changes in version 3.0.0.RC1 (2009-09-25)
|
||||
-----------------------------------------
|
||||
|
||||
* upgraded to CGLIB 2.2, AspectJ 1.6.5, Groovy 1.6.3, EHCache 1.6.2, JUnit 4.7, TestNG 5.10
|
||||
* introduced early support for JSR-330 "javax.inject" annotations (for autowiring)
|
||||
* introduced early support for JSR-303 Bean Validation (setup and MVC integration)
|
||||
* added default editors for "java.util.Currency" and "java.util.TimeZone"
|
||||
* refined PathMatchingResourcePatternResolver's treatment of non-readable directories
|
||||
* PathMatchingResourcePatternResolver understands VFS resources (i.e. works on JBoss 5.x)
|
||||
* revised AccessControlContext access from BeanFactory
|
||||
* AbstractBeanDefinitionParser can deal with null return value as well
|
||||
* PropertyOverrideConfigurer's "ignoreInvalidKeys" ignores invalid property names as well
|
||||
* PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax
|
||||
* BeanFactory's default type conversion falls back to String constructor on target type
|
||||
* BeanFactory tries to create unknown collection implementation types via default constructor
|
||||
* BeanFactory supports ObjectFactory as a dependency type for @Autowired and @Value
|
||||
* BeanFactory supports JSR-330 Provider interface as a dependency type for @Inject
|
||||
* BeanFactory prefers local primary bean to primary bean in parent factory
|
||||
* protected @Autowired method can be overridden with non-annotated method to suppress injection
|
||||
* private @Autowired methods with same signature will be called individually across a hierarchy
|
||||
* @PostConstruct processed top-down (base class first); @PreDestroy bottom-up (subclass first)
|
||||
* ConfigurationClassPostProcessor detect @Bean methods on registered plain bean classes as well
|
||||
* support for default "conversionService" bean in an ApplicationContext
|
||||
* MBeanServerFactoryBean returns JDK 1.5 platform MBeanServer for agent id "" (empty String)
|
||||
* changed NamedParameter/SimpleJdbcOperations parameter signatures to accept any Map value type
|
||||
* refined logging in JMS SingleConnectionFactory and DefaultMessageListenerContainer
|
||||
* introduced "ui.format" package as an alternative to PropertyEditors for data binding
|
||||
* @RequestMapping annotation now supported for annotated interfaces (and JDK proxies) as well
|
||||
* @RequestParam and co support placeholders and expressions in their defaultValue attributes
|
||||
* @Value expressions supported as MVC handler method arguments as well (against request scope)
|
||||
* JSR-303 support for validation of @MVC handler method arguments driven by @Valid annotations
|
||||
* refined response handling for @ExceptionHandler methods
|
||||
* @ResponseStatus usage in handler methods detected by RedirectView
|
||||
* all @SessionAttributes get exposed to the model before handler method execution
|
||||
* @Event/ResourceMapping uniquely mapped to through event/resource id, even across controllers
|
||||
* MultipartRequest is available as a mixin interface on (Native)WebRequest as well
|
||||
* removed outdated "cacheJspExpressions" feature from ExpressionEvaluationUtils
|
||||
* introduced common ErrorHandler strategy, supported by message listener container
|
||||
* Jpa/JdoTransactionManager passes resolved timeout into Jpa/JdoDialect's beginTransaction
|
||||
* HibernateJpaDialect applies timeout onto native Hibernate Transaction before begin call
|
||||
* Spring's Hibernate support is now compatible with Hibernate 3.5 beta 1 as well
|
||||
* Spring's JPA support is now fully compatible with JPA 2.0 as in EclipseLink 2.0.0.M7
|
||||
* SpringJUnit4ClassRunner is now compatible with JUnit 4.5, 4.6, and 4.7
|
||||
* SpringJUnit4ClassRunner once again supports collective timeouts for repeated tests
|
||||
* deprecated @NotTransactional annotation for test classes in favor of @BeforeTransaction
|
||||
|
||||
|
||||
Changes in version 3.0.0.M4 (2009-08-10)
|
||||
----------------------------------------
|
||||
|
||||
* upgraded to JUnit 4.6, TestNG 5.9, and EasyMock 2.5.1
|
||||
* updated all Spring Framework OSGI manifests to list unversioned imports explicitly
|
||||
* relaxed several OSGi bundle dependencies (optional, extended version ranges)
|
||||
* revised Java 6 checks to test for the presence of specific Java 6 interfaces/classes only
|
||||
* replaced Commons Collections dependency with Spring-provided LinkedCaseInsensitiveMap
|
||||
* case-insensitive Maps and key Sets preserve original casing for introspection/logging
|
||||
* constructor argument type matching supports arrays and simple class names now
|
||||
* XML constructor-arg element allows for specifying a constructor argument by name now
|
||||
* XML import elements with relative resource patterns are supported as well now
|
||||
* introduced non-lenient constructor resolution mode for BeanDefinitions (for RFC-124)
|
||||
* revised DefaultListableBeanFactory's access control when running within a SecurityManager
|
||||
* BeanWrapper and DefaultListableBeanFactory accept a custom ConversionService now
|
||||
* DefaultListableBeanFactory references are serializable now when initialized with an id
|
||||
* scoped proxies are serializable now, for web scopes as well as for singleton beans
|
||||
* injected request/session references are serializable proxies for the current request now
|
||||
* Servlet/Portlet ApplicationContexts use a specific id based on servlet/portlet name
|
||||
* ReloadableResourceBundleMessageSource correctly calculates filenames for all locales now
|
||||
* @PostConstruct works for multiple private init methods of the same name in a hierarchy
|
||||
* @Primary/@Lazy/@DependsOn supported as meta-annotations as well
|
||||
* @Bean/@Scope etc supported as meta-annotations on factory methods as well now
|
||||
* @Required does not get processed on beans returned by @Bean factory methods
|
||||
* @Import detects and accepts existing configuration class of the desired type
|
||||
* @Transactional supports qualifier value for choosing between multiple transaction managers
|
||||
* WebSphereUowTransactionManager falls back to UOWManagerFactory lookup by default
|
||||
* JMS SingleConnectionFactory performs start call within connection monitor (for Oracle AQ)
|
||||
* @ManagedResource is marked as inherited now, for generic management-aware base classes
|
||||
* introduced dedicated @ManagedMetric annotation for metric attributes in a JMX environment
|
||||
* added task namespace with scheduler/executor configuration and scheduled task definitions
|
||||
* added jdbc namespace with embedded-database tag (supporting HSQL, H2, and Derby)
|
||||
* Hibernate AnnotationSessionFactoryBean detects Hibernate's special @Entity annotation too
|
||||
* added SimpleJaxWsServiceExporter workaround for WebLogic 10.3's address format requirements
|
||||
* added support for @WebServiceProvider annotation to Spring's JaxWsServiceExporters
|
||||
* updated Hessian support for Hessian 3.2 compatibility (requiring Hessian 3.2 or above now)
|
||||
* updated Tiles support for Tiles 2.1 compatibility (requiring Tiles 2.1.2 or above now)
|
||||
* Velocity/FreeMarker/TilesViewResolver only returns a view if the target resource exists now
|
||||
* @DirtiesContext is now supported at the test class level with configurable class modes
|
||||
* added beforeTestClass() and afterTestClass() to the TestExecutionListener API
|
||||
* ProfileValueUtils now enforces class-level overrides for @IfProfileValue
|
||||
* @ContextConfiguration's loader attribute is now inherited if not declared locally
|
||||
* TransactionalTestExecutionListener no longer flushes transactions before rolling back
|
||||
|
||||
|
||||
Changes in version 3.0.0.M3 (2009-05-06)
|
||||
----------------------------------------
|
||||
|
||||
* Spring 3.0 includes reference documentation now
|
||||
* Spring 3.0 is shipping with proper Maven POMs now
|
||||
* updated to JRuby 1.2 (remaining compatible with JRuby 1.1 and above)
|
||||
* updated to Hessian 3.2.1 (remaining compatible with Hessian 3.1.3 and above)
|
||||
* updated to FreeMarker 2.3.15 (for exposure of FreeMarkerServlet-style HTTP scopes)
|
||||
* removed Axis 1.x support package, keeping basic JAX-RPC support only (next to JAX-WS)
|
||||
* introduced explicit XML array element in spring-beans-3.0.xsd
|
||||
* introduced new type conversion SPI and converter API in spring-core convert package
|
||||
* introduced annotated @Bean factory methods and JavaConfig-style @Configuration classes
|
||||
* introduced @Primary, @Lazy and @DependsOn annotations for scanned components
|
||||
* custom stereotype annotations can be meta-annotated with @Service, @Controller etc as well
|
||||
* @Scope and @Transactional are now supported as meta-annotations on custom annotations
|
||||
* @Autowired uses field/parameter name as fallback qualifier value
|
||||
* qualifier annotations can be used at method level as well (applying to all parameters)
|
||||
* @Value annotation can be used at method level as well (e.g. on bean property setters)
|
||||
* @Value values may use ${...} placeholders (driven by PropertyPlaceholderConfigurer)
|
||||
* @Resource names may use ${...} placeholders (driven by PropertyPlaceholderConfigurer)
|
||||
* fixed EL evaluation of prepared constructor arguments for repeated prototype creation
|
||||
* ConstructorArgumentValues exposed indexed arguments in the order of definition
|
||||
* AutowiredAnnotationBeanPostProcessor calculates cached arguments in a synchronized block
|
||||
* declarative destroy-method="..." specifications get validated at bean creation time
|
||||
* component-scan's "base-package" attribute supports spaces as separators as well
|
||||
* CachedIntrospectionResults always caches bean classes except in case of custom BeanInfo
|
||||
* GenericTypeResolver's type variable cache uses weak values (for OSGi compatibility)
|
||||
* fixed CachingMapDecorator to support garbage-collected weak references (again)
|
||||
* AOP ProxyFactory excludes non-public interfaces when autodetecting proxy interfaces
|
||||
* added DuplicateKeyException to DAO exception hierachy
|
||||
* added EmbeddedDatabase support in spring-jdbc embedded package, with initial HSQL support
|
||||
* SessionAwareMessageListener supports generic declaration of concrete JMS Message type
|
||||
* RmiServiceExporter and RmiRegistryFactoryBean synchronize registry lookup/creation
|
||||
* added "unregisterManagedResource" method to MBeanExporter/MBeanExportOperations
|
||||
* TimerTaskExecutor creates non-daemon Timer and uses bean name as default Timer name
|
||||
* added TaskScheduler interface and Trigger abstraction
|
||||
* added ConcurrentTaskScheduler and ThreadPoolTaskScheduler
|
||||
* added CommonJ TimerManagerTaskScheduler
|
||||
* added CronTrigger implementation for cron expression support
|
||||
* renamed "contextProperties" attribute to "contextParameters" (matching web.xml naming)
|
||||
* "contextParameters" contains Servlet/PortletConfig parameters as well
|
||||
* added default "servletContext" and "servletConfig" environment beans
|
||||
* added default "portletContext" and "portletConfig" environment beans
|
||||
* added default web scope "application", wrapping a ServletContext/PortletContext
|
||||
* JSF FacesContext and ExternalContext are resolvable dependencies by default, if available
|
||||
* FacesRequestAttributes (as used by RequestContextHolder) can access global Portlet session
|
||||
* revised @RequestMapping semantics for REST support purposes
|
||||
* request handler methods with @ModelAttribute annotation always return a model attribute
|
||||
* introduced @ExceptionHandler annotation for used in annotated web controllers
|
||||
* introduced ModelAndViewResolver SPI for custom handler method return types
|
||||
* FreeMarkerView can be initialized with ServletContext only (e.g. for testing)
|
||||
* MockPortletSession supports destruction of session attributes on invalidation
|
||||
* completed upgrade of the TestContext Framework to JUnit 4.5
|
||||
* SpringJUnit4ClassRunner subclasses can now override the default ContextLoader class
|
||||
* added "value" alias for @ContextConfiguration's "locations" attribute
|
||||
|
||||
|
||||
Changes in version 3.0.0.M2 (2009-02-25)
|
||||
----------------------------------------
|
||||
|
||||
* revised expression parser API design
|
||||
* added SimpleThreadScope implementation
|
||||
* refined OSGi version constraints for "javax.annotation" and "junit.framework"
|
||||
* "systemProperties" bean is not considered a default match for type Properties anymore
|
||||
* SimpleAliasRegistry's "getAliases" method returns transitive aliases now
|
||||
* SimpleAliasRegistry detects resolved aliases that loop back to the original name
|
||||
* PropertyPlaceholderConfigurer does not modify Map in case of equal String keys
|
||||
* improved NoClassDefFoundError handling during constructor resolution
|
||||
* inner class names in Java source style ("java.lang.Thread.State") supported as well
|
||||
* pre-converted property values are preserved more eagerly for re-created beans
|
||||
* prototype beans receive independent collection/array even when based on single value
|
||||
* registered plain singletons will be fully matched according to their qualifiers
|
||||
* @Qualifier value matching takes chained aliases of target beans into account as well
|
||||
* ASM-based AnnotationMetadata fully resolves class arguments and enums into Java types
|
||||
* ProceedingJoinPoint resolves parameter names using ASM-based parameter name discovery
|
||||
* MethodInvocations and ProceedingJoinPoints always expose original method (not bridge)
|
||||
* bridge method resolution works with Hibernate-generated CGLIB proxies as well
|
||||
* generic collection type resolution respects upper bound (e.g. ? extends Number) as well
|
||||
* TypeUtils detects variations of ParameterizedType/GenericArrayType assignability as well
|
||||
* ReflectionUtils findMethod detects methods on "java.lang.Object" as well
|
||||
* UrlResource eagerly closes HTTP connections in case of "getInputStream()" failure
|
||||
* PathMatchingResourcePatternResolver avoids NPE when initialized with null ClassLoader
|
||||
* all "taskExecutor" bean properties now accept any "java.util.concurrent.Executor"
|
||||
* added "Future submit(Runnable)" and "Future submit(Callable)" to AsyncTaskExecutor
|
||||
* SimpleAsyncTaskExecutor supports a custom "java.util.concurrent.ThreadFactory"
|
||||
* SchedulingTaskExecutor interface extends AsyncTaskExecutor now
|
||||
* added ThreadPoolExecutorFactoryBean (exposing the native ExecutorService interface)
|
||||
* added ExecutorServiceAdapter class as a standard wrapper for a Spring TaskExecutor
|
||||
* reduced backport-concurrent support to TaskExecutor adapters
|
||||
* added @Async annotation and AsyncAnnotationAdvisor (namespace support coming in M3)
|
||||
* EJB 3.1's @Asynchronous annotation gets detected and supported by default as well
|
||||
* ApplicationListener beans get obtained on demand, supporting non-singletons as well
|
||||
* ApplicationListeners will be called in the order according to the Ordered contract
|
||||
* generified ApplicationListener interface, narrowing the event type to be received
|
||||
* introduced SmartApplicationListener interface for supported event/source types
|
||||
* generified Transaction/Hibernate/Jdo/JpaCallback with generic "doInXxx" return type
|
||||
* HibernateOperations uses generic parameter/return types where possible
|
||||
* JdoOperations uses generic parameter/return types where possible (following JDO 2.1)
|
||||
* removed "flush" operation from JdoDialect (fully relying on JDO 2.0+ compliance now)
|
||||
* added JDO 2.1 compliant StandardPersistenceManagerProxy/SpringPersistenceManagerProxy
|
||||
* Spring-created EntityManagers support JPA 2.0 draft API ("unwrap", "getQueryBuilder")
|
||||
* Spring initiates JPA 2.0 query timeout with remaining Spring transaction timeout
|
||||
* added support for WebSphere's ResourceAdapter-managed messaging transactions
|
||||
* made SpringBeanAutowiringInterceptor callback signature compatible with WebSphere
|
||||
* WebSphereUowTransactionManager preserves original exception in case of rollback
|
||||
* added "flush()" method to TransactionStatus and TransactionSynchronization interfaces
|
||||
* test context manager automatically flushes transactions before rolling back
|
||||
* DefaultLobHandler uses explicit Blob/Clob access for reading when "wrapAsLob"=true
|
||||
* fixed JmsException/JmsUtils to fully avoid NPEs in case of cause messages being null
|
||||
* fixed MessageListenerAdapter's "getSubscriptionName()" to work without delegate as well
|
||||
* fixed HTTP invoker to support resolution of multi-level primitive array classes again
|
||||
* deprecated support for JMS 1.0.2 providers (JmsTemplate102 etc)
|
||||
* introduced top-level HTTP support package "org.springframework.http"
|
||||
* introduced RestTemplate facility in package "org.springframework.web.client"
|
||||
* introduced OXM support package (originating from Spring Web Services)
|
||||
* introduced OXM-based MarshallingMessageConverter for Spring JMS
|
||||
* introduced OXM-based MarshallingView for Spring MVC
|
||||
* refined @PathVariable handling in MVC handler methods
|
||||
* updated Spring Portlet MVC infrastructure and mocks for Portlet API 2.0
|
||||
* added resource and event methods to Portlet HandlerAdapter/HandlerInterceptor
|
||||
* added resolveException method for resource requests to HandlerExceptionResolver
|
||||
* introduced Resource/EventAwareController subinterfaces of Portlet Controller
|
||||
* introduced @Action/@Render/@Resource/@EventMapping annotations for Portlet MVC
|
||||
* added @RequestHeader support for Portlet MVC (based on Portlet request properties)
|
||||
* introduced @CookieValue annotation for Servlet and Portlet MVC handler methods
|
||||
* @RequestMapping type-level param constraints taken into account consistently
|
||||
* optional boolean parameters in MVC handler methods resolve to "false" if not present
|
||||
* "url" macro in "spring.ftl" performs standard Servlet URL encoding automatically
|
||||
|
||||
|
||||
Changes in version 3.0.0.M1 (2008-12-05)
|
||||
----------------------------------------
|
||||
|
||||
* revised project layout and build system (module-based sources, bundle repository)
|
||||
* updated entire codebase for Java 5 code style (generics, varargs, StringBuilder)
|
||||
* updated to JUnit 4.5 and JRuby 1.1
|
||||
* removed WebLogic 8.1 and WebSphere 5.1 support
|
||||
* removed native TopLink API support (superseded by JPA)
|
||||
* removed Commons Attributes support (superseded by Java 5 annotations)
|
||||
* removed Jakarta JSTL support for JSP 1.2 (superseded by JSP 2.0)
|
||||
* removed outdated Struts 1.x Action delegation support
|
||||
* removed ContextLoaderServlet and Log4jConfigServlet
|
||||
* deprecated form controller hierarchy in favor of @MVC form object handling
|
||||
* deprecated JUnit 3.8 test class hierarchy in favor of test context framework
|
||||
* revised TaskExecutor interface to extend "java.util.concurrent.Executor" now
|
||||
* introduced Spring EL parser in org.springframework.expression package
|
||||
* introduced #{...} expression support in bean definitions
|
||||
* introduced @Value annotation for embedded expression support
|
||||
* introduced @PathVariable annotation for MVC handler methods
|
||||
* introduced ShallowEtagHeaderFilter
|
||||
* introduced AbstractAtomFeedView and AbstractRssFeedView
|
||||
* introduced default value support for @RequestParam
|
||||
* introduced @RequestHeader annotation for MVC handler methods
|
||||
* introduced "spring:url" and "spring:param" JSP tags
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,22 @@
|
||||
======================================================================
|
||||
== NOTICE file corresponding to section 4 d of the Apache License, ==
|
||||
== Version 2.0, for the Spring Framework distribution. ==
|
||||
======================================================================
|
||||
|
||||
This product includes software developed by
|
||||
the Apache Software Foundation (http://www.apache.org).
|
||||
|
||||
The end-user documentation included with a redistribution, if any,
|
||||
must include the following acknowledgement:
|
||||
|
||||
"This product includes software developed by the Spring Framework
|
||||
Project (http://www.springframework.org)."
|
||||
|
||||
Alternately, this acknowledgement may appear in the software itself,
|
||||
if and wherever such third-party acknowledgements normally appear.
|
||||
|
||||
The names "Spring", "Spring Framework", and "Spring Web Flow" must
|
||||
not be used to endorse or promote products derived from this
|
||||
software without prior written permission. For written permission,
|
||||
please contact enquiries@springsource.com.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
SPRING FRAMEWORK 3.0 RC2 (November 2009)
|
||||
-------------------------------------
|
||||
http://www.springframework.org
|
||||
|
||||
1. INTRODUCTION
|
||||
|
||||
This is the second release candidate of Spring 3.0, which is scheduled for final release in Q4 2009.
|
||||
It release is feature complete, but may still have some issues.
|
||||
|
||||
2. RELEASE NOTES
|
||||
|
||||
This release comes with complete reference documentation already. Consult the provided
|
||||
javadoc for technical details of specific packages and classes.
|
||||
|
||||
3. DISTRIBUTION JAR FILES
|
||||
|
||||
The Spring Framework module jar files can be found in the 'dist' directory. Note that
|
||||
this release does not contain a 'spring.jar' file anymore, in contrast to previous Spring
|
||||
generations. Furthermore, the jar file names follow bundle repository conventions now.
|
||||
|
||||
4. GETTING STARTED
|
||||
|
||||
A Getting Started guide is to be provided in time for Spring 3.0 GA. For the time being,
|
||||
please consult the blog examples at http://blog.springsource.com as well as the sections
|
||||
of interest in the reference documentation.
|
||||
@@ -1,177 +0,0 @@
|
||||
plugins {
|
||||
id 'io.spring.nohttp' version '0.0.10'
|
||||
id 'io.freefair.aspectj' version '6.5.0.3' apply false
|
||||
// kotlinVersion is managed in gradle.properties
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version "${kotlinVersion}" apply false
|
||||
id 'org.jetbrains.dokka' version '1.7.20'
|
||||
id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false
|
||||
id 'org.unbroken-dome.xjc' version '2.0.0' apply false
|
||||
id 'com.github.ben-manes.versions' version '0.42.0'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
|
||||
id 'de.undercouch.download' version '5.1.0'
|
||||
id 'me.champeau.jmh' version '0.6.6' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
moduleProjects = subprojects.findAll { it.name.startsWith("spring-") }
|
||||
javaProjects = subprojects - project(":framework-bom") - project(":framework-platform")
|
||||
}
|
||||
|
||||
configure(allprojects) { project ->
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "https://repo.spring.io/milestone"
|
||||
content {
|
||||
// Netty 5 optional support
|
||||
includeGroup 'io.projectreactor.netty'
|
||||
}
|
||||
}
|
||||
maven { url "https://repo.spring.io/libs-spring-framework-build" }
|
||||
if (version.contains('-')) {
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
}
|
||||
if (version.endsWith('-SNAPSHOT')) {
|
||||
maven { url "https://repo.spring.io/snapshot" }
|
||||
}
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor 0, "seconds"
|
||||
cacheDynamicVersionsFor 0, "seconds"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configure([rootProject] + javaProjects) { project ->
|
||||
group = "org.springframework"
|
||||
|
||||
apply plugin: "java"
|
||||
apply plugin: "java-test-fixtures"
|
||||
apply plugin: "checkstyle"
|
||||
apply plugin: 'org.springframework.build.conventions'
|
||||
apply from: "${rootDir}/gradle/toolchains.gradle"
|
||||
apply from: "${rootDir}/gradle/ide.gradle"
|
||||
|
||||
configurations {
|
||||
dependencyManagement {
|
||||
canBeConsumed = false
|
||||
canBeResolved = false
|
||||
visible = false
|
||||
}
|
||||
matching { it.name.endsWith("Classpath") }.all { it.extendsFrom(dependencyManagement) }
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
include(["**/*Tests.class", "**/*Test.class"])
|
||||
systemProperty("java.awt.headless", "true")
|
||||
systemProperty("testGroups", project.properties.get("testGroups"))
|
||||
systemProperty("io.netty.leakDetection.level", "paranoid")
|
||||
systemProperty("io.netty5.leakDetectionLevel", "paranoid")
|
||||
systemProperty("io.netty5.leakDetection.targetRecords", "32")
|
||||
systemProperty("io.netty5.buffer.lifecycleTracingEnabled", "true")
|
||||
systemProperty("io.netty5.buffer.leakDetectionEnabled", "true")
|
||||
jvmArgs(["--add-opens=java.base/java.lang=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.util=ALL-UNNAMED"])
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.4"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
tasks.named("checkstyleMain").configure {
|
||||
maxHeapSize = "1g"
|
||||
}
|
||||
|
||||
tasks.named("checkstyleTest").configure {
|
||||
maxHeapSize = "1g"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependencyManagement(enforcedPlatform(dependencies.project(path: ":framework-platform")))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-params")
|
||||
testImplementation("org.junit.platform:junit-platform-suite-api")
|
||||
testImplementation("org.mockito:mockito-core")
|
||||
testImplementation("org.mockito:mockito-junit-jupiter")
|
||||
testImplementation("io.mockk:mockk")
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
// Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs.
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
|
||||
// JSR-305 only used for non-required meta-annotations
|
||||
compileOnly("com.google.code.findbugs:jsr305")
|
||||
testCompileOnly("com.google.code.findbugs:jsr305")
|
||||
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
|
||||
}
|
||||
|
||||
ext.javadocLinks = [
|
||||
"https://docs.oracle.com/en/java/javase/17/docs/api/",
|
||||
"https://jakarta.ee/specifications/platform/9/apidocs/",
|
||||
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
|
||||
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
|
||||
"https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"https://www.quartz-scheduler.org/api/2.3.0/",
|
||||
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
|
||||
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
|
||||
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
|
||||
"https://hc.apache.org/httpcomponents-client-5.2.x/current/httpclient5/apidocs/",
|
||||
"https://projectreactor.io/docs/test/release/api/",
|
||||
"https://junit.org/junit4/javadoc/4.13.2/",
|
||||
// TODO Uncomment link to JUnit 5 docs once we have sorted out
|
||||
// the following warning in the build.
|
||||
//
|
||||
// warning: The code being documented uses packages in the unnamed module, but the packages defined in https://junit.org/junit5/docs/5.9.1/api/ are in named modules.
|
||||
//
|
||||
// "https://junit.org/junit5/docs/5.9.1/api/",
|
||||
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
|
||||
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
|
||||
"https://r2dbc.io/spec/1.0.0.RELEASE/api/",
|
||||
// The external Javadoc link for JSR 305 must come last to ensure that types from
|
||||
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
|
||||
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
|
||||
// in a split package, and the javadoc tool does not support split packages
|
||||
// across multiple external Javadoc sites.
|
||||
"https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
configure(moduleProjects) { project ->
|
||||
apply from: "${rootDir}/gradle/spring-module.gradle"
|
||||
}
|
||||
|
||||
configure(rootProject) {
|
||||
description = "Spring Framework"
|
||||
|
||||
apply plugin: "io.spring.nohttp"
|
||||
apply plugin: 'org.springframework.build.api-diff'
|
||||
|
||||
nohttp {
|
||||
source.exclude "**/test-output/**"
|
||||
allowlistFile = project.file("src/nohttp/allowlist.lines")
|
||||
def rootPath = file(rootDir).toPath()
|
||||
def projectDirs = allprojects.collect { it.projectDir } + "${rootDir}/buildSrc"
|
||||
projectDirs.forEach { dir ->
|
||||
[ 'bin', 'build', 'out', '.settings' ]
|
||||
.collect { rootPath.relativize(new File(dir, it).toPath()) }
|
||||
.forEach { source.exclude "$it/**" }
|
||||
[ '.classpath', '.project' ]
|
||||
.collect { rootPath.relativize(new File(dir, it).toPath()) }
|
||||
.forEach { source.exclude "$it" }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("checkstyleNohttp").configure {
|
||||
maxHeapSize = "1g"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
version=3.0.0
|
||||
build.stamp=RC2
|
||||
release.type=milestone
|
||||
natural.name=spring-framework
|
||||
project.name=Spring Framework
|
||||
project.key=SPR
|
||||
ivy.cache.dir=${basedir}/../ivy-cache
|
||||
integration.repo.dir=${basedir}/../integration-repo
|
||||
javadoc.exclude.package.names=org/springframework/samples/**
|
||||
javadoc.max.memory=256M
|
||||
test.vm.args=-Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
|
||||
compiler.args=-enableJavadoc -warn:none
|
||||
|
||||
# For when releasing
|
||||
#release.type=release
|
||||
#build.stamp=RELEASE
|
||||
|
||||
# For when releasing milestones
|
||||
#release.type=milestone
|
||||
#build.stamp=M1
|
||||
|
||||
# For development in trunk
|
||||
#release.type=integration
|
||||
#build.stamp=BUILD-SNAPSHOT
|
||||
@@ -0,0 +1,2 @@
|
||||
org.testng.version=5.10.0
|
||||
org.junit.version=4.7.0
|
||||
@@ -1,75 +0,0 @@
|
||||
# Spring Framework Build
|
||||
|
||||
This folder contains the custom plugins and conventions for the Spring Framework build.
|
||||
They are declared in the `build.gradle` file in this folder.
|
||||
|
||||
## Build Conventions
|
||||
|
||||
The `org.springframework.build.conventions` plugin applies all conventions to the Framework build:
|
||||
|
||||
* Configuring the Java compiler, see `JavaConventions`
|
||||
* Configuring the Kotlin compiler, see `KotlinConventions`
|
||||
* Configuring testing in the build with `TestConventions`
|
||||
|
||||
|
||||
## Build Plugins
|
||||
|
||||
### Optional dependencies
|
||||
|
||||
The `org.springframework.build.optional-dependencies` plugin creates a new `optional`
|
||||
Gradle configuration - it adds the dependencies to the project's compile and runtime classpath
|
||||
but doesn't affect the classpath of dependent projects.
|
||||
This plugin does not provide a `provided` configuration, as the native `compileOnly` and `testCompileOnly`
|
||||
configurations are preferred.
|
||||
|
||||
### API Diff
|
||||
|
||||
This plugin uses the [Gradle JApiCmp](https://github.com/melix/japicmp-gradle-plugin) plugin
|
||||
to generate API Diff reports for each Spring Framework module. This plugin is applied once on the root
|
||||
project and creates tasks in each framework module. Unlike previous versions of this part of the build,
|
||||
there is no need for checking out a specific tag. The plugin will fetch the JARs we want to compare the
|
||||
current working version with. You can generate the reports for all modules or a single module:
|
||||
|
||||
```
|
||||
./gradlew apiDiff -PbaselineVersion=5.1.0.RELEASE
|
||||
./gradlew :spring-core:apiDiff -PbaselineVersion=5.1.0.RELEASE
|
||||
```
|
||||
|
||||
The reports are located under `build/reports/api-diff/$OLDVERSION_to_$NEWVERSION/`.
|
||||
|
||||
|
||||
### RuntimeHints Java Agent
|
||||
|
||||
The `spring-core-test` project module contributes the `RuntimeHintsAgent` Java agent.
|
||||
|
||||
The `RuntimeHintsAgentPlugin` Gradle plugin creates a dedicated `"runtimeHintsTest"` test task for each project.
|
||||
This task will detect and execute [tests tagged](https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle)
|
||||
with the `"RuntimeHintsTests"` [JUnit tag](https://junit.org/junit5/docs/current/user-guide/#running-tests-tags).
|
||||
In the Spring Framework test suite, those are usually annotated with the `@EnabledIfRuntimeHintsAgent` annotation.
|
||||
|
||||
By default, the agent will instrument all classes located in the `"org.springframework"` package, as they are loaded.
|
||||
The `RuntimeHintsAgentExtension` allows to customize this using a DSL:
|
||||
|
||||
```groovy
|
||||
// this applies the `RuntimeHintsAgentPlugin` to the project
|
||||
plugins {
|
||||
id 'org.springframework.build.runtimehints-agent'
|
||||
}
|
||||
|
||||
// You can configure the agent to include and exclude packages from the instrumentation process.
|
||||
runtimeHintsAgent {
|
||||
includedPackages = ["org.springframework", "io.spring"]
|
||||
excludedPackages = ["org.example"]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// to use the test infrastructure, the project should also depend on the "spring-core-test" module
|
||||
testImplementation(project(":spring-core-test"))
|
||||
}
|
||||
```
|
||||
|
||||
With this configuration, `./gradlew runtimeHintsTest` will run all tests instrumented by this java agent.
|
||||
The global `./gradlew check` task depends on `runtimeHintsTest`.
|
||||
|
||||
NOTE: the "spring-core-test" module doesn't shade "spring-core" by design, so the agent should never instrument
|
||||
code that doesn't have "spring-core" on its classpath.
|
||||
@@ -1,45 +0,0 @@
|
||||
plugins {
|
||||
id 'java-gradle-plugin'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
ext {
|
||||
def propertiesFile = new File(new File("$projectDir").parentFile, "gradle.properties")
|
||||
propertiesFile.withInputStream {
|
||||
def properties = new Properties()
|
||||
properties.load(it)
|
||||
set("kotlinVersion", properties["kotlinVersion"])
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
|
||||
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}")
|
||||
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
|
||||
implementation "org.gradle:test-retry-gradle-plugin:1.4.1"
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
apiDiffPlugin {
|
||||
id = "org.springframework.build.api-diff"
|
||||
implementationClass = "org.springframework.build.api.ApiDiffPlugin"
|
||||
}
|
||||
conventionsPlugin {
|
||||
id = "org.springframework.build.conventions"
|
||||
implementationClass = "org.springframework.build.ConventionsPlugin"
|
||||
}
|
||||
optionalDependenciesPlugin {
|
||||
id = "org.springframework.build.optional-dependencies"
|
||||
implementationClass = "org.springframework.build.optional.OptionalDependenciesPlugin"
|
||||
}
|
||||
runtimeHintsAgentPlugin {
|
||||
id = "org.springframework.build.runtimehints-agent"
|
||||
implementationClass = "org.springframework.build.hint.RuntimeHintsAgentPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
org.gradle.caching=true
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin;
|
||||
|
||||
/**
|
||||
* Plugin to apply conventions to projects that are part of Spring Framework's build.
|
||||
* Conventions are applied in response to various plugins being applied.
|
||||
*
|
||||
* When the {@link JavaBasePlugin} is applied, the conventions in {@link TestConventions}
|
||||
* are applied.
|
||||
* When the {@link JavaBasePlugin} is applied, the conventions in {@link JavaConventions}
|
||||
* are applied.
|
||||
* When the {@link KotlinBasePlugin} is applied, the conventions in {@link KotlinConventions}
|
||||
* are applied.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class ConventionsPlugin implements Plugin<Project> {
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
new JavaConventions().apply(project);
|
||||
new KotlinConventions().apply(project);
|
||||
new TestConventions().apply(project);
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
|
||||
/**
|
||||
* {@link Plugin} that applies conventions for compiling Java sources in Spring Framework.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Sam Brannen
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class JavaConventions {
|
||||
|
||||
private static final List<String> COMPILER_ARGS;
|
||||
|
||||
private static final List<String> TEST_COMPILER_ARGS;
|
||||
|
||||
static {
|
||||
List<String> commonCompilerArgs = Arrays.asList(
|
||||
"-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann",
|
||||
"-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides",
|
||||
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options",
|
||||
"-parameters"
|
||||
);
|
||||
COMPILER_ARGS = new ArrayList<>();
|
||||
COMPILER_ARGS.addAll(commonCompilerArgs);
|
||||
COMPILER_ARGS.addAll(Arrays.asList(
|
||||
"-Xlint:varargs", "-Xlint:fallthrough", "-Xlint:rawtypes", "-Xlint:deprecation",
|
||||
"-Xlint:unchecked", "-Werror"
|
||||
));
|
||||
TEST_COMPILER_ARGS = new ArrayList<>();
|
||||
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
|
||||
TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes",
|
||||
"-Xlint:-deprecation", "-Xlint:-unchecked"));
|
||||
}
|
||||
|
||||
public void apply(Project project) {
|
||||
project.getPlugins().withType(JavaBasePlugin.class, javaPlugin -> applyJavaCompileConventions(project));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the common Java compiler options for main sources, test fixture sources, and
|
||||
* test sources.
|
||||
* @param project the current project
|
||||
*/
|
||||
private void applyJavaCompileConventions(Project project) {
|
||||
project.getTasks().withType(JavaCompile.class)
|
||||
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME))
|
||||
.forEach(compileTask -> {
|
||||
compileTask.getOptions().setCompilerArgs(COMPILER_ARGS);
|
||||
compileTask.getOptions().setEncoding("UTF-8");
|
||||
});
|
||||
project.getTasks().withType(JavaCompile.class)
|
||||
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME)
|
||||
|| compileTask.getName().equals("compileTestFixturesJava"))
|
||||
.forEach(compileTask -> {
|
||||
compileTask.getOptions().setCompilerArgs(TEST_COMPILER_ARGS);
|
||||
compileTask.getOptions().setEncoding("UTF-8");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions;
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile;
|
||||
|
||||
/**
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class KotlinConventions {
|
||||
|
||||
void apply(Project project) {
|
||||
project.getPlugins().withId("org.jetbrains.kotlin.jvm",
|
||||
(plugin) -> project.getTasks().withType(KotlinCompile.class, this::configure));
|
||||
}
|
||||
|
||||
private void configure(KotlinCompile compile) {
|
||||
KotlinJvmOptions kotlinOptions = compile.getKotlinOptions();
|
||||
kotlinOptions.setApiVersion("1.7");
|
||||
kotlinOptions.setLanguageVersion("1.7");
|
||||
kotlinOptions.setJvmTarget("17");
|
||||
kotlinOptions.setJavaParameters(true);
|
||||
kotlinOptions.setAllWarningsAsErrors(true);
|
||||
List<String> freeCompilerArgs = new ArrayList<>(compile.getKotlinOptions().getFreeCompilerArgs());
|
||||
freeCompilerArgs.addAll(List.of("-Xsuppress-version-warnings", "-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn"));
|
||||
compile.getKotlinOptions().setFreeCompilerArgs(freeCompilerArgs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.gradle.api.tasks.testing.Test;
|
||||
import org.gradle.testretry.TestRetryPlugin;
|
||||
import org.gradle.testretry.TestRetryTaskExtension;
|
||||
|
||||
/**
|
||||
* Conventions that are applied in the presence of the {@link JavaBasePlugin}. When the
|
||||
* plugin is applied:
|
||||
* <ul>
|
||||
* <li>The {@link TestRetryPlugin Test Retry} plugins is applied so that flaky tests
|
||||
* are retried 3 times when running on the CI.
|
||||
* </ul>
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class TestConventions {
|
||||
|
||||
void apply(Project project) {
|
||||
project.getPlugins().withType(JavaBasePlugin.class, (java) -> configureTestConventions(project));
|
||||
}
|
||||
|
||||
private void configureTestConventions(Project project) {
|
||||
project.getPlugins().apply(TestRetryPlugin.class);
|
||||
project.getTasks().withType(Test.class,
|
||||
(test) -> project.getPlugins().withType(TestRetryPlugin.class, (testRetryPlugin) -> {
|
||||
TestRetryTaskExtension testRetry = test.getExtensions().getByType(TestRetryTaskExtension.class);
|
||||
testRetry.getFailOnPassedAfterRetry().set(true);
|
||||
testRetry.getMaxRetries().set(isCi() ? 3 : 0);
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean isCi() {
|
||||
return Boolean.parseBoolean(System.getenv("CI"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.build.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.champeau.gradle.japicmp.JapicmpPlugin;
|
||||
import me.champeau.gradle.japicmp.JapicmpTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.jvm.tasks.Jar;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* {@link Plugin} that applies the {@code "japicmp-gradle-plugin"}
|
||||
* and create tasks for all subprojects named {@code "spring-*"}, diffing the public API one by one
|
||||
* and creating the reports in {@code "build/reports/api-diff/$OLDVERSION_to_$NEWVERSION/"}.
|
||||
* <p>{@code "./gradlew apiDiff -PbaselineVersion=5.1.0.RELEASE"} will output the
|
||||
* reports for the API diff between the baseline version and the current one for all modules.
|
||||
* You can limit the report to a single module with
|
||||
* {@code "./gradlew :spring-core:apiDiff -PbaselineVersion=5.1.0.RELEASE"}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class ApiDiffPlugin implements Plugin<Project> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ApiDiffPlugin.class);
|
||||
|
||||
public static final String TASK_NAME = "apiDiff";
|
||||
|
||||
private static final String BASELINE_VERSION_PROPERTY = "baselineVersion";
|
||||
|
||||
private static final List<String> PACKAGE_INCLUDES = Collections.singletonList("org.springframework.*");
|
||||
|
||||
private static final URI SPRING_MILESTONE_REPOSITORY = URI.create("https://repo.spring.io/milestone");
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
if (project.hasProperty(BASELINE_VERSION_PROPERTY) && project.equals(project.getRootProject())) {
|
||||
project.getPluginManager().apply(JapicmpPlugin.class);
|
||||
project.getPlugins().withType(JapicmpPlugin.class,
|
||||
plugin -> applyApiDiffConventions(project));
|
||||
}
|
||||
}
|
||||
|
||||
private void applyApiDiffConventions(Project project) {
|
||||
String baselineVersion = project.property(BASELINE_VERSION_PROPERTY).toString();
|
||||
project.subprojects(subProject -> {
|
||||
if (subProject.getName().startsWith("spring-")) {
|
||||
createApiDiffTask(baselineVersion, subProject);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createApiDiffTask(String baselineVersion, Project project) {
|
||||
if (isProjectEligible(project)) {
|
||||
// Add Spring Milestone repository for generating diffs against previous milestones
|
||||
project.getRootProject()
|
||||
.getRepositories()
|
||||
.maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(SPRING_MILESTONE_REPOSITORY));
|
||||
JapicmpTask apiDiff = project.getTasks().create(TASK_NAME, JapicmpTask.class);
|
||||
apiDiff.setDescription("Generates an API diff report with japicmp");
|
||||
apiDiff.setGroup(JavaBasePlugin.DOCUMENTATION_GROUP);
|
||||
|
||||
apiDiff.setOldClasspath(createBaselineConfiguration(baselineVersion, project));
|
||||
TaskProvider<Jar> jar = project.getTasks().withType(Jar.class).named("jar");
|
||||
apiDiff.setNewArchives(project.getLayout().files(jar.get().getArchiveFile().get().getAsFile()));
|
||||
apiDiff.setNewClasspath(getRuntimeClassPath(project));
|
||||
apiDiff.setPackageIncludes(PACKAGE_INCLUDES);
|
||||
apiDiff.setOnlyModified(true);
|
||||
apiDiff.setIgnoreMissingClasses(true);
|
||||
// Ignore Kotlin metadata annotations since they contain
|
||||
// illegal HTML characters and fail the report generation
|
||||
apiDiff.setAnnotationExcludes(Collections.singletonList("@kotlin.Metadata"));
|
||||
|
||||
apiDiff.setHtmlOutputFile(getOutputFile(baselineVersion, project));
|
||||
|
||||
apiDiff.dependsOn(project.getTasks().getByName("jar"));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProjectEligible(Project project) {
|
||||
return project.getPlugins().hasPlugin(JavaPlugin.class)
|
||||
&& project.getPlugins().hasPlugin(MavenPublishPlugin.class);
|
||||
}
|
||||
|
||||
private Configuration createBaselineConfiguration(String baselineVersion, Project project) {
|
||||
String baseline = String.join(":",
|
||||
project.getGroup().toString(), project.getName(), baselineVersion);
|
||||
Dependency baselineDependency = project.getDependencies().create(baseline + "@jar");
|
||||
Configuration baselineConfiguration = project.getRootProject().getConfigurations().detachedConfiguration(baselineDependency);
|
||||
try {
|
||||
// eagerly resolve the baseline configuration to check whether this is a new Spring module
|
||||
baselineConfiguration.resolve();
|
||||
return baselineConfiguration;
|
||||
}
|
||||
catch (GradleException exception) {
|
||||
logger.warn("Could not resolve {} - assuming this is a new Spring module.", baseline);
|
||||
}
|
||||
return project.getRootProject().getConfigurations().detachedConfiguration();
|
||||
}
|
||||
|
||||
private Configuration getRuntimeClassPath(Project project) {
|
||||
return project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
|
||||
}
|
||||
|
||||
private File getOutputFile(String baseLineVersion, Project project) {
|
||||
Path outDir = Paths.get(project.getRootProject().getBuildDir().getAbsolutePath(),
|
||||
"reports", "api-diff",
|
||||
baseLineVersion + "_to_" + project.getRootProject().getVersion());
|
||||
return project.file(outDir.resolve(project.getName() + ".html").toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build.hint;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
|
||||
/**
|
||||
* Entry point to the DSL extension for the {@link RuntimeHintsAgentPlugin} Gradle plugin.
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class RuntimeHintsAgentExtension {
|
||||
|
||||
private final SetProperty<String> includedPackages;
|
||||
|
||||
private final SetProperty<String> excludedPackages;
|
||||
|
||||
public RuntimeHintsAgentExtension(ObjectFactory objectFactory) {
|
||||
this.includedPackages = objectFactory.setProperty(String.class).convention(Collections.singleton("org.springframework"));
|
||||
this.excludedPackages = objectFactory.setProperty(String.class).convention(Collections.emptySet());
|
||||
}
|
||||
|
||||
public SetProperty<String> getIncludedPackages() {
|
||||
return this.includedPackages;
|
||||
}
|
||||
|
||||
public SetProperty<String> getExcludedPackages() {
|
||||
return this.excludedPackages;
|
||||
}
|
||||
|
||||
String asJavaAgentArgument() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
this.includedPackages.get().forEach(packageName -> builder.append('+').append(packageName).append(','));
|
||||
this.excludedPackages.get().forEach(packageName -> builder.append('-').append(packageName).append(','));
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build.hint;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.tasks.bundling.Jar;
|
||||
import org.gradle.api.tasks.testing.Test;
|
||||
|
||||
/**
|
||||
* {@link Plugin} that configures the {@code RuntimeHints} Java agent to test tasks.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class RuntimeHintsAgentPlugin implements Plugin<Project> {
|
||||
|
||||
public static final String RUNTIMEHINTS_TEST_TASK = "runtimeHintsTest";
|
||||
private static final String EXTENSION_NAME = "runtimeHintsAgent";
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
|
||||
project.getPlugins().withType(JavaPlugin.class, javaPlugin -> {
|
||||
RuntimeHintsAgentExtension agentExtension = project.getExtensions().create(EXTENSION_NAME,
|
||||
RuntimeHintsAgentExtension.class, project.getObjects());
|
||||
Test agentTest = project.getTasks().create(RUNTIMEHINTS_TEST_TASK, Test.class, test -> {
|
||||
test.useJUnitPlatform(options -> {
|
||||
options.includeTags("RuntimeHintsTests");
|
||||
});
|
||||
test.include("**/*Tests.class", "**/*Test.class");
|
||||
test.systemProperty("java.awt.headless", "true");
|
||||
});
|
||||
project.afterEvaluate(p -> {
|
||||
Jar jar = project.getRootProject().project("spring-core-test").getTasks().withType(Jar.class).named("jar").get();
|
||||
agentTest.jvmArgs("-javaagent:" + jar.getArchiveFile().get().getAsFile() + "=" + agentExtension.asJavaAgentArgument());
|
||||
});
|
||||
project.getTasks().getByName("check", task -> task.dependsOn(agentTest));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.build.optional;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
|
||||
/**
|
||||
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
|
||||
* {@code optional} configuration. The {@code optional} configuration is part of the
|
||||
* project's compile and runtime classpaths but does not affect the classpath of
|
||||
* dependent projects.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class OptionalDependenciesPlugin implements Plugin<Project> {
|
||||
|
||||
/**
|
||||
* Name of the {@code optional} configuration.
|
||||
*/
|
||||
public static final String OPTIONAL_CONFIGURATION_NAME = "optional";
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
Configuration optional = project.getConfigurations().create("optional");
|
||||
optional.setCanBeConsumed(false);
|
||||
optional.setCanBeResolved(false);
|
||||
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
|
||||
SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class)
|
||||
.getSourceSets();
|
||||
sourceSets.all((sourceSet) -> {
|
||||
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
|
||||
project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package org.springframework.build.shadow;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.component.ModuleComponentSelector;
|
||||
import org.gradle.api.artifacts.query.ArtifactResolutionQuery;
|
||||
import org.gradle.api.artifacts.result.ArtifactResolutionResult;
|
||||
import org.gradle.api.artifacts.result.ComponentArtifactsResult;
|
||||
import org.gradle.api.artifacts.result.DependencyResult;
|
||||
import org.gradle.api.artifacts.result.ResolutionResult;
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCopyDetails;
|
||||
import org.gradle.api.file.FileTree;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.jvm.JvmLibrary;
|
||||
import org.gradle.language.base.artifact.SourcesArtifact;
|
||||
|
||||
/**
|
||||
* Gradle task to add source from shadowed jars into our own source jars.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ShadowSource extends DefaultTask {
|
||||
|
||||
private final DirectoryProperty outputDirectory = getProject().getObjects().directoryProperty();
|
||||
|
||||
private List<Configuration> configurations = new ArrayList<>();
|
||||
|
||||
private final List<Relocation> relocations = new ArrayList<>();
|
||||
|
||||
|
||||
@Classpath
|
||||
@Optional
|
||||
public List<Configuration> getConfigurations() {
|
||||
return this.configurations;
|
||||
}
|
||||
|
||||
public void setConfigurations(List<Configuration> configurations) {
|
||||
this.configurations = configurations;
|
||||
}
|
||||
|
||||
@Nested
|
||||
public List<Relocation> getRelocations() {
|
||||
return this.relocations;
|
||||
}
|
||||
|
||||
public void relocate(String pattern, String destination) {
|
||||
this.relocations.add(new Relocation(pattern, destination));
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
DirectoryProperty getOutputDirectory() {
|
||||
return this.outputDirectory;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void syncSourceJarFiles() {
|
||||
sync(getSourceJarFiles());
|
||||
}
|
||||
|
||||
private List<File> getSourceJarFiles() {
|
||||
List<File> sourceJarFiles = new ArrayList<>();
|
||||
for (Configuration configuration : this.configurations) {
|
||||
ResolutionResult resolutionResult = configuration.getIncoming().getResolutionResult();
|
||||
resolutionResult.getRootComponent().get().getDependencies().forEach(dependency -> {
|
||||
Set<ComponentArtifactsResult> artifactsResults = resolveSourceArtifacts(dependency);
|
||||
for (ComponentArtifactsResult artifactResult : artifactsResults) {
|
||||
artifactResult.getArtifacts(SourcesArtifact.class).forEach(sourceArtifact -> {
|
||||
sourceJarFiles.add(((ResolvedArtifactResult) sourceArtifact).getFile());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return Collections.unmodifiableList(sourceJarFiles);
|
||||
}
|
||||
|
||||
private Set<ComponentArtifactsResult> resolveSourceArtifacts(DependencyResult dependency) {
|
||||
ModuleComponentSelector componentSelector = (ModuleComponentSelector) dependency.getRequested();
|
||||
ArtifactResolutionQuery query = getProject().getDependencies().createArtifactResolutionQuery()
|
||||
.forModule(componentSelector.getGroup(), componentSelector.getModule(), componentSelector.getVersion());
|
||||
return executeQuery(query).getResolvedComponents();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ArtifactResolutionResult executeQuery(ArtifactResolutionQuery query) {
|
||||
return query.withArtifacts(JvmLibrary.class, SourcesArtifact.class).execute();
|
||||
}
|
||||
|
||||
private void sync(List<File> sourceJarFiles) {
|
||||
getProject().sync(spec -> {
|
||||
spec.into(this.outputDirectory);
|
||||
spec.eachFile(this::relocateFile);
|
||||
spec.filter(this::transformContent);
|
||||
spec.exclude("META-INF/**");
|
||||
spec.setIncludeEmptyDirs(false);
|
||||
sourceJarFiles.forEach(sourceJar -> spec.from(zipTree(sourceJar)));
|
||||
});
|
||||
}
|
||||
|
||||
private void relocateFile(FileCopyDetails details) {
|
||||
String path = details.getPath();
|
||||
for (Relocation relocation : this.relocations) {
|
||||
path = relocation.relocatePath(path);
|
||||
}
|
||||
details.setPath(path);
|
||||
}
|
||||
|
||||
private String transformContent(String content) {
|
||||
for (Relocation relocation : this.relocations) {
|
||||
content = relocation.transformContent(content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private FileTree zipTree(File sourceJar) {
|
||||
return getProject().zipTree(sourceJar);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A single relocation.
|
||||
*/
|
||||
static class Relocation {
|
||||
|
||||
private final String pattern;
|
||||
|
||||
private final String pathPattern;
|
||||
|
||||
private final String destination;
|
||||
|
||||
private final String pathDestination;
|
||||
|
||||
|
||||
Relocation(String pattern, String destination) {
|
||||
this.pattern = pattern;
|
||||
this.pathPattern = pattern.replace('.', '/');
|
||||
this.destination = destination;
|
||||
this.pathDestination = destination.replace('.', '/');
|
||||
}
|
||||
|
||||
|
||||
@Input
|
||||
public String getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
@Input
|
||||
public String getDestination() {
|
||||
return this.destination;
|
||||
}
|
||||
|
||||
String relocatePath(String path) {
|
||||
return path.replace(this.pathPattern, this.pathDestination);
|
||||
}
|
||||
|
||||
public String transformContent(String content) {
|
||||
return content.replaceAll("\\b" + this.pattern, this.destination);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# properties used by Bamboo build plan at http://build.springframework.org/build/admin/buildConfiguration.action?buildKey=SPR-TRUNKQUICK
|
||||
# run in conjunction with ANT_OPTS='-XX:MaxPermSize=512m -Xmx1024m'
|
||||
compiler.args=-enableJavadoc -warn:none
|
||||
java.awt.headless=true
|
||||
ci.build=true
|
||||
test.vm.args=-XX:MaxPermSize=512m -Xmx1024m
|
||||
@@ -1,57 +0,0 @@
|
||||
== Spring Framework Concourse pipeline
|
||||
|
||||
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
|
||||
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
|
||||
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x[Spring Framework 6.0.x].
|
||||
|
||||
=== Setting up your development environment
|
||||
|
||||
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
|
||||
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
|
||||
|
||||
You can then login with the instance using:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly -t spring login -n spring-framework -c https://ci.spring.io
|
||||
----
|
||||
|
||||
Once logged in, you should get something like:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly ts
|
||||
name url team expiry
|
||||
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
|
||||
----
|
||||
|
||||
=== Pipeline configuration and structure
|
||||
|
||||
The build pipelines are described in `pipeline.yml` file.
|
||||
|
||||
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
|
||||
|
||||
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
|
||||
|
||||
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
|
||||
|
||||
You'll find in this folder the following resources:
|
||||
|
||||
* `pipeline.yml` the build pipeline
|
||||
* `parameters.yml` the build parameters used for the pipeline
|
||||
* `images/` holds the container images definitions used in this pipeline
|
||||
* `scripts/` holds the build scripts that ship within the CI container images
|
||||
* `tasks` contains the task definitions used in the main `pipeline.yml`
|
||||
|
||||
=== Updating the build pipeline
|
||||
|
||||
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
|
||||
|
||||
The pipeline can be deployed using the following command:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly -t spring set-pipeline -p spring-framework-6.0.x -c ci/pipeline.yml -l ci/parameters.yml
|
||||
----
|
||||
|
||||
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
|
||||
@@ -1,20 +0,0 @@
|
||||
changelog:
|
||||
repository: spring-projects/spring-framework
|
||||
sections:
|
||||
- title: ":star: New Features"
|
||||
labels:
|
||||
- "type: enhancement"
|
||||
- title: ":lady_beetle: Bug Fixes"
|
||||
labels:
|
||||
- "type: bug"
|
||||
- "type: regression"
|
||||
- title: ":notebook_with_decorative_cover: Documentation"
|
||||
labels:
|
||||
- "type: documentation"
|
||||
- title: ":hammer: Dependency Upgrades"
|
||||
sort: "title"
|
||||
labels:
|
||||
- "type: dependency-upgrade"
|
||||
contributors:
|
||||
exclude:
|
||||
names: ["bclozel", "jhoeller", "poutsma", "rstoyanchev", "sbrannen", "sdeleuze", "snicoll"]
|
||||
@@ -1,10 +0,0 @@
|
||||
logging:
|
||||
level:
|
||||
io.spring.concourse: DEBUG
|
||||
spring:
|
||||
main:
|
||||
banner-mode: off
|
||||
sonatype:
|
||||
exclude:
|
||||
- 'build-info\.json'
|
||||
- '.*\.zip'
|
||||
@@ -1,21 +0,0 @@
|
||||
== CI Images
|
||||
|
||||
These images are used by CI to run the actual builds.
|
||||
|
||||
To build the image locally run the following from this directory:
|
||||
|
||||
----
|
||||
$ docker build --no-cache -f <image-folder>/Dockerfile .
|
||||
----
|
||||
|
||||
For example
|
||||
|
||||
----
|
||||
$ docker build --no-cache -f spring-framework-ci-image/Dockerfile .
|
||||
----
|
||||
|
||||
To test run:
|
||||
|
||||
----
|
||||
$ docker run -it --entrypoint /bin/bash <SHA>
|
||||
----
|
||||
@@ -1,12 +0,0 @@
|
||||
FROM ubuntu:focal-20220922
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
RUN ./setup.sh
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk/java17
|
||||
ENV JDK17 /opt/openjdk/java17
|
||||
ENV JDK18 /opt/openjdk/java18
|
||||
ENV JDK19 /opt/openjdk/java19
|
||||
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
java17)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.5+8/bellsoft-jdk17.0.5+8-linux-amd64.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/18.0.2.1%2B1/bellsoft-jdk18.0.2.1+1-linux-amd64.tar.gz"
|
||||
;;
|
||||
java19)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/19.0.1%2B11/bellsoft-jdk19.0.1+11-linux-amd64.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
###########################################################
|
||||
# UTILS
|
||||
###########################################################
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
|
||||
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
|
||||
dpkg-reconfigure --frontend noninteractive tzdata
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
###########################################################
|
||||
|
||||
mkdir -p /opt/openjdk
|
||||
pushd /opt/openjdk > /dev/null
|
||||
for jdk in java17 java18 java19
|
||||
do
|
||||
JDK_URL=$( /get-jdk-url.sh $jdk )
|
||||
mkdir $jdk
|
||||
pushd $jdk > /dev/null
|
||||
curl -L ${JDK_URL} | tar zx --strip-components=1
|
||||
test -f bin/java
|
||||
test -f bin/javac
|
||||
popd > /dev/null
|
||||
done
|
||||
popd
|
||||
|
||||
###########################################################
|
||||
# GRADLE ENTERPRISE
|
||||
###########################################################
|
||||
cd /
|
||||
mkdir ~/.gradle
|
||||
echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
|
||||
@@ -1,14 +0,0 @@
|
||||
github-repo: "https://github.com/spring-projects/spring-framework.git"
|
||||
github-repo-name: "spring-projects/spring-framework"
|
||||
sonatype-staging-profile: "org.springframework"
|
||||
docker-hub-organization: "springci"
|
||||
artifactory-server: "https://repo.spring.io"
|
||||
branch: "main"
|
||||
milestone: "6.0.x"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
concourse-url: "https://ci.spring.io"
|
||||
registry-mirror-host: docker.repo.spring.io
|
||||
registry-mirror-username: ((artifactory-username))
|
||||
registry-mirror-password: ((artifactory-password))
|
||||
task-timeout: 1h00m
|
||||
@@ -1,480 +0,0 @@
|
||||
anchors:
|
||||
git-repo-resource-source: &git-repo-resource-source
|
||||
uri: ((github-repo))
|
||||
username: ((github-username))
|
||||
password: ((github-ci-release-token))
|
||||
branch: ((branch))
|
||||
gradle-enterprise-task-params: &gradle-enterprise-task-params
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
sonatype-task-params: &sonatype-task-params
|
||||
SONATYPE_USERNAME: ((sonatype-username))
|
||||
SONATYPE_PASSWORD: ((sonatype-password))
|
||||
SONATYPE_URL: ((sonatype-url))
|
||||
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
|
||||
artifactory-task-params: &artifactory-task-params
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
ARTIFACTORY_PASSWORD: ((artifactory-password))
|
||||
build-project-task-params: &build-project-task-params
|
||||
BRANCH: ((branch))
|
||||
<<: *gradle-enterprise-task-params
|
||||
docker-resource-source: &docker-resource-source
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: ((milestone))
|
||||
registry-mirror-vars: ®istry-mirror-vars
|
||||
registry-mirror-host: ((registry-mirror-host))
|
||||
registry-mirror-username: ((registry-mirror-username))
|
||||
registry-mirror-password: ((registry-mirror-password))
|
||||
slack-fail-params: &slack-fail-params
|
||||
text: >
|
||||
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
|
||||
[$TEXT_FILE_CONTENT]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
changelog-task-params: &changelog-task-params
|
||||
name: generated-changelog/tag
|
||||
tag: generated-changelog/tag
|
||||
body: generated-changelog/changelog.md
|
||||
github-task-params: &github-task-params
|
||||
GITHUB_USERNAME: ((github-username))
|
||||
GITHUB_TOKEN: ((github-ci-release-token))
|
||||
|
||||
resource_types:
|
||||
- name: registry-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/registry-image-resource
|
||||
tag: 1.5.0
|
||||
- name: artifactory-resource
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/artifactory-resource
|
||||
tag: 0.0.17
|
||||
- name: github-release
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/github-release-resource
|
||||
tag: 1.5.5
|
||||
- name: github-status-resource
|
||||
type: registry-image
|
||||
source:
|
||||
repository: dpb587/github-status-resource
|
||||
tag: master
|
||||
- name: pull-request
|
||||
type: registry-image
|
||||
source:
|
||||
repository: teliaoss/github-pr-resource
|
||||
tag: v0.23.0
|
||||
- name: slack-notification
|
||||
type: registry-image
|
||||
source:
|
||||
repository: cfcommunity/slack-notification-resource
|
||||
tag: latest
|
||||
resources:
|
||||
- name: git-repo
|
||||
type: git
|
||||
icon: github
|
||||
source:
|
||||
<<: *git-repo-resource-source
|
||||
- name: ci-images-git-repo
|
||||
type: git
|
||||
icon: github
|
||||
source:
|
||||
uri: ((github-repo))
|
||||
branch: ((branch))
|
||||
paths: ["ci/images/*"]
|
||||
- name: ci-image
|
||||
type: registry-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
repository: ((docker-hub-organization))/spring-framework-ci
|
||||
- name: every-morning
|
||||
type: time
|
||||
icon: alarm
|
||||
source:
|
||||
start: 8:00 AM
|
||||
stop: 9:00 AM
|
||||
location: Europe/Vienna
|
||||
- name: artifactory-repo
|
||||
type: artifactory-resource
|
||||
icon: package-variant
|
||||
source:
|
||||
uri: ((artifactory-server))
|
||||
username: ((artifactory-username))
|
||||
password: ((artifactory-password))
|
||||
build_name: ((build-name))
|
||||
- name: git-pull-request
|
||||
type: pull-request
|
||||
icon: source-pull
|
||||
source:
|
||||
access_token: ((github-ci-pull-request-token))
|
||||
repository: ((github-repo-name))
|
||||
base_branch: ((branch))
|
||||
ignore_paths: ["ci/*"]
|
||||
- name: repo-status-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: build
|
||||
- name: repo-status-jdk18-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk18-build
|
||||
- name: repo-status-jdk19-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk19-build
|
||||
- name: slack-alert
|
||||
type: slack-notification
|
||||
icon: slack
|
||||
source:
|
||||
url: ((slack-webhook-url))
|
||||
- name: github-pre-release
|
||||
type: github-release
|
||||
icon: briefcase-download-outline
|
||||
source:
|
||||
owner: spring-projects
|
||||
repository: spring-framework
|
||||
access_token: ((github-ci-release-token))
|
||||
pre_release: true
|
||||
release: false
|
||||
- name: github-release
|
||||
type: github-release
|
||||
icon: briefcase-download
|
||||
source:
|
||||
owner: spring-projects
|
||||
repository: spring-framework
|
||||
access_token: ((github-ci-release-token))
|
||||
pre_release: false
|
||||
jobs:
|
||||
- name: build-ci-images
|
||||
plan:
|
||||
- get: git-repo
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- task: build-ci-image
|
||||
privileged: true
|
||||
file: git-repo/ci/tasks/build-ci-image.yml
|
||||
output_mapping:
|
||||
image: ci-image
|
||||
vars:
|
||||
ci-image-name: ci-image
|
||||
<<: *registry-mirror-vars
|
||||
- put: ci-image
|
||||
params:
|
||||
image: ci-image/image.tar
|
||||
- name: build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: true
|
||||
- put: repo-status-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: build-project
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/build-project.yml
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- put: artifactory-repo
|
||||
params: &artifactory-params
|
||||
signing_key: ((signing-key))
|
||||
signing_passphrase: ((signing-passphrase))
|
||||
repo: libs-snapshot-local
|
||||
folder: distribution-repository
|
||||
build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}"
|
||||
build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}"
|
||||
disable_checksum_uploads: true
|
||||
threads: 8
|
||||
artifact_set:
|
||||
- include:
|
||||
- "/**/framework-docs-*.zip"
|
||||
properties:
|
||||
"zip.name": "spring-framework"
|
||||
"zip.displayname": "Spring Framework"
|
||||
"zip.deployed": "false"
|
||||
- include:
|
||||
- "/**/framework-docs-*-docs.zip"
|
||||
properties:
|
||||
"zip.type": "docs"
|
||||
- include:
|
||||
- "/**/framework-docs-*-dist.zip"
|
||||
properties:
|
||||
"zip.type": "dist"
|
||||
- include:
|
||||
- "/**/framework-docs-*-schema.zip"
|
||||
properties:
|
||||
"zip.type": "schema"
|
||||
get_params:
|
||||
threads: 8
|
||||
- name: jdk18-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk18-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
TEST_TOOLCHAIN: 18
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk18-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk18-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk19-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk19-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
TEST_TOOLCHAIN: 19
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk19-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk19-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: build-pull-requests
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
resource: git-pull-request
|
||||
trigger: true
|
||||
version: every
|
||||
- do:
|
||||
- put: git-pull-request
|
||||
params:
|
||||
path: git-repo
|
||||
status: pending
|
||||
- task: build-pr
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/build-pr.yml
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
on_success:
|
||||
put: git-pull-request
|
||||
params:
|
||||
path: git-repo
|
||||
status: success
|
||||
on_failure:
|
||||
put: git-pull-request
|
||||
params:
|
||||
path: git-repo
|
||||
status: failure
|
||||
- name: stage-milestone
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-milestone
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-milestone]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
<<: *artifactory-task-params
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
<<: *github-task-params
|
||||
- put: github-pre-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
- name: stage-rc
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-rc
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-rc]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *artifactory-task-params
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
<<: *github-task-params
|
||||
- put: github-pre-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
- name: stage-release
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *gradle-enterprise-task-params
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-release
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-release]
|
||||
params:
|
||||
download_artifacts: true
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *artifactory-task-params
|
||||
<<: *sonatype-task-params
|
||||
- name: create-github-release
|
||||
serial: true
|
||||
plan:
|
||||
- get: ci-image
|
||||
- get: git-repo
|
||||
- get: artifactory-repo
|
||||
trigger: true
|
||||
passed: [promote-release]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: generate-changelog
|
||||
file: git-repo/ci/tasks/generate-changelog.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
<<: *github-task-params
|
||||
- put: github-release
|
||||
params:
|
||||
<<: *changelog-task-params
|
||||
|
||||
groups:
|
||||
- name: "builds"
|
||||
jobs: ["build", "jdk18-build", "jdk19-build"]
|
||||
- name: "releases"
|
||||
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
|
||||
- name: "ci-images"
|
||||
jobs: ["build-ci-images"]
|
||||
- name: "pull-requests"
|
||||
jobs: [ "build-pull-requests" ]
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
|
||||
popd > /dev/null
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
repository=$(pwd)/distribution-repository
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
|
||||
popd > /dev/null
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17,JDK18 \
|
||||
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
|
||||
popd > /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
source /opt/concourse-java.sh
|
||||
setup_symlinks
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
CONFIG_DIR=git-repo/ci/config
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
|
||||
java -jar /github-changelog-generator.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/changelog-generator.yml \
|
||||
${version} generated-changelog/changelog.md
|
||||
|
||||
echo ${version} > generated-changelog/version
|
||||
echo v${version} > generated-changelog/tag
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CONFIG_DIR=git-repo/ci/config
|
||||
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
|
||||
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
echo "Promotion complete"
|
||||
echo $version > version/version
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
repository=$(pwd)/distribution-repository
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
git fetch --tags --all > /dev/null
|
||||
popd > /dev/null
|
||||
|
||||
git clone git-repo stage-git-repo > /dev/null
|
||||
|
||||
pushd stage-git-repo > /dev/null
|
||||
|
||||
snapshotVersion=$( awk -F '=' '$1 == "version" { print $2 }' gradle.properties )
|
||||
if [[ $RELEASE_TYPE = "M" ]]; then
|
||||
stageVersion=$( get_next_milestone_release $snapshotVersion)
|
||||
nextVersion=$snapshotVersion
|
||||
elif [[ $RELEASE_TYPE = "RC" ]]; then
|
||||
stageVersion=$( get_next_rc_release $snapshotVersion)
|
||||
nextVersion=$snapshotVersion
|
||||
elif [[ $RELEASE_TYPE = "RELEASE" ]]; then
|
||||
stageVersion=$( get_next_release $snapshotVersion)
|
||||
nextVersion=$( bump_version_number $snapshotVersion)
|
||||
else
|
||||
echo "Unknown release type $RELEASE_TYPE" >&2; exit 1;
|
||||
fi
|
||||
|
||||
echo "Staging $stageVersion (next version will be $nextVersion)"
|
||||
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
|
||||
|
||||
git config user.name "Spring Builds" > /dev/null
|
||||
git config user.email "spring-builds@users.noreply.github.com" > /dev/null
|
||||
git add gradle.properties > /dev/null
|
||||
git commit -m"Release v$stageVersion" > /dev/null
|
||||
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
|
||||
|
||||
./gradlew --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
|
||||
|
||||
git reset --hard HEAD^ > /dev/null
|
||||
if [[ $nextVersion != $snapshotVersion ]]; then
|
||||
echo "Setting next development version (v$nextVersion)"
|
||||
sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties
|
||||
git add gradle.properties > /dev/null
|
||||
git commit -m"Next development version (v$nextVersion)" > /dev/null
|
||||
fi;
|
||||
|
||||
echo "Staging Complete"
|
||||
|
||||
popd > /dev/null
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/oci-build-task
|
||||
tag: 0.10.0
|
||||
registry_mirror:
|
||||
host: ((registry-mirror-host))
|
||||
username: ((registry-mirror-username))
|
||||
password: ((registry-mirror-password))
|
||||
inputs:
|
||||
- name: ci-images-git-repo
|
||||
outputs:
|
||||
- name: image
|
||||
caches:
|
||||
- path: ci-image-cache
|
||||
params:
|
||||
CONTEXT: ci-images-git-repo/ci/images
|
||||
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
|
||||
DOCKER_HUB_AUTH: ((docker-hub-auth))
|
||||
run:
|
||||
path: /bin/sh
|
||||
args:
|
||||
- "-c"
|
||||
- |
|
||||
mkdir -p /root/.docker
|
||||
cat > /root/.docker/config.json <<EOF
|
||||
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
|
||||
EOF
|
||||
build
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
caches:
|
||||
- path: gradle
|
||||
params:
|
||||
BRANCH:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
run:
|
||||
path: bash
|
||||
args:
|
||||
- -ec
|
||||
- |
|
||||
${PWD}/git-repo/ci/scripts/build-pr.sh
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: distribution-repository
|
||||
- name: git-repo
|
||||
caches:
|
||||
- path: gradle
|
||||
params:
|
||||
BRANCH:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
run:
|
||||
path: bash
|
||||
args:
|
||||
- -ec
|
||||
- |
|
||||
${PWD}/git-repo/ci/scripts/build-project.sh
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: distribution-repository
|
||||
- name: git-repo
|
||||
caches:
|
||||
- path: gradle
|
||||
params:
|
||||
BRANCH:
|
||||
CI: true
|
||||
MAIN_TOOLCHAIN:
|
||||
TEST_TOOLCHAIN:
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
run:
|
||||
path: bash
|
||||
args:
|
||||
- -ec
|
||||
- |
|
||||
${PWD}/git-repo/ci/scripts/check-project.sh
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/github-changelog-generator
|
||||
tag: '0.0.8'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
outputs:
|
||||
- name: generated-changelog
|
||||
params:
|
||||
GITHUB_ORGANIZATION:
|
||||
GITHUB_REPO:
|
||||
GITHUB_USERNAME:
|
||||
GITHUB_TOKEN:
|
||||
RELEASE_TYPE:
|
||||
run:
|
||||
path: git-repo/ci/scripts/generate-changelog.sh
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/concourse-release-scripts
|
||||
tag: '0.3.4'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
outputs:
|
||||
- name: version
|
||||
params:
|
||||
RELEASE_TYPE:
|
||||
ARTIFACTORY_SERVER:
|
||||
ARTIFACTORY_USERNAME:
|
||||
ARTIFACTORY_PASSWORD:
|
||||
SONATYPE_USER:
|
||||
SONATYPE_PASSWORD:
|
||||
SONATYPE_URL:
|
||||
SONATYPE_STAGING_PROFILE:
|
||||
run:
|
||||
path: git-repo/ci/scripts/promote-version.sh
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: stage-git-repo
|
||||
- name: distribution-repository
|
||||
params:
|
||||
RELEASE_TYPE:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
caches:
|
||||
- path: gradle
|
||||
run:
|
||||
path: git-repo/ci/scripts/stage-version.sh
|
||||
@@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<profiles version="11">
|
||||
<profile kind="CodeFormatterProfile" name="Spring" version="11">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
@@ -1,23 +0,0 @@
|
||||
description = "Spring Framework (Bill of Materials)"
|
||||
|
||||
apply plugin: 'java-platform'
|
||||
apply from: "$rootDir/gradle/publications.gradle"
|
||||
|
||||
group = "org.springframework"
|
||||
|
||||
dependencies {
|
||||
constraints {
|
||||
parent.moduleProjects.sort { "$it.name" }.each {
|
||||
api it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifactId = 'spring-framework-bom'
|
||||
from components.javaPlatform
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
description = "Spring Framework Docs"
|
||||
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'org.asciidoctor.jvm.convert'
|
||||
apply plugin: 'org.asciidoctor.jvm.pdf'
|
||||
apply from: "${rootDir}/gradle/publications.gradle"
|
||||
|
||||
|
||||
configurations {
|
||||
asciidoctorExtensions
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-context"))
|
||||
api(project(":spring-web"))
|
||||
|
||||
implementation(project(":spring-core-test"))
|
||||
implementation("org.assertj:assertj-core")
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
sourceSets = []
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
javadoc {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoctorExtensions "io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.3"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://repo.spring.io/release"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce Javadoc for all Spring Framework modules in "build/docs/javadoc"
|
||||
*/
|
||||
task api(type: Javadoc) {
|
||||
group = "Documentation"
|
||||
description = "Generates aggregated Javadoc API documentation."
|
||||
title = "${rootProject.description} ${version} API"
|
||||
|
||||
dependsOn {
|
||||
moduleProjects.collect {
|
||||
it.tasks.getByName("jar")
|
||||
}
|
||||
}
|
||||
doFirst {
|
||||
classpath = files(
|
||||
// ensure the javadoc process can resolve types compiled from .aj sources
|
||||
project(":spring-aspects").sourceSets.main.output
|
||||
)
|
||||
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
|
||||
}
|
||||
|
||||
options {
|
||||
encoding = "UTF-8"
|
||||
memberLevel = JavadocMemberLevel.PROTECTED
|
||||
author = true
|
||||
header = rootProject.description
|
||||
use = true
|
||||
overview = "framework-docs/src/docs/api/overview.html"
|
||||
splitIndex = true
|
||||
links(project.ext.javadocLinks)
|
||||
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
|
||||
addBooleanOption('Werror', true) // fail build on Javadoc warnings
|
||||
}
|
||||
source moduleProjects.collect { project ->
|
||||
project.sourceSets.main.allJava
|
||||
}
|
||||
maxMemory = "1024m"
|
||||
destinationDir = file("$buildDir/docs/javadoc")
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce KDoc for all Spring Framework modules in "build/docs/kdoc"
|
||||
*/
|
||||
rootProject.tasks.dokkaHtmlMultiModule.configure {
|
||||
dependsOn {
|
||||
tasks.getByName("api")
|
||||
}
|
||||
moduleName.set("spring-framework")
|
||||
outputDirectory.set(project.file("$buildDir/docs/kdoc"))
|
||||
}
|
||||
|
||||
asciidoctorj {
|
||||
version = '2.4.3'
|
||||
fatalWarnings ".*"
|
||||
options doctype: 'book', eruby: 'erubis'
|
||||
attributes([
|
||||
icons: 'font',
|
||||
idprefix: '',
|
||||
idseparator: '-',
|
||||
revnumber: project.version,
|
||||
sectanchors: '',
|
||||
sectnums: '',
|
||||
'spring-version': project.version
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the Spring Framework Reference documentation from
|
||||
* "src/docs/asciidoc" in "build/docs/ref-docs/html5".
|
||||
*/
|
||||
asciidoctor {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations "asciidoctorExtensions"
|
||||
sources {
|
||||
include '*.adoc'
|
||||
}
|
||||
outputDir "$buildDir/docs/ref-docs/html5"
|
||||
outputOptions {
|
||||
backends "spring-html"
|
||||
}
|
||||
logDocuments = true
|
||||
resources {
|
||||
from(sourceDir) {
|
||||
include 'images/*.png'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the Spring Framework Reference documentation from "src/docs/asciidoc"
|
||||
* in "build/docs/ref-docs/pdf".
|
||||
*/
|
||||
asciidoctorPdf {
|
||||
baseDirFollowsSourceDir()
|
||||
configurations 'asciidoctorExtensions'
|
||||
sources {
|
||||
include 'spring-framework.adocbook'
|
||||
}
|
||||
outputDir "$buildDir/docs/ref-docs/pdf"
|
||||
forkOptions {
|
||||
jvmArgs += ["--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", "--add-opens", "java.base/java.io=ALL-UNNAMED"]
|
||||
}
|
||||
logDocuments = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip all docs (API and reference) into a single archive
|
||||
*/
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', rootProject.tasks.dokkaHtmlMultiModule]) {
|
||||
group = "Distribution"
|
||||
description = "Builds -${archiveClassifier} archive containing api and reference " +
|
||||
"for deployment at https://docs.spring.io/spring-framework/docs/."
|
||||
|
||||
archiveBaseName.set("spring-framework")
|
||||
archiveClassifier.set("docs")
|
||||
from("src/dist") {
|
||||
include "changelog.txt"
|
||||
}
|
||||
from (api) {
|
||||
into "javadoc-api"
|
||||
}
|
||||
from ("$asciidoctor.outputDir") {
|
||||
into "reference/html"
|
||||
}
|
||||
from ("$asciidoctorPdf.outputDir") {
|
||||
into "reference/pdf"
|
||||
}
|
||||
from (rootProject.tasks.dokkaHtmlMultiModule.outputDirectory) {
|
||||
into "kdoc-api"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip all Spring Framework schemas into a single archive
|
||||
*/
|
||||
task schemaZip(type: Zip) {
|
||||
group = "Distribution"
|
||||
archiveBaseName.set("spring-framework")
|
||||
archiveClassifier.set("schema")
|
||||
description = "Builds -${archiveClassifier} archive containing all " +
|
||||
"XSDs for deployment at https://springframework.org/schema."
|
||||
duplicatesStrategy DuplicatesStrategy.EXCLUDE
|
||||
moduleProjects.each { module ->
|
||||
def Properties schemas = new Properties();
|
||||
|
||||
module.sourceSets.main.resources.find {
|
||||
(it.path.endsWith("META-INF/spring.schemas") || it.path.endsWith("META-INF\\spring.schemas"))
|
||||
}?.withInputStream { schemas.load(it) }
|
||||
|
||||
for (def key : schemas.keySet()) {
|
||||
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
|
||||
assert shortName != key
|
||||
File xsdFile = module.sourceSets.main.resources.find {
|
||||
(it.path.endsWith(schemas.get(key)) || it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')))
|
||||
}
|
||||
assert xsdFile != null
|
||||
into (shortName) {
|
||||
from xsdFile.path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a distribution zip with everything:
|
||||
* docs, schemas, jars, source jars, javadoc jars
|
||||
*/
|
||||
task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
|
||||
group = "Distribution"
|
||||
archiveBaseName.set("spring-framework")
|
||||
archiveClassifier.set("dist")
|
||||
description = "Builds -${archiveClassifier} archive, containing all jars and docs, " +
|
||||
"suitable for community download page."
|
||||
|
||||
ext.baseDir = "spring-framework-${project.version}";
|
||||
|
||||
from("src/docs/dist") {
|
||||
include "readme.txt"
|
||||
include "license.txt"
|
||||
include "notice.txt"
|
||||
into "${baseDir}"
|
||||
expand(copyright: new Date().format("yyyy"), version: project.version)
|
||||
}
|
||||
|
||||
from(zipTree(docsZip.archiveFile)) {
|
||||
into "${baseDir}/docs"
|
||||
}
|
||||
|
||||
from(zipTree(schemaZip.archiveFile)) {
|
||||
into "${baseDir}/schema"
|
||||
}
|
||||
|
||||
moduleProjects.each { module ->
|
||||
into ("${baseDir}/libs") {
|
||||
from module.jar
|
||||
if (module.tasks.findByPath("sourcesJar")) {
|
||||
from module.sourcesJar
|
||||
}
|
||||
if (module.tasks.findByPath("javadocJar")) {
|
||||
from module.javadocJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distZip.mustRunAfter moduleProjects.check
|
||||
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact docsZip
|
||||
artifact schemaZip
|
||||
artifact distZip
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
This is the public API documentation for the <a href="https://github.com/spring-projects/spring-framework" target="_top">Spring Framework</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,80 +0,0 @@
|
||||
[[appendix]]
|
||||
= Appendix
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
|
||||
This part of the reference documentation covers topics that apply to multiple modules
|
||||
within the core Spring Framework.
|
||||
|
||||
|
||||
[[appendix-spring-properties]]
|
||||
== Spring Properties
|
||||
|
||||
{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder
|
||||
for properties that control certain low-level aspects of the Spring Framework. Users can
|
||||
configure these properties via JVM system properties or programmatically via the
|
||||
`SpringProperties.setProperty(String key, String value)` method. The latter may be
|
||||
necessary if the deployment environment disallows custom JVM system properties. As an
|
||||
alternative, these properties may be configured in a `spring.properties` file in the root
|
||||
of the classpath -- for example, deployed within the application's JAR file.
|
||||
|
||||
The following table lists all currently supported Spring properties.
|
||||
|
||||
.Supported Spring Properties
|
||||
|===
|
||||
| Name | Description
|
||||
|
||||
| `spring.beaninfo.ignore`
|
||||
| Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the
|
||||
JavaBeans `Introspector`. See
|
||||
{api-spring-framework}++/beans/CachedIntrospectionResults.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]
|
||||
for details.
|
||||
|
||||
| `spring.expression.compiler.mode`
|
||||
| The mode to use when compiling expressions for the
|
||||
<<core.adoc#expressions-compiler-configuration, Spring Expression Language>>.
|
||||
|
||||
| `spring.getenv.ignore`
|
||||
| Instructs Spring to ignore operating system environment variables if a Spring
|
||||
`Environment` property -- for example, a placeholder in a configuration String -- isn't
|
||||
resolvable otherwise. See
|
||||
{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]
|
||||
for details.
|
||||
|
||||
| `spring.index.ignore`
|
||||
| Instructs Spring to ignore the components index located in
|
||||
`META-INF/spring.components`. See <<core.adoc#beans-scanning-index, Generating an Index
|
||||
of Candidate Components>>.
|
||||
|
||||
| `spring.jdbc.getParameterType.ignore`
|
||||
| Instructs Spring to ignore `java.sql.ParameterMetaData.getParameterType` completely.
|
||||
See the note in <<data-access.adoc#jdbc-batch-list, Batch Operations with a List of Objects>>.
|
||||
|
||||
| `spring.jndi.ignore`
|
||||
| Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios
|
||||
where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding
|
||||
the repeated JNDI lookup overhead. See
|
||||
{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]
|
||||
for details.
|
||||
|
||||
| `spring.objenesis.ignore`
|
||||
| Instructs Spring to ignore Objenesis, not even attempting to use it. See
|
||||
{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]
|
||||
for details.
|
||||
|
||||
| `spring.test.constructor.autowire.mode`
|
||||
| The default _test constructor autowire mode_ to use if `@TestConstructor` is not present
|
||||
on a test class. See <<testing.adoc#integration-testing-annotations-testconstructor,
|
||||
Changing the default test constructor autowire mode>>.
|
||||
|
||||
| `spring.test.context.cache.maxSize`
|
||||
| The maximum size of the context cache in the _Spring TestContext Framework_. See
|
||||
<<testing.adoc#testcontext-ctx-management-caching, Context Caching>>.
|
||||
|
||||
| `spring.test.enclosing.configuration`
|
||||
| The default _enclosing configuration inheritance mode_ to use if
|
||||
`@NestedTestConfiguration` is not present on a test class. See
|
||||
<<testing.adoc#integration-testing-annotations-nestedtestconfiguration, Changing the
|
||||
default enclosing configuration inheritance mode>>.
|
||||
|
||||
|===
|
||||
@@ -1,18 +0,0 @@
|
||||
:chomp: default headers packages
|
||||
:docs-site: https://docs.spring.io
|
||||
// Spring Framework
|
||||
:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}
|
||||
:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework
|
||||
:docs-java: {docdir}/../../main/java/org/springframework/docs
|
||||
:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs
|
||||
:docs-resources: {docdir}/../../main/resources
|
||||
:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main
|
||||
// Spring portfolio Links
|
||||
:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference
|
||||
:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference
|
||||
:docs-spring-security: {docs-site}/spring-security/reference
|
||||
// Third-party Links
|
||||
:docs-graalvm: https://www.graalvm.org/22.3/reference-manual
|
||||
:gh-rsocket: https://github.com/rsocket
|
||||
:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions
|
||||
:gh-rsocket-java: {gh-rsocket}/rsocket-java
|
||||
@@ -1,43 +0,0 @@
|
||||
[[spring-core]]
|
||||
= Core Technologies
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
|
||||
This part of the reference documentation covers all the technologies that are
|
||||
absolutely integral to the Spring Framework.
|
||||
|
||||
Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container.
|
||||
A thorough treatment of the Spring Framework's IoC container is closely followed by
|
||||
comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies.
|
||||
The Spring Framework has its own AOP framework, which is conceptually easy to
|
||||
understand and which successfully addresses the 80% sweet spot of AOP requirements
|
||||
in Java enterprise programming.
|
||||
|
||||
Coverage of Spring's integration with AspectJ (currently the richest -- in terms of
|
||||
features -- and certainly most mature AOP implementation in the Java enterprise space)
|
||||
is also provided.
|
||||
|
||||
AOT processing can be used to optimize your application ahead-of-time. It is typically
|
||||
used for native image deployment using GraalVM.
|
||||
|
||||
include::core/core-beans.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-resources.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-validation.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-expressions.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-aop.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-aop-api.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-null-safety.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-databuffer-codec.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-spring-jcl.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-aot.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-appendix.adoc[leveloffset=+1]
|
||||
@@ -1,307 +0,0 @@
|
||||
[[core.aot]]
|
||||
= Ahead of Time Optimizations
|
||||
|
||||
This chapter covers Spring's Ahead of Time (AOT) optimizations.
|
||||
|
||||
For AOT support specific to integration tests, see <<testing.adoc#testcontext-aot, Ahead of Time Support for Tests>>.
|
||||
|
||||
[[core.aot.introduction]]
|
||||
== Introduction to Ahead of Time Optimizations
|
||||
|
||||
Spring's support for AOT optimizations is meant to inspect an `ApplicationContext` at build time and apply decisions and discovery logic that usually happens at runtime.
|
||||
Doing so allows building an application startup arrangement that is more straightforward and focused on a fixed set of features based mainly on the classpath and the `Environment`.
|
||||
|
||||
Applying such optimizations early implies the following restrictions:
|
||||
|
||||
* The classpath is fixed and fully defined at build time.
|
||||
* The beans defined in your application cannot change at runtime, meaning:
|
||||
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
|
||||
** Environment properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
|
||||
|
||||
When these restrictions are in place, it becomes possible to perform ahead-of-time processing at build time and generate additional assets.
|
||||
A Spring AOT processed application typically generates:
|
||||
|
||||
* Java source code
|
||||
* Bytecode (usually for dynamic proxies)
|
||||
* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.
|
||||
|
||||
NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.
|
||||
We intend to support more JVM-based use cases in future generations.
|
||||
|
||||
[[core.aot.basics]]
|
||||
== AOT engine overview
|
||||
|
||||
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:
|
||||
|
||||
* Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.
|
||||
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
|
||||
For instance, a core implementation iterates over all candidate bean definitions and generates the necessary code to restore the state of the `BeanFactory`.
|
||||
|
||||
Once this process completes, the `GenerationContext` will have been updated with the generated code, resources, and classes that are necessary for the application to run.
|
||||
The `RuntimeHints` instance can also be used to generate the relevant GraalVM native image configuration files.
|
||||
|
||||
`ApplicationContextAotGenerator#processAheadOfTime` returns the class name of the `ApplicationContextInitializer` entry point that allows the context to be started with AOT optimizations.
|
||||
|
||||
Those steps are covered in greater detail in the sections below.
|
||||
|
||||
[[core.aot.refresh]]
|
||||
== Refresh for AOT Processing
|
||||
|
||||
Refresh for AOT processing is supported on all `GenericApplicationContext` implementations.
|
||||
An application context is created with any number of entry points, usually in the form of `@Configuration`-annotated classes.
|
||||
|
||||
Let's look at a basic example:
|
||||
|
||||
include::code:AotProcessingSample[tag=myapplication]
|
||||
|
||||
Starting this application with the regular runtime involves a number of steps including classpath scanning, configuration class parsing, bean instantiation, and lifecycle callback handling.
|
||||
Refresh for AOT processing only applies a subset of what happens with a <<beans-introduction,regular `refresh`>>.
|
||||
AOT processing can be triggered as follows:
|
||||
|
||||
include::code:AotProcessingSample[tag=aotcontext]
|
||||
|
||||
In this mode, <<beans-factory-extension-factory-postprocessors,`BeanFactoryPostProcessor` implementations>> are invoked as usual.
|
||||
This includes configuration class parsing, import selectors, classpath scanning, etc.
|
||||
Such steps make sure that the `BeanRegistry` contains the relevant bean definitions for the application.
|
||||
If bean definitions are guarded by conditions (such as `@Profile`), these are discarded at this stage.
|
||||
|
||||
Because this mode does not actually create bean instances, `BeanPostProcessor` implementations are not invoked, except for specific variants that are relevant for AOT processing.
|
||||
These are:
|
||||
|
||||
* `MergedBeanDefinitionPostProcessor` implementations post-process bean definitions to extract additional settings, such as `init` and `destroy` methods.
|
||||
* `SmartInstantiationAwareBeanPostProcessor` implementations determine a more precise bean type if necessary.
|
||||
This makes sure to create any proxy that will be required at runtime.
|
||||
|
||||
One this part completes, the `BeanFactory` contains the bean definitions that are necessary for the application to run. It does not trigger bean instantiation but allows the AOT engine to inspect the beans that will be created at runtime.
|
||||
|
||||
[[core.aot.bean-factory-initialization-contributions]]
|
||||
== Bean Factory Initialization AOT Contributions
|
||||
|
||||
Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
|
||||
Each implementation can return an AOT contribution, based on the state of the bean factory.
|
||||
|
||||
An AOT contribution is a component that contributes generated code that reproduces a particular behavior.
|
||||
It can also contribute `RuntimeHints` to indicate the need for reflection, resource loading, serialization, or JDK proxies.
|
||||
|
||||
A `BeanFactoryInitializationAotProcessor` implementation can be registered in `META-INF/spring/aot.factories` with a key equal to the fully qualified name of the interface.
|
||||
|
||||
A `BeanFactoryInitializationAotProcessor` can also be implemented directly by a bean.
|
||||
In this mode, the bean provides an AOT contribution equivalent to the feature it provides with a regular runtime.
|
||||
Consequently, such a bean is automatically excluded from the AOT-optimized context.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If a bean implements the `BeanFactoryInitializationAotProcessor` interface, the bean and **all** of its dependencies will be initialized during AOT processing.
|
||||
We generally recommend that this interface is only implemented by infrastructure beans such as `BeanFactoryPostProcessor` which have limited dependencies and are already initialized early in the bean factory lifecycle.
|
||||
If such a bean is registered using an `@Bean` factory method, ensure the method is `static` so that its enclosing `@Configuration` class does not have to be initialized.
|
||||
====
|
||||
|
||||
|
||||
[[core.aot.bean-registration-contributions]]
|
||||
=== Bean Registration AOT Contributions
|
||||
|
||||
A core `BeanFactoryInitializationAotProcessor` implementation is responsible for collecting the necessary contributions for each candidate `BeanDefinition`.
|
||||
It does so using a dedicated `BeanRegistrationAotProcessor`.
|
||||
|
||||
This interface is used as follows:
|
||||
|
||||
* Implemented by a `BeanPostProcessor` bean, to replace its runtime behavior.
|
||||
For instance <<beans-factory-extension-bpp-examples-aabpp,`AutowiredAnnotationBeanPostProcessor`>> implements this interface to generate code that injects members annotated with `@Autowired`.
|
||||
* Implemented by a type registered in `META-INF/spring/aot.factories` with a key equal to the fully qualified name of the interface.
|
||||
Typically used when the bean definition needs to be tuned for specific features of the core framework.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If a bean implements the `BeanRegistrationAotProcessor` interface, the bean and **all** of its dependencies will be initialized during AOT processing.
|
||||
We generally recommend that this interface is only implemented by infrastructure beans such as `BeanFactoryPostProcessor` which have limited dependencies and are already initialized early in the bean factory lifecycle.
|
||||
If such a bean is registered using an `@Bean` factory method, ensure the method is `static` so that its enclosing `@Configuration` class does not have to be initialized.
|
||||
====
|
||||
|
||||
If no `BeanRegistrationAotProcessor` handles a particular registered bean, a default implementation processes it.
|
||||
This is the default behavior, since tuning the generated code for a bean definition should be restricted to corner cases.
|
||||
|
||||
Taking our previous example, let's assume that `DataSourceConfiguration` is as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class DataSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
public SimpleDataSource dataSource() {
|
||||
return new SimpleDataSource();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Since there isn't any particular condition on this class, `dataSourceConfiguration` and `dataSource` are identified as candidates.
|
||||
The AOT engine will convert the configuration class above to code similar to the following:
|
||||
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Java
|
||||
----
|
||||
/**
|
||||
* Bean definitions for {@link DataSourceConfiguration}
|
||||
*/
|
||||
public class DataSourceConfiguration__BeanDefinitions {
|
||||
/**
|
||||
* Get the bean definition for 'dataSourceConfiguration'
|
||||
*/
|
||||
public static BeanDefinition getDataSourceConfigurationBeanDefinition() {
|
||||
Class<?> beanType = DataSourceConfiguration.class;
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType);
|
||||
beanDefinition.setInstanceSupplier(DataSourceConfiguration::new);
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bean instance supplier for 'dataSource'.
|
||||
*/
|
||||
private static BeanInstanceSupplier<SimpleDataSource> getDataSourceInstanceSupplier() {
|
||||
return BeanInstanceSupplier.<SimpleDataSource>forFactoryMethod(DataSourceConfiguration.class, "dataSource")
|
||||
.withGenerator((registeredBean) -> registeredBean.getBeanFactory().getBean(DataSourceConfiguration.class).dataSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bean definition for 'dataSource'
|
||||
*/
|
||||
public static BeanDefinition getDataSourceBeanDefinition() {
|
||||
Class<?> beanType = SimpleDataSource.class;
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType);
|
||||
beanDefinition.setInstanceSupplier(getDataSourceInstanceSupplier());
|
||||
return beanDefinition;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: The exact code generated may differ depending on the exact nature of your bean definitions.
|
||||
|
||||
The generated code above creates bean definitions equivalent to the `@Configuration` class, but in a direct way and without the use of reflection if at all possible.
|
||||
There is a bean definition for `dataSourceConfiguration` and one for `dataSourceBean`.
|
||||
When a `datasource` instance is required, a `BeanInstanceSupplier` is called.
|
||||
This supplier invokes the `dataSource()` method on the `dataSourceConfiguration` bean.
|
||||
|
||||
|
||||
[[core.aot.hints]]
|
||||
== Runtime Hints
|
||||
|
||||
Running an application as a native image requires additional information compared to a regular JVM runtime.
|
||||
For instance, GraalVM needs to know ahead of time if a component uses reflection.
|
||||
Similarly, classpath resources are not shipped in a native image unless specified explicitly.
|
||||
Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.
|
||||
|
||||
The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.
|
||||
The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
runtimeHints.resources().registerPattern("config/app.properties");
|
||||
----
|
||||
|
||||
A number of contracts are handled automatically during AOT processing.
|
||||
For instance, the return type of a `@Controller` method is inspected, and relevant reflection hints are added if Spring detects that the type should be serialized (typically to JSON).
|
||||
|
||||
For cases that the core container cannot infer, you can register such hints programmatically.
|
||||
A number of convenient annotations are also provided for common use cases.
|
||||
|
||||
|
||||
[[core.aot.hints.import-runtime-hints]]
|
||||
=== `@ImportRuntimeHints`
|
||||
|
||||
`RuntimeHintsRegistrar` implementations allow you to get a callback to the `RuntimeHints` instance managed by the AOT engine.
|
||||
Implementations of this interface can be registered using `@ImportRuntimeHints` on any Spring bean or `@Bean` factory method.
|
||||
`RuntimeHintsRegistrar` implementations are detected and invoked at build time.
|
||||
|
||||
include::code:SpellCheckService[]
|
||||
|
||||
If at all possible, `@ImportRuntimeHints` should be used as close as possible to the component that requires the hints.
|
||||
This way, if the component is not contributed to the `BeanFactory`, the hints won't be contributed either.
|
||||
|
||||
It is also possible to register an implementation statically by adding an entry in `META-INF/spring/aot.factories` with a key equal to the fully qualified name of the `RuntimeHintsRegistrar` interface.
|
||||
|
||||
|
||||
[[core.aot.hints.reflective]]
|
||||
=== `@Reflective`
|
||||
|
||||
{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
|
||||
For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.
|
||||
|
||||
By default, only Spring beans are considered and an invocation hint is registered for the annotated element.
|
||||
This can be tuned by specifying a custom `ReflectiveProcessor` implementation via the
|
||||
`@Reflective` annotation.
|
||||
|
||||
Library authors can reuse this annotation for their own purposes.
|
||||
If components other than Spring beans need to be processed, a `BeanFactoryInitializationAotProcessor` can detect the relevant types and use `ReflectiveRuntimeHintsRegistrar` to process them.
|
||||
|
||||
|
||||
[[core.aot.hints.register-reflection-for-binding]]
|
||||
=== `@RegisterReflectionForBinding`
|
||||
|
||||
{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
|
||||
A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.
|
||||
|
||||
`@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.
|
||||
The following example registers `Account` for serialization.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Component
|
||||
public class OrderService {
|
||||
|
||||
@RegisterReflectionForBinding(Account.class)
|
||||
public void process(Order order) {
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[[core.aot.hints.testing]]
|
||||
=== Testing Runtime Hints
|
||||
|
||||
Spring Core also ships `RuntimeHintsPredicates`, a utility for checking that existing hints match a particular use case.
|
||||
This can be used in your own tests to validate that a `RuntimeHintsRegistrar` contains the expected results.
|
||||
We can write a test for our `SpellCheckService` and ensure that we will be able to load a dictionary at runtime:
|
||||
|
||||
include::code:SpellCheckServiceTests[tag=hintspredicates]
|
||||
|
||||
With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.
|
||||
This approach works well for unit tests but implies that the runtime behavior of a component is well known.
|
||||
|
||||
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
|
||||
This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.
|
||||
|
||||
For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `"org.springframework:spring-core-test"`.
|
||||
This module contains the RuntimeHints Agent, a Java agent that records all method invocations that are related to runtime hints and helps you to assert that a given `RuntimeHints` instance covers all recorded invocations.
|
||||
Let's consider a piece of infrastructure for which we'd like to test the hints we're contributing during the AOT processing phase.
|
||||
|
||||
include::code:SampleReflection[]
|
||||
|
||||
We can then write a unit test (no native compilation required) that checks our contributed hints:
|
||||
|
||||
include::code:SampleReflectionRuntimeHintsTests[]
|
||||
|
||||
If you forgot to contribute a hint, the test will fail and provide some details about the invocation:
|
||||
|
||||
[source,txt,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
org.springframework.docs.core.aot.hints.testing.SampleReflection performReflection
|
||||
INFO: Spring version:6.0.0-SNAPSHOT
|
||||
|
||||
Missing <"ReflectionHints"> for invocation <java.lang.Class#forName>
|
||||
with arguments ["org.springframework.core.SpringVersion",
|
||||
false,
|
||||
jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7].
|
||||
Stacktrace:
|
||||
<"org.springframework.util.ClassUtils#forName, Line 284
|
||||
io.spring.runtimehintstesting.SampleReflection#performReflection, Line 19
|
||||
io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldRegisterReflectionHints$0, Line 25
|
||||
----
|
||||
|
||||
There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.
|
||||
The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).
|
||||
You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.
|
||||
@@ -1,181 +0,0 @@
|
||||
[[databuffers]]
|
||||
= Data Buffers and Codecs
|
||||
|
||||
Java NIO provides `ByteBuffer` but many libraries build their own byte buffer API on top,
|
||||
especially for network operations where reusing buffers and/or using direct buffers is
|
||||
beneficial for performance. For example Netty has the `ByteBuf` hierarchy, Undertow uses
|
||||
XNIO, Jetty uses pooled byte buffers with a callback to be released, and so on.
|
||||
The `spring-core` module provides a set of abstractions to work with various byte buffer
|
||||
APIs as follows:
|
||||
|
||||
* <<databuffers-factory>> abstracts the creation of a data buffer.
|
||||
* <<databuffers-buffer>> represents a byte buffer, which may be
|
||||
<<databuffers-buffer-pooled, pooled>>.
|
||||
* <<databuffers-utils>> offers utility methods for data buffers.
|
||||
* <<Codecs>> decode or encode data buffer streams into higher level objects.
|
||||
|
||||
|
||||
|
||||
|
||||
[[databuffers-factory]]
|
||||
== `DataBufferFactory`
|
||||
|
||||
`DataBufferFactory` is used to create data buffers in one of two ways:
|
||||
|
||||
. Allocate a new data buffer, optionally specifying capacity upfront, if known, which is
|
||||
more efficient even though implementations of `DataBuffer` can grow and shrink on demand.
|
||||
. Wrap an existing `byte[]` or `java.nio.ByteBuffer`, which decorates the given data with
|
||||
a `DataBuffer` implementation and that does not involve allocation.
|
||||
|
||||
Note that WebFlux applications do not create a `DataBufferFactory` directly but instead
|
||||
access it through the `ServerHttpResponse` or the `ClientHttpRequest` on the client side.
|
||||
The type of factory depends on the underlying client or server, e.g.
|
||||
`NettyDataBufferFactory` for Reactor Netty, `DefaultDataBufferFactory` for others.
|
||||
|
||||
|
||||
|
||||
|
||||
[[databuffers-buffer]]
|
||||
== `DataBuffer`
|
||||
|
||||
The `DataBuffer` interface offers similar operations as `java.nio.ByteBuffer` but also
|
||||
brings a few additional benefits some of which are inspired by the Netty `ByteBuf`.
|
||||
Below is a partial list of benefits:
|
||||
|
||||
* Read and write with independent positions, i.e. not requiring a call to `flip()` to
|
||||
alternate between read and write.
|
||||
* Capacity expanded on demand as with `java.lang.StringBuilder`.
|
||||
* Pooled buffers and reference counting via <<databuffers-buffer-pooled>>.
|
||||
* View a buffer as `java.nio.ByteBuffer`, `InputStream`, or `OutputStream`.
|
||||
* Determine the index, or the last index, for a given byte.
|
||||
|
||||
|
||||
|
||||
|
||||
[[databuffers-buffer-pooled]]
|
||||
== `PooledDataBuffer`
|
||||
|
||||
As explained in the Javadoc for
|
||||
https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],
|
||||
byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap
|
||||
which eliminates the need for copying for native I/O operations. That makes direct buffers
|
||||
particularly useful for receiving and sending data over a socket, but they're also more
|
||||
expensive to create and release, which leads to the idea of pooling buffers.
|
||||
|
||||
`PooledDataBuffer` is an extension of `DataBuffer` that helps with reference counting which
|
||||
is essential for byte buffer pooling. How does it work? When a `PooledDataBuffer` is
|
||||
allocated the reference count is at 1. Calls to `retain()` increment the count, while
|
||||
calls to `release()` decrement it. As long as the count is above 0, the buffer is
|
||||
guaranteed not to be released. When the count is decreased to 0, the pooled buffer can be
|
||||
released, which in practice could mean the reserved memory for the buffer is returned to
|
||||
the memory pool.
|
||||
|
||||
Note that instead of operating on `PooledDataBuffer` directly, in most cases it's better
|
||||
to use the convenience methods in `DataBufferUtils` that apply release or retain to a
|
||||
`DataBuffer` only if it is an instance of `PooledDataBuffer`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[databuffers-utils]]
|
||||
== `DataBufferUtils`
|
||||
|
||||
`DataBufferUtils` offers a number of utility methods to operate on data buffers:
|
||||
|
||||
* Join a stream of data buffers into a single buffer possibly with zero copy, e.g. via
|
||||
composite buffers, if that's supported by the underlying byte buffer API.
|
||||
* Turn `InputStream` or NIO `Channel` into `Flux<DataBuffer>`, and vice versa a
|
||||
`Publisher<DataBuffer>` into `OutputStream` or NIO `Channel`.
|
||||
* Methods to release or retain a `DataBuffer` if the buffer is an instance of
|
||||
`PooledDataBuffer`.
|
||||
* Skip or take from a stream of bytes until a specific byte count.
|
||||
|
||||
|
||||
|
||||
|
||||
[[codecs]]
|
||||
== Codecs
|
||||
|
||||
The `org.springframework.core.codec` package provides the following strategy interfaces:
|
||||
|
||||
* `Encoder` to encode `Publisher<T>` into a stream of data buffers.
|
||||
* `Decoder` to decode `Publisher<DataBuffer>` into a stream of higher level objects.
|
||||
|
||||
The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
|
||||
`String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON,
|
||||
Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
|
||||
<<web-reactive.adoc#webflux-codecs, Codecs>> in the WebFlux section.
|
||||
|
||||
|
||||
|
||||
|
||||
[[databuffers-using]]
|
||||
== Using `DataBuffer`
|
||||
|
||||
When working with data buffers, special care must be taken to ensure buffers are released
|
||||
since they may be <<databuffers-buffer-pooled, pooled>>. We'll use codecs to illustrate
|
||||
how that works but the concepts apply more generally. Let's see what codecs must do
|
||||
internally to manage data buffers.
|
||||
|
||||
A `Decoder` is the last to read input data buffers, before creating higher level
|
||||
objects, and therefore it must release them as follows:
|
||||
|
||||
. If a `Decoder` simply reads each input buffer and is ready to
|
||||
release it immediately, it can do so via `DataBufferUtils.release(dataBuffer)`.
|
||||
. If a `Decoder` is using `Flux` or `Mono` operators such as `flatMap`, `reduce`, and
|
||||
others that prefetch and cache data items internally, or is using operators such as
|
||||
`filter`, `skip`, and others that leave out items, then
|
||||
`doOnDiscard(DataBuffer.class, DataBufferUtils::release)` must be added to the
|
||||
composition chain to ensure such buffers are released prior to being discarded, possibly
|
||||
also as a result of an error or cancellation signal.
|
||||
. If a `Decoder` holds on to one or more data buffers in any other way, it must
|
||||
ensure they are released when fully read, or in case of an error or cancellation signals that
|
||||
take place before the cached data buffers have been read and released.
|
||||
|
||||
Note that `DataBufferUtils#join` offers a safe and efficient way to aggregate a data
|
||||
buffer stream into a single data buffer. Likewise `skipUntilByteCount` and
|
||||
`takeUntilByteCount` are additional safe methods for decoders to use.
|
||||
|
||||
An `Encoder` allocates data buffers that others must read (and release). So an `Encoder`
|
||||
doesn't have much to do. However an `Encoder` must take care to release a data buffer if
|
||||
a serialization error occurs while populating the buffer with data. For example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
DataBuffer buffer = factory.allocateBuffer();
|
||||
boolean release = true;
|
||||
try {
|
||||
// serialize and populate buffer..
|
||||
release = false;
|
||||
}
|
||||
finally {
|
||||
if (release) {
|
||||
DataBufferUtils.release(buffer);
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val buffer = factory.allocateBuffer()
|
||||
var release = true
|
||||
try {
|
||||
// serialize and populate buffer..
|
||||
release = false
|
||||
} finally {
|
||||
if (release) {
|
||||
DataBufferUtils.release(buffer)
|
||||
}
|
||||
}
|
||||
return buffer
|
||||
----
|
||||
|
||||
The consumer of an `Encoder` is responsible for releasing the data buffers it receives.
|
||||
In a WebFlux application, the output of the `Encoder` is used to write to the HTTP server
|
||||
response, or to the client HTTP request, in which case releasing the data buffers is the
|
||||
responsibility of the code writing to the server response, or to the client request.
|
||||
|
||||
Note that when running on Netty, there are debugging options for
|
||||
https://github.com/netty/netty/wiki/Reference-counted-objects#troubleshooting-buffer-leaks[troubleshooting buffer leaks].
|
||||
@@ -1,56 +0,0 @@
|
||||
[[null-safety]]
|
||||
= Null-safety
|
||||
|
||||
Although Java does not let you express null-safety with its type system, the Spring Framework
|
||||
now provides the following annotations in the `org.springframework.lang` package to let you
|
||||
declare nullability of APIs and fields:
|
||||
|
||||
* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a
|
||||
specific parameter, return value, or field can be `null`.
|
||||
* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific
|
||||
parameter, return value, or field cannot be `null` (not needed on parameters / return values
|
||||
and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).
|
||||
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level
|
||||
that declares non-null as the default semantics for parameters and return values.
|
||||
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package
|
||||
level that declares non-null as the default semantics for fields.
|
||||
|
||||
The Spring Framework itself leverages these annotations, but they can also be used in any
|
||||
Spring-based Java project to declare null-safe APIs and optionally null-safe fields.
|
||||
Generic type arguments, varargs and array elements nullability are not supported yet but
|
||||
should be in an upcoming release, see https://jira.spring.io/browse/SPR-15942[SPR-15942]
|
||||
for up-to-date information. Nullability declarations are expected to be fine-tuned between
|
||||
Spring Framework releases, including minor ones. Nullability of types used inside method
|
||||
bodies is outside of the scope of this feature.
|
||||
|
||||
NOTE: Other common libraries such as Reactor and Spring Data provide null-safe APIs that
|
||||
use a similar nullability arrangement, delivering a consistent overall experience for
|
||||
Spring application developers.
|
||||
|
||||
|
||||
|
||||
|
||||
== Use cases
|
||||
|
||||
In addition to providing an explicit declaration for Spring Framework API nullability,
|
||||
these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful
|
||||
warnings related to null-safety in order to avoid `NullPointerException` at runtime.
|
||||
|
||||
They are also used to make Spring API null-safe in Kotlin projects, since Kotlin natively
|
||||
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
|
||||
are available in the <<languages#kotlin-null-safety, Kotlin support documentation>>.
|
||||
|
||||
|
||||
|
||||
|
||||
== JSR-305 meta-annotations
|
||||
|
||||
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
||||
annotations (a dormant but wide-spread JSR). JSR-305 meta-annotations let tooling vendors
|
||||
like IDEA or Kotlin provide null-safety support in a generic way, without having to
|
||||
hard-code support for Spring annotations.
|
||||
|
||||
It is not necessary nor recommended to add a JSR-305 dependency to the project classpath to
|
||||
take advantage of Spring null-safe API. Only projects such as Spring-based libraries that use
|
||||
null-safety annotations in their codebase should add `com.google.code.findbugs:jsr305:3.0.2`
|
||||
with `compileOnly` Gradle configuration or Maven `provided` scope to avoid compile warnings.
|
||||
@@ -1,965 +0,0 @@
|
||||
[[resources]]
|
||||
= Resources
|
||||
|
||||
This chapter covers how Spring handles resources and how you can work with resources in
|
||||
Spring. It includes the following topics:
|
||||
|
||||
* <<resources-introduction>>
|
||||
* <<resources-resource>>
|
||||
* <<resources-implementations>>
|
||||
* <<resources-resourceloader>>
|
||||
* <<resources-resourcepatternresolver>>
|
||||
* <<resources-resourceloaderaware>>
|
||||
* <<resources-as-dependencies>>
|
||||
* <<resources-app-ctx>>
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-introduction]]
|
||||
== Introduction
|
||||
|
||||
Java's standard `java.net.URL` class and standard handlers for various URL prefixes,
|
||||
unfortunately, are not quite adequate enough for all access to low-level resources. For
|
||||
example, there is no standardized `URL` implementation that may be used to access a
|
||||
resource that needs to be obtained from the classpath or relative to a
|
||||
`ServletContext`. While it is possible to register new handlers for specialized `URL`
|
||||
prefixes (similar to existing handlers for prefixes such as `http:`), this is generally
|
||||
quite complicated, and the `URL` interface still lacks some desirable functionality,
|
||||
such as a method to check for the existence of the resource being pointed to.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resource]]
|
||||
== The `Resource` Interface
|
||||
|
||||
Spring's `Resource` interface located in the `org.springframework.core.io.` package is
|
||||
meant to be a more capable interface for abstracting access to low-level resources. The
|
||||
following listing provides an overview of the `Resource` interface. See the
|
||||
{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.
|
||||
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public interface Resource extends InputStreamSource {
|
||||
|
||||
boolean exists();
|
||||
|
||||
boolean isReadable();
|
||||
|
||||
boolean isOpen();
|
||||
|
||||
boolean isFile();
|
||||
|
||||
URL getURL() throws IOException;
|
||||
|
||||
URI getURI() throws IOException;
|
||||
|
||||
File getFile() throws IOException;
|
||||
|
||||
ReadableByteChannel readableChannel() throws IOException;
|
||||
|
||||
long contentLength() throws IOException;
|
||||
|
||||
long lastModified() throws IOException;
|
||||
|
||||
Resource createRelative(String relativePath) throws IOException;
|
||||
|
||||
String getFilename();
|
||||
|
||||
String getDescription();
|
||||
}
|
||||
----
|
||||
|
||||
As the definition of the `Resource` interface shows, it extends the `InputStreamSource`
|
||||
interface. The following listing shows the definition of the `InputStreamSource`
|
||||
interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public interface InputStreamSource {
|
||||
|
||||
InputStream getInputStream() throws IOException;
|
||||
}
|
||||
----
|
||||
|
||||
Some of the most important methods from the `Resource` interface are:
|
||||
|
||||
* `getInputStream()`: Locates and opens the resource, returning an `InputStream` for
|
||||
reading from the resource. It is expected that each invocation returns a fresh
|
||||
`InputStream`. It is the responsibility of the caller to close the stream.
|
||||
* `exists()`: Returns a `boolean` indicating whether this resource actually exists in
|
||||
physical form.
|
||||
* `isOpen()`: Returns a `boolean` indicating whether this resource represents a handle
|
||||
with an open stream. If `true`, the `InputStream` cannot be read multiple times and
|
||||
must be read once only and then closed to avoid resource leaks. Returns `false` for
|
||||
all usual resource implementations, with the exception of `InputStreamResource`.
|
||||
* `getDescription()`: Returns a description for this resource, to be used for error
|
||||
output when working with the resource. This is often the fully qualified file name or
|
||||
the actual URL of the resource.
|
||||
|
||||
Other methods let you obtain an actual `URL` or `File` object representing the
|
||||
resource (if the underlying implementation is compatible and supports that
|
||||
functionality).
|
||||
|
||||
Some implementations of the `Resource` interface also implement the extended
|
||||
{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface
|
||||
for a resource that supports writing to it.
|
||||
|
||||
Spring itself uses the `Resource` abstraction extensively, as an argument type in
|
||||
many method signatures when a resource is needed. Other methods in some Spring APIs
|
||||
(such as the constructors to various `ApplicationContext` implementations) take a
|
||||
`String` which in unadorned or simple form is used to create a `Resource` appropriate to
|
||||
that context implementation or, via special prefixes on the `String` path, let the
|
||||
caller specify that a specific `Resource` implementation must be created and used.
|
||||
|
||||
While the `Resource` interface is used a lot with Spring and by Spring, it is actually
|
||||
very convenient to use as a general utility class by itself in your own code, for access
|
||||
to resources, even when your code does not know or care about any other parts of Spring.
|
||||
While this couples your code to Spring, it really only couples it to this small set of
|
||||
utility classes, which serves as a more capable replacement for `URL` and can be
|
||||
considered equivalent to any other library you would use for this purpose.
|
||||
|
||||
NOTE: The `Resource` abstraction does not replace functionality. It wraps it where
|
||||
possible. For example, a `UrlResource` wraps a URL and uses the wrapped `URL` to do its
|
||||
work.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-implementations]]
|
||||
== Built-in `Resource` Implementations
|
||||
|
||||
Spring includes several built-in `Resource` implementations:
|
||||
|
||||
* <<resources-implementations-urlresource>>
|
||||
* <<resources-implementations-classpathresource>>
|
||||
* <<resources-implementations-filesystemresource>>
|
||||
* <<resources-implementations-pathresource>>
|
||||
* <<resources-implementations-servletcontextresource>>
|
||||
* <<resources-implementations-inputstreamresource>>
|
||||
* <<resources-implementations-bytearrayresource>>
|
||||
|
||||
For a complete list of `Resource` implementations available in Spring, consult the
|
||||
"All Known Implementing Classes" section of the
|
||||
{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-urlresource]]
|
||||
=== `UrlResource`
|
||||
|
||||
`UrlResource` wraps a `java.net.URL` and can be used to access any object that is
|
||||
normally accessible with a URL, such as files, an HTTPS target, an FTP target, and
|
||||
others. All URLs have a standardized `String` representation, such that appropriate
|
||||
standardized prefixes are used to indicate one URL type from another. This includes
|
||||
`file:` for accessing filesystem paths, `https:` for accessing resources through the
|
||||
HTTPS protocol, `ftp:` for accessing resources through FTP, and others.
|
||||
|
||||
A `UrlResource` is created by Java code by explicitly using the `UrlResource` constructor
|
||||
but is often created implicitly when you call an API method that takes a `String`
|
||||
argument meant to represent a path. For the latter case, a JavaBeans `PropertyEditor`
|
||||
ultimately decides which type of `Resource` to create. If the path string contains a
|
||||
well-known (to property editor, that is) prefix (such as `classpath:`), it creates an
|
||||
appropriate specialized `Resource` for that prefix. However, if it does not recognize the
|
||||
prefix, it assumes the string is a standard URL string and creates a `UrlResource`.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-classpathresource]]
|
||||
=== `ClassPathResource`
|
||||
|
||||
This class represents a resource that should be obtained from the classpath. It uses
|
||||
either the thread context class loader, a given class loader, or a given class for
|
||||
loading resources.
|
||||
|
||||
This `Resource` implementation supports resolution as a `java.io.File` if the class path
|
||||
resource resides in the file system but not for classpath resources that reside in a
|
||||
jar and have not been expanded (by the servlet engine or whatever the environment is)
|
||||
to the filesystem. To address this, the various `Resource` implementations always support
|
||||
resolution as a `java.net.URL`.
|
||||
|
||||
A `ClassPathResource` is created by Java code by explicitly using the `ClassPathResource`
|
||||
constructor but is often created implicitly when you call an API method that takes a
|
||||
`String` argument meant to represent a path. For the latter case, a JavaBeans
|
||||
`PropertyEditor` recognizes the special prefix, `classpath:`, on the string path and
|
||||
creates a `ClassPathResource` in that case.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-filesystemresource]]
|
||||
=== `FileSystemResource`
|
||||
|
||||
This is a `Resource` implementation for `java.io.File` handles. It also supports
|
||||
`java.nio.file.Path` handles, applying Spring's standard String-based path
|
||||
transformations but performing all operations via the `java.nio.file.Files` API. For pure
|
||||
`java.nio.path.Path` based support use a `PathResource` instead. `FileSystemResource`
|
||||
supports resolution as a `File` and as a `URL`.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-pathresource]]
|
||||
=== `PathResource`
|
||||
|
||||
This is a `Resource` implementation for `java.nio.file.Path` handles, performing all
|
||||
operations and transformations via the `Path` API. It supports resolution as a `File` and
|
||||
as a `URL` and also implements the extended `WritableResource` interface. `PathResource`
|
||||
is effectively a pure `java.nio.path.Path` based alternative to `FileSystemResource` with
|
||||
different `createRelative` behavior.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-servletcontextresource]]
|
||||
=== `ServletContextResource`
|
||||
|
||||
This is a `Resource` implementation for `ServletContext` resources that interprets
|
||||
relative paths within the relevant web application's root directory.
|
||||
|
||||
It always supports stream access and URL access but allows `java.io.File` access only
|
||||
when the web application archive is expanded and the resource is physically on the
|
||||
filesystem. Whether or not it is expanded and on the filesystem or accessed
|
||||
directly from the JAR or somewhere else like a database (which is conceivable) is actually
|
||||
dependent on the Servlet container.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-inputstreamresource]]
|
||||
=== `InputStreamResource`
|
||||
|
||||
An `InputStreamResource` is a `Resource` implementation for a given `InputStream`. It
|
||||
should be used only if no specific `Resource` implementation is applicable. In
|
||||
particular, prefer `ByteArrayResource` or any of the file-based `Resource`
|
||||
implementations where possible.
|
||||
|
||||
In contrast to other `Resource` implementations, this is a descriptor for an
|
||||
already-opened resource. Therefore, it returns `true` from `isOpen()`. Do not use it if
|
||||
you need to keep the resource descriptor somewhere or if you need to read a stream
|
||||
multiple times.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-bytearrayresource]]
|
||||
=== `ByteArrayResource`
|
||||
|
||||
This is a `Resource` implementation for a given byte array. It creates a
|
||||
`ByteArrayInputStream` for the given byte array.
|
||||
|
||||
It is useful for loading content from any given byte array without having to resort to a
|
||||
single-use `InputStreamResource`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resourceloader]]
|
||||
== The `ResourceLoader` Interface
|
||||
|
||||
The `ResourceLoader` interface is meant to be implemented by objects that can return
|
||||
(that is, load) `Resource` instances. The following listing shows the `ResourceLoader`
|
||||
interface definition:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public interface ResourceLoader {
|
||||
|
||||
Resource getResource(String location);
|
||||
|
||||
ClassLoader getClassLoader();
|
||||
}
|
||||
----
|
||||
|
||||
All application contexts implement the `ResourceLoader` interface. Therefore, all
|
||||
application contexts may be used to obtain `Resource` instances.
|
||||
|
||||
When you call `getResource()` on a specific application context, and the location path
|
||||
specified doesn't have a specific prefix, you get back a `Resource` type that is
|
||||
appropriate to that particular application context. For example, assume the following
|
||||
snippet of code was run against a `ClassPathXmlApplicationContext` instance:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val template = ctx.getResource("some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
Against a `ClassPathXmlApplicationContext`, that code returns a `ClassPathResource`. If
|
||||
the same method were run against a `FileSystemXmlApplicationContext` instance, it would
|
||||
return a `FileSystemResource`. For a `WebApplicationContext`, it would return a
|
||||
`ServletContextResource`. It would similarly return appropriate objects for each context.
|
||||
|
||||
As a result, you can load resources in a fashion appropriate to the particular application
|
||||
context.
|
||||
|
||||
On the other hand, you may also force `ClassPathResource` to be used, regardless of the
|
||||
application context type, by specifying the special `classpath:` prefix, as the following
|
||||
example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val template = ctx.getResource("classpath:some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
Similarly, you can force a `UrlResource` to be used by specifying any of the standard
|
||||
`java.net.URL` prefixes. The following examples use the `file` and `https` prefixes:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val template = ctx.getResource("file:///some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
The following table summarizes the strategy for converting `String` objects to `Resource`
|
||||
objects:
|
||||
|
||||
[[resources-resource-strings]]
|
||||
.Resource strings
|
||||
|===
|
||||
| Prefix| Example| Explanation
|
||||
|
||||
| classpath:
|
||||
| `classpath:com/myapp/config.xml`
|
||||
| Loaded from the classpath.
|
||||
|
||||
| file:
|
||||
| `\file:///data/config.xml`
|
||||
| Loaded as a `URL` from the filesystem. See also <<resources-filesystemresource-caveats>>.
|
||||
|
||||
| https:
|
||||
| `\https://myserver/logo.png`
|
||||
| Loaded as a `URL`.
|
||||
|
||||
| (none)
|
||||
| `/data/config.xml`
|
||||
| Depends on the underlying `ApplicationContext`.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resourcepatternresolver]]
|
||||
== The `ResourcePatternResolver` Interface
|
||||
|
||||
The `ResourcePatternResolver` interface is an extension to the `ResourceLoader` interface
|
||||
which defines a strategy for resolving a location pattern (for example, an Ant-style path
|
||||
pattern) into `Resource` objects.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public interface ResourcePatternResolver extends ResourceLoader {
|
||||
|
||||
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
|
||||
|
||||
Resource[] getResources(String locationPattern) throws IOException;
|
||||
}
|
||||
----
|
||||
|
||||
As can be seen above, this interface also defines a special `classpath*:` resource prefix
|
||||
for all matching resources from the class path. Note that the resource location is
|
||||
expected to be a path without placeholders in this case -- for example,
|
||||
`classpath*:/config/beans.xml`. JAR files or different directories in the class path can
|
||||
contain multiple files with the same path and the same name. See
|
||||
<<resources-app-ctx-wildcards-in-resource-paths>> and its subsections for further details
|
||||
on wildcard support with the `classpath*:` resource prefix.
|
||||
|
||||
A passed-in `ResourceLoader` (for example, one supplied via
|
||||
<<resources-resourceloaderaware,`ResourceLoaderAware`>> semantics) can be checked whether
|
||||
it implements this extended interface too.
|
||||
|
||||
`PathMatchingResourcePatternResolver` is a standalone implementation that is usable
|
||||
outside an `ApplicationContext` and is also used by `ResourceArrayPropertyEditor` for
|
||||
populating `Resource[]` bean properties. `PathMatchingResourcePatternResolver` is able to
|
||||
resolve a specified resource location path into one or more matching `Resource` objects.
|
||||
The source path may be a simple path which has a one-to-one mapping to a target
|
||||
`Resource`, or alternatively may contain the special `classpath*:` prefix and/or internal
|
||||
Ant-style regular expressions (matched using Spring's
|
||||
`org.springframework.util.AntPathMatcher` utility). Both of the latter are effectively
|
||||
wildcards.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The default `ResourceLoader` in any standard `ApplicationContext` is in fact an instance
|
||||
of `PathMatchingResourcePatternResolver` which implements the `ResourcePatternResolver`
|
||||
interface. The same is true for the `ApplicationContext` instance itself which also
|
||||
implements the `ResourcePatternResolver` interface and delegates to the default
|
||||
`PathMatchingResourcePatternResolver`.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resourceloaderaware]]
|
||||
== The `ResourceLoaderAware` Interface
|
||||
|
||||
The `ResourceLoaderAware` interface is a special callback interface which identifies
|
||||
components that expect to be provided a `ResourceLoader` reference. The following listing
|
||||
shows the definition of the `ResourceLoaderAware` interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public interface ResourceLoaderAware {
|
||||
|
||||
void setResourceLoader(ResourceLoader resourceLoader);
|
||||
}
|
||||
----
|
||||
|
||||
When a class implements `ResourceLoaderAware` and is deployed into an application context
|
||||
(as a Spring-managed bean), it is recognized as `ResourceLoaderAware` by the application
|
||||
context. The application context then invokes `setResourceLoader(ResourceLoader)`,
|
||||
supplying itself as the argument (remember, all application contexts in Spring implement
|
||||
the `ResourceLoader` interface).
|
||||
|
||||
Since an `ApplicationContext` is a `ResourceLoader`, the bean could also implement the
|
||||
`ApplicationContextAware` interface and use the supplied application context directly to
|
||||
load resources. However, in general, it is better to use the specialized `ResourceLoader`
|
||||
interface if that is all you need. The code would be coupled only to the resource loading
|
||||
interface (which can be considered a utility interface) and not to the whole Spring
|
||||
`ApplicationContext` interface.
|
||||
|
||||
In application components, you may also rely upon autowiring of the `ResourceLoader` as
|
||||
an alternative to implementing the `ResourceLoaderAware` interface. The _traditional_
|
||||
`constructor` and `byType` autowiring modes (as described in <<beans-factory-autowire>>)
|
||||
are capable of providing a `ResourceLoader` for either a constructor argument or a
|
||||
setter method parameter, respectively. For more flexibility (including the ability to
|
||||
autowire fields and multiple parameter methods), consider using the annotation-based
|
||||
autowiring features. In that case, the `ResourceLoader` is autowired into a field,
|
||||
constructor argument, or method parameter that expects the `ResourceLoader` type as long
|
||||
as the field, constructor, or method in question carries the `@Autowired` annotation.
|
||||
For more information, see <<beans-autowired-annotation>>.
|
||||
|
||||
NOTE: To load one or more `Resource` objects for a resource path that contains wildcards
|
||||
or makes use of the special `classpath*:` resource prefix, consider having an instance of
|
||||
<<resources-resourcepatternresolver,`ResourcePatternResolver`>> autowired into your
|
||||
application components instead of `ResourceLoader`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-as-dependencies]]
|
||||
== Resources as Dependencies
|
||||
|
||||
If the bean itself is going to determine and supply the resource path through some sort
|
||||
of dynamic process, it probably makes sense for the bean to use the `ResourceLoader` or
|
||||
`ResourcePatternResolver` interface to load resources. For example, consider the loading
|
||||
of a template of some sort, where the specific resource that is needed depends on the
|
||||
role of the user. If the resources are static, it makes sense to eliminate the use of the
|
||||
`ResourceLoader` interface (or `ResourcePatternResolver` interface) completely, have the
|
||||
bean expose the `Resource` properties it needs, and expect them to be injected into it.
|
||||
|
||||
What makes it trivial to then inject these properties is that all application contexts
|
||||
register and use a special JavaBeans `PropertyEditor`, which can convert `String` paths
|
||||
to `Resource` objects. For example, the following `MyBean` class has a `template`
|
||||
property of type `Resource`.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
package example;
|
||||
|
||||
public class MyBean {
|
||||
|
||||
private Resource template;
|
||||
|
||||
public setTemplate(Resource template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
class MyBean(var template: Resource)
|
||||
----
|
||||
|
||||
In an XML configuration file, the `template` property can be configured with a simple
|
||||
string for that resource, as the following example shows:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<bean id="myBean" class="example.MyBean">
|
||||
<property name="template" value="some/resource/path/myTemplate.txt"/>
|
||||
</bean>
|
||||
----
|
||||
|
||||
Note that the resource path has no prefix. Consequently, because the application context
|
||||
itself is going to be used as the `ResourceLoader`, the resource is loaded through a
|
||||
`ClassPathResource`, a `FileSystemResource`, or a `ServletContextResource`, depending on
|
||||
the exact type of the application context.
|
||||
|
||||
If you need to force a specific `Resource` type to be used, you can use a prefix. The
|
||||
following two examples show how to force a `ClassPathResource` and a `UrlResource` (the
|
||||
latter being used to access a file in the filesystem):
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<property name="template" value="classpath:some/resource/path/myTemplate.txt">
|
||||
----
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
|
||||
----
|
||||
|
||||
If the `MyBean` class is refactored for use with annotation-driven configuration, the
|
||||
path to `myTemplate.txt` can be stored under a key named `template.path` -- for example,
|
||||
in a properties file made available to the Spring `Environment` (see
|
||||
<<beans-environment>>). The template path can then be referenced via the `@Value`
|
||||
annotation using a property placeholder (see <<beans-value-annotations>>). Spring will
|
||||
retrieve the value of the template path as a string, and a special `PropertyEditor` will
|
||||
convert the string to a `Resource` object to be injected into the `MyBean` constructor.
|
||||
The following example demonstrates how to achieve this.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Component
|
||||
public class MyBean {
|
||||
|
||||
private final Resource template;
|
||||
|
||||
public MyBean(@Value("${template.path}") Resource template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@Component
|
||||
class MyBean(@Value("\${template.path}") private val template: Resource)
|
||||
----
|
||||
|
||||
If we want to support multiple templates discovered under the same path in multiple
|
||||
locations in the classpath -- for example, in multiple jars in the classpath -- we can
|
||||
use the special `classpath*:` prefix and wildcarding to define a `templates.path` key as
|
||||
`classpath*:/config/templates/*.txt`. If we redefine the `MyBean` class as follows,
|
||||
Spring will convert the template path pattern into an array of `Resource` objects that
|
||||
can be injected into the `MyBean` constructor.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Component
|
||||
public class MyBean {
|
||||
|
||||
private final Resource[] templates;
|
||||
|
||||
public MyBean(@Value("${templates.path}") Resource[] templates) {
|
||||
this.templates = templates;
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@Component
|
||||
class MyBean(@Value("\${templates.path}") private val templates: Resource[])
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-app-ctx]]
|
||||
== Application Contexts and Resource Paths
|
||||
|
||||
This section covers how to create application contexts with resources, including shortcuts
|
||||
that work with XML, how to use wildcards, and other details.
|
||||
|
||||
|
||||
|
||||
[[resources-app-ctx-construction]]
|
||||
=== Constructing Application Contexts
|
||||
|
||||
An application context constructor (for a specific application context type) generally
|
||||
takes a string or array of strings as the location paths of the resources, such as
|
||||
XML files that make up the definition of the context.
|
||||
|
||||
When such a location path does not have a prefix, the specific `Resource` type built from
|
||||
that path and used to load the bean definitions depends on and is appropriate to the
|
||||
specific application context. For example, consider the following example, which creates a
|
||||
`ClassPathXmlApplicationContext`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = ClassPathXmlApplicationContext("conf/appContext.xml")
|
||||
----
|
||||
|
||||
The bean definitions are loaded from the classpath, because a `ClassPathResource` is
|
||||
used. However, consider the following example, which creates a `FileSystemXmlApplicationContext`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("conf/appContext.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = FileSystemXmlApplicationContext("conf/appContext.xml")
|
||||
----
|
||||
|
||||
Now the bean definitions are loaded from a filesystem location (in this case, relative to
|
||||
the current working directory).
|
||||
|
||||
Note that the use of the special `classpath` prefix or a standard URL prefix on the
|
||||
location path overrides the default type of `Resource` created to load the bean
|
||||
definitions. Consider the following example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml")
|
||||
----
|
||||
|
||||
Using `FileSystemXmlApplicationContext` loads the bean definitions from the classpath.
|
||||
However, it is still a `FileSystemXmlApplicationContext`. If it is subsequently used as a
|
||||
`ResourceLoader`, any unprefixed paths are still treated as filesystem paths.
|
||||
|
||||
|
||||
[[resources-app-ctx-classpathxml]]
|
||||
==== Constructing `ClassPathXmlApplicationContext` Instances -- Shortcuts
|
||||
|
||||
The `ClassPathXmlApplicationContext` exposes a number of constructors to enable
|
||||
convenient instantiation. The basic idea is that you can supply merely a string array
|
||||
that contains only the filenames of the XML files themselves (without the leading path
|
||||
information) and also supply a `Class`. The `ClassPathXmlApplicationContext` then derives
|
||||
the path information from the supplied class.
|
||||
|
||||
Consider the following directory layout:
|
||||
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
com/
|
||||
example/
|
||||
services.xml
|
||||
repositories.xml
|
||||
MessengerService.class
|
||||
----
|
||||
|
||||
The following example shows how a `ClassPathXmlApplicationContext` instance composed of
|
||||
the beans defined in files named `services.xml` and `repositories.xml` (which are on the
|
||||
classpath) can be instantiated:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||
new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.xml"), MessengerService::class.java)
|
||||
----
|
||||
|
||||
See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]
|
||||
javadoc for details on the various constructors.
|
||||
|
||||
|
||||
|
||||
[[resources-app-ctx-wildcards-in-resource-paths]]
|
||||
=== Wildcards in Application Context Constructor Resource Paths
|
||||
|
||||
The resource paths in application context constructor values may be simple paths (as
|
||||
shown earlier), each of which has a one-to-one mapping to a target `Resource` or,
|
||||
alternately, may contain the special `classpath*:` prefix or internal Ant-style patterns
|
||||
(matched by using Spring's `PathMatcher` utility). Both of the latter are effectively
|
||||
wildcards.
|
||||
|
||||
One use for this mechanism is when you need to do component-style application assembly. All
|
||||
components can _publish_ context definition fragments to a well-known location path, and,
|
||||
when the final application context is created using the same path prefixed with
|
||||
`classpath*:`, all component fragments are automatically picked up.
|
||||
|
||||
Note that this wildcarding is specific to the use of resource paths in application context
|
||||
constructors (or when you use the `PathMatcher` utility class hierarchy directly) and is
|
||||
resolved at construction time. It has nothing to do with the `Resource` type itself.
|
||||
You cannot use the `classpath*:` prefix to construct an actual `Resource`, as
|
||||
a resource points to just one resource at a time.
|
||||
|
||||
|
||||
[[resources-app-ctx-ant-patterns-in-paths]]
|
||||
==== Ant-style Patterns
|
||||
|
||||
Path locations can contain Ant-style patterns, as the following example shows:
|
||||
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
/WEB-INF/\*-context.xml
|
||||
com/mycompany/\**/applicationContext.xml
|
||||
file:C:/some/path/\*-context.xml
|
||||
classpath:com/mycompany/**/applicationContext.xml
|
||||
----
|
||||
|
||||
When the path location contains an Ant-style pattern, the resolver follows a more complex
|
||||
procedure to try to resolve the wildcard. It produces a `Resource` for the path up to the
|
||||
last non-wildcard segment and obtains a URL from it. If this URL is not a `jar:` URL or
|
||||
container-specific variant (such as `zip:` in WebLogic, `wsjar` in WebSphere, and so on),
|
||||
a `java.io.File` is obtained from it and used to resolve the wildcard by traversing the
|
||||
filesystem. In the case of a jar URL, the resolver either gets a
|
||||
`java.net.JarURLConnection` from it or manually parses the jar URL and then traverses the
|
||||
contents of the jar file to resolve the wildcards.
|
||||
|
||||
[[resources-app-ctx-portability]]
|
||||
===== Implications on Portability
|
||||
|
||||
If the specified path is already a `file` URL (either implicitly because the base
|
||||
`ResourceLoader` is a filesystem one or explicitly), wildcarding is guaranteed to
|
||||
work in a completely portable fashion.
|
||||
|
||||
If the specified path is a `classpath` location, the resolver must obtain the last
|
||||
non-wildcard path segment URL by making a `Classloader.getResource()` call. Since this
|
||||
is just a node of the path (not the file at the end), it is actually undefined (in the
|
||||
`ClassLoader` javadoc) exactly what sort of a URL is returned in this case. In practice,
|
||||
it is always a `java.io.File` representing the directory (where the classpath resource
|
||||
resolves to a filesystem location) or a jar URL of some sort (where the classpath resource
|
||||
resolves to a jar location). Still, there is a portability concern on this operation.
|
||||
|
||||
If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to
|
||||
get a `java.net.JarURLConnection` from it or manually parse the jar URL, to be able to
|
||||
walk the contents of the jar and resolve the wildcard. This does work in most environments
|
||||
but fails in others, and we strongly recommend that the wildcard resolution of resources
|
||||
coming from jars be thoroughly tested in your specific environment before you rely on it.
|
||||
|
||||
|
||||
[[resources-classpath-wildcards]]
|
||||
==== The `classpath*:` Prefix
|
||||
|
||||
When constructing an XML-based application context, a location string may use the
|
||||
special `classpath*:` prefix, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = ClassPathXmlApplicationContext("classpath*:conf/appContext.xml")
|
||||
----
|
||||
|
||||
This special prefix specifies that all classpath resources that match the given name
|
||||
must be obtained (internally, this essentially happens through a call to
|
||||
`ClassLoader.getResources(...)`) and then merged to form the final application
|
||||
context definition.
|
||||
|
||||
NOTE: The wildcard classpath relies on the `getResources()` method of the underlying
|
||||
`ClassLoader`. As most application servers nowadays supply their own `ClassLoader`
|
||||
implementation, the behavior might differ, especially when dealing with jar files. A
|
||||
simple test to check if `classpath*` works is to use the `ClassLoader` to load a file from
|
||||
within a jar on the classpath:
|
||||
`getClass().getClassLoader().getResources("<someFileInsideTheJar>")`. Try this test with
|
||||
files that have the same name but reside in two different locations -- for example, files
|
||||
with the same name and same path but in different jars on the classpath. In case an
|
||||
inappropriate result is returned, check the application server documentation for settings
|
||||
that might affect the `ClassLoader` behavior.
|
||||
|
||||
You can also combine the `classpath*:` prefix with a `PathMatcher` pattern in the
|
||||
rest of the location path (for example, `classpath*:META-INF/*-beans.xml`). In this
|
||||
case, the resolution strategy is fairly simple: A `ClassLoader.getResources()` call is
|
||||
used on the last non-wildcard path segment to get all the matching resources in the
|
||||
class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
|
||||
strategy described earlier is used for the wildcard subpath.
|
||||
|
||||
|
||||
[[resources-wildcards-in-path-other-stuff]]
|
||||
==== Other Notes Relating to Wildcards
|
||||
|
||||
Note that `classpath*:`, when combined with Ant-style patterns, only works
|
||||
reliably with at least one root directory before the pattern starts, unless the actual
|
||||
target files reside in the file system. This means that a pattern such as
|
||||
`classpath*:*.xml` might not retrieve files from the root of jar files but rather only
|
||||
from the root of expanded directories.
|
||||
|
||||
Spring's ability to retrieve classpath entries originates from the JDK's
|
||||
`ClassLoader.getResources()` method, which only returns file system locations for an
|
||||
empty string (indicating potential roots to search). Spring evaluates
|
||||
`URLClassLoader` runtime configuration and the `java.class.path` manifest in jar files
|
||||
as well, but this is not guaranteed to lead to portable behavior.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The scanning of classpath packages requires the presence of corresponding directory
|
||||
entries in the classpath. When you build JARs with Ant, do not activate the `files-only`
|
||||
switch of the JAR task. Also, classpath directories may not get exposed based on security
|
||||
policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45
|
||||
and higher (which requires 'Trusted-Library' to be set up in your manifests. See
|
||||
https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).
|
||||
|
||||
On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.
|
||||
Putting resources into a dedicated directory is highly recommendable here as well,
|
||||
avoiding the aforementioned portability problems with searching the jar file root level.
|
||||
====
|
||||
|
||||
Ant-style patterns with `classpath:` resources are not guaranteed to find matching
|
||||
resources if the root package to search is available in multiple classpath locations.
|
||||
Consider the following example of a resource location:
|
||||
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
com/mycompany/package1/service-context.xml
|
||||
----
|
||||
|
||||
Now consider an Ant-style path that someone might use to try to find that file:
|
||||
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
classpath:com/mycompany/**/service-context.xml
|
||||
----
|
||||
|
||||
Such a resource may exist in only one location in the classpath, but when a path such as
|
||||
the preceding example is used to try to resolve it, the resolver works off the (first)
|
||||
URL returned by `getResource("com/mycompany");`. If this base package node exists in
|
||||
multiple `ClassLoader` locations, the desired resource may not exist in the first
|
||||
location found. Therefore, in such cases you should prefer using `classpath*:` with the
|
||||
same Ant-style pattern, which searches all classpath locations that contain the
|
||||
`com.mycompany` base package: `classpath*:com/mycompany/**/service-context.xml`.
|
||||
|
||||
|
||||
|
||||
[[resources-filesystemresource-caveats]]
|
||||
=== `FileSystemResource` Caveats
|
||||
|
||||
A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that
|
||||
is, when a `FileSystemApplicationContext` is not the actual `ResourceLoader`) treats
|
||||
absolute and relative paths as you would expect. Relative paths are relative to the
|
||||
current working directory, while absolute paths are relative to the root of the
|
||||
filesystem.
|
||||
|
||||
For backwards compatibility (historical) reasons however, this changes when the
|
||||
`FileSystemApplicationContext` is the `ResourceLoader`. The
|
||||
`FileSystemApplicationContext` forces all attached `FileSystemResource` instances
|
||||
to treat all location paths as relative, whether they start with a leading slash or not.
|
||||
In practice, this means the following examples are equivalent:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("conf/context.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = FileSystemXmlApplicationContext("conf/context.xml")
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("/conf/context.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx = FileSystemXmlApplicationContext("/conf/context.xml")
|
||||
----
|
||||
|
||||
The following examples are also equivalent (even though it would make sense for them to be different, as one
|
||||
case is relative and the other absolute):
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
FileSystemXmlApplicationContext ctx = ...;
|
||||
ctx.getResource("some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx: FileSystemXmlApplicationContext = ...
|
||||
ctx.getResource("some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
FileSystemXmlApplicationContext ctx = ...;
|
||||
ctx.getResource("/some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val ctx: FileSystemXmlApplicationContext = ...
|
||||
ctx.getResource("/some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
In practice, if you need true absolute filesystem paths, you should avoid using
|
||||
absolute paths with `FileSystemResource` or `FileSystemXmlApplicationContext` and
|
||||
force the use of a `UrlResource` by using the `file:` URL prefix. The following examples
|
||||
show how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// actual context type doesn't matter, the Resource will always be UrlResource
|
||||
ctx.getResource("file:///some/resource/path/myTemplate.txt");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// actual context type doesn't matter, the Resource will always be UrlResource
|
||||
ctx.getResource("file:///some/resource/path/myTemplate.txt")
|
||||
----
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("file:///conf/context.xml");
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
|
||||
val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml")
|
||||
----
|
||||
@@ -1,41 +0,0 @@
|
||||
[[spring-jcl]]
|
||||
= Logging
|
||||
|
||||
Since Spring Framework 5.0, Spring comes with its own Commons Logging bridge implemented
|
||||
in the `spring-jcl` module. The implementation checks for the presence of the Log4j 2.x
|
||||
API and the SLF4J 1.7 API in the classpath and uses the first one of those found as the
|
||||
logging implementation, falling back to the Java platform's core logging facilities (also
|
||||
known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is available.
|
||||
|
||||
Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra
|
||||
bridges, and let the framework auto-adapt to your choice. For further information see the
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring
|
||||
Boot Logging Reference Documentation].
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Spring's Commons Logging variant is only meant to be used for infrastructure logging
|
||||
purposes in the core framework and in extensions.
|
||||
|
||||
For logging needs within application code, prefer direct use of Log4j 2.x, SLF4J, or JUL.
|
||||
====
|
||||
|
||||
A `Log` implementation may be retrieved via `org.apache.commons.logging.LogFactory` as in
|
||||
the following example.
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
public class MyBean {
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
// ...
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
class MyBean {
|
||||
private val log = LogFactory.getLog(javaClass)
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@@ -1,90 +0,0 @@
|
||||
[[data.access.appendix]]
|
||||
= Appendix
|
||||
|
||||
|
||||
|
||||
|
||||
[[data.access.xsd-schemas]]
|
||||
== XML Schemas
|
||||
|
||||
This part of the appendix lists XML schemas for data access, including the following:
|
||||
|
||||
* <<xsd-schemas-tx>>
|
||||
* <<xsd-schemas-jdbc>>
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-tx]]
|
||||
=== The `tx` Schema
|
||||
|
||||
The `tx` tags deal with configuring all of those beans in Spring's comprehensive support
|
||||
for transactions. These tags are covered in the chapter entitled
|
||||
<<data-access.adoc#transaction, Transaction Management>>.
|
||||
|
||||
TIP: We strongly encourage you to look at the `'spring-tx.xsd'` file that ships with the
|
||||
Spring distribution. This file contains the XML Schema for Spring's transaction
|
||||
configuration and covers all of the various elements in the `tx` namespace, including
|
||||
attribute defaults and similar information. This file is documented inline, and, thus,
|
||||
the information is not repeated here in the interests of adhering to the DRY (Don't
|
||||
Repeat Yourself) principle.
|
||||
|
||||
In the interest of completeness, to use the elements in the `tx` schema, you need to have
|
||||
the following preamble at the top of your Spring XML configuration file. The text in the
|
||||
following snippet references the correct schema so that the tags in the `tx` namespace
|
||||
are available to you:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" <1>
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd <2>
|
||||
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
|
||||
<!-- bean definitions here -->
|
||||
|
||||
</beans>
|
||||
----
|
||||
<1> Declare usage of the `tx` namespace.
|
||||
<2> Specify the location (with other schema locations).
|
||||
|
||||
NOTE: Often, when you use the elements in the `tx` namespace, you are also using the
|
||||
elements from the `aop` namespace (since the declarative transaction support in Spring is
|
||||
implemented by using AOP). The preceding XML snippet contains the relevant lines needed
|
||||
to reference the `aop` schema so that the elements in the `aop` namespace are available
|
||||
to you.
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-jdbc]]
|
||||
=== The `jdbc` Schema
|
||||
|
||||
The `jdbc` elements let you quickly configure an embedded database or initialize an
|
||||
existing data source. These elements are documented in
|
||||
<<data-access.adoc#jdbc-embedded-database-support, Embedded Database Support>> and
|
||||
<<data-access.adoc#jdbc-initializing-datasource, Initializing a DataSource>>, respectively.
|
||||
|
||||
To use the elements in the `jdbc` schema, you need to have the following preamble at the
|
||||
top of your Spring XML configuration file. The text in the following snippet references
|
||||
the correct schema so that the elements in the `jdbc` namespace are available to you:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc" <1>
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> <2>
|
||||
|
||||
<!-- bean definitions here -->
|
||||
|
||||
</beans>
|
||||
----
|
||||
<1> Declare usage of the `jdbc` namespace.
|
||||
<2> Specify the location (with other schema locations).
|
||||
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 63 KiB |
@@ -1,612 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generated by Microsoft Visio 11.0, SVG Export, v1.0 spring-overview.svg Page-1 -->
|
||||
|
||||
<svg
|
||||
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="6.4728541in"
|
||||
height="5.9522467in"
|
||||
viewBox="0 0 466.04561 428.56238"
|
||||
xml:space="preserve"
|
||||
class="st5"
|
||||
id="svg5499"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mvc-splitted-contexts.svg"
|
||||
style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-rule:evenodd;stroke-linecap:square;stroke-miterlimit:3"
|
||||
inkscape:export-filename="/Users/seb/Workspace/spring-framework/src/asciidoc/images/mvc-splitted-contexts.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><metadata
|
||||
id="metadata5713"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="https://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs5711"><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker9162"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path9164" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker8834"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path8836" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker8518"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path8520" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker8214"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path8216" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker7922"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path7924" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker7641"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path7644" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker7373"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path7375" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker7117"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path7119" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6873"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path6875" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6641"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path6643" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6421"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path6423" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6213"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path6215" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6017"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path6019" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5833"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5835" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5661"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5663" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5501"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5503" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5353"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5355" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5217"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5219" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5093"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path5095" /></marker><marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4981"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"><path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path4983" /></marker><marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always"><path
|
||||
id="path7394"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker8121"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path8123"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker8033"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path8035"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker7957"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path7959"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path7376"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path7388"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" /></marker><marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"><path
|
||||
id="path7370"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" /></marker></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1005"
|
||||
id="namedview5709"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1640492"
|
||||
inkscape:cx="134.86698"
|
||||
inkscape:cy="203.59898"
|
||||
inkscape:window-x="84"
|
||||
inkscape:window-y="176"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="g5503"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" /><v:documentProperties
|
||||
v:langID="1033"
|
||||
v:viewMarkup="false" /><style
|
||||
type="text/css"
|
||||
id="style5501"><![CDATA[
|
||||
.st1 {fill:#969696;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
|
||||
.st2 {fill:#dde2cd;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
|
||||
.st3 {fill:#000000;font-family:Arial;font-size:2.50001em;font-weight:bold}
|
||||
.st4 {font-size:0.333333em;font-weight:normal}
|
||||
.st5 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
|
||||
]]></style><g
|
||||
v:mID="0"
|
||||
v:index="1"
|
||||
v:groupContext="foregroundPage"
|
||||
id="g5503"
|
||||
transform="matrix(0.99998201,0,0,1.0824094,-40.812382,-98.908648)"><rect
|
||||
style="fill:#dde2cd;fill-opacity:1;stroke:#000000;stroke-width:1.53790233;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6599"
|
||||
width="382.68423"
|
||||
height="146.09897"
|
||||
x="87.884865"
|
||||
y="148.26482" /><v:userDefs><v:ud
|
||||
v:nameU="SchemeName"
|
||||
v:val="VT4(Default)" /></v:userDefs><rect
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.53790233;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5725"
|
||||
width="464.31128"
|
||||
height="374.11411"
|
||||
x="41.684383"
|
||||
y="112.3262" /><title
|
||||
id="title5505">Page-1</title><v:pageProperties
|
||||
v:drawingScale="0.0393701"
|
||||
v:pageScale="0.0393701"
|
||||
v:drawingUnits="24"
|
||||
v:shadowOffsetX="8.50394"
|
||||
v:shadowOffsetY="-8.50394" /><v:layer
|
||||
v:name="Connector"
|
||||
v:index="0" /><rect
|
||||
style="fill:#dde2cd;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.53790233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5715"
|
||||
width="322.8194"
|
||||
height="43.63184"
|
||||
x="119.95335"
|
||||
y="-135.66222"
|
||||
transform="scale(1,-1)" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:30.7580471px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="168.843"
|
||||
y="124.32391"
|
||||
id="text5717"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5719"
|
||||
x="168.843"
|
||||
y="124.32391"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:23.06853676px;font-family:sans-serif;-inkscape-font-specification:sans-serif">DispatcherServlet</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="89.770851"
|
||||
y="181.20923"
|
||||
id="text6589"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6591"
|
||||
x="89.770851"
|
||||
y="181.20923"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:23.06853676px;font-family:sans-serif;-inkscape-font-specification:sans-serif">Servlet WebApplicationContext</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="260.00443"
|
||||
y="198.41273"
|
||||
id="text6593"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6595"
|
||||
x="260.00443"
|
||||
y="198.41273"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.53426838px;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle">(containing controllers, view resolvers,</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="260.00443"
|
||||
y="212.83057"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.53426838px;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle"
|
||||
id="tspan6597">and other web-related beans)</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.86203903;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6620"
|
||||
width="82.040657"
|
||||
height="36.72575"
|
||||
x="114.52653"
|
||||
y="-259.43161"
|
||||
transform="scale(1,-1)" /><rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.89166164;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6622"
|
||||
width="87.843979"
|
||||
height="36.697304"
|
||||
x="223.39864"
|
||||
y="-287.19809"
|
||||
transform="scale(1,-1)" /><rect
|
||||
transform="scale(1,-1)"
|
||||
y="-264.81918"
|
||||
x="117.92834"
|
||||
height="36.72575"
|
||||
width="82.040657"
|
||||
id="rect6614"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.86203903;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="121.24728"
|
||||
y="260.14957"
|
||||
id="text6616"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6618"
|
||||
x="121.24728"
|
||||
y="260.14957"
|
||||
style="font-size:11.53426838px">Controllers</tspan></text>
|
||||
<text
|
||||
transform="scale(1.0403984,0.96117025)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6624"
|
||||
y="282.70709"
|
||||
x="219.61203"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:11.53426838px"
|
||||
y="282.70709"
|
||||
x="219.61203"
|
||||
id="tspan6626"
|
||||
sodipodi:role="line">ViewResolver</tspan></text>
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-259.30249"
|
||||
x="332.5405"
|
||||
height="36.577778"
|
||||
width="114.4539"
|
||||
id="rect6628"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.0161339;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="327.51276"
|
||||
y="255.28464"
|
||||
id="text6630"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6632"
|
||||
x="327.51276"
|
||||
y="255.28464"
|
||||
style="font-size:11.53426838px">HandlerMapping</tspan></text>
|
||||
<rect
|
||||
y="338.69724"
|
||||
x="87.803261"
|
||||
height="121.5683"
|
||||
width="382.84744"
|
||||
id="rect6634"
|
||||
style="fill:#dde2cd;fill-opacity:1;stroke:#000000;stroke-width:1.53790233;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1" /><text
|
||||
transform="scale(1.0403984,0.96117025)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6636"
|
||||
y="376.61673"
|
||||
x="108.61351"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:23.06853676px;font-family:sans-serif;-inkscape-font-specification:sans-serif"
|
||||
y="376.61673"
|
||||
x="108.61351"
|
||||
id="tspan6638"
|
||||
sodipodi:role="line">Root WebApplicationContext</tspan></text>
|
||||
<text
|
||||
transform="scale(1.0403984,0.96117025)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6640"
|
||||
y="395.35812"
|
||||
x="260.93863"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan6644"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.53426838px;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle"
|
||||
y="395.35812"
|
||||
x="260.93863"
|
||||
sodipodi:role="line">(containing middle-tier services, datasources, etc.)</tspan></text>
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-440.06805"
|
||||
x="164.32933"
|
||||
height="36.72575"
|
||||
width="82.040657"
|
||||
id="rect6648"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.86203903;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1" /><rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.86203903;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6650"
|
||||
width="82.040657"
|
||||
height="36.72575"
|
||||
x="167.73116"
|
||||
y="-445.45563"
|
||||
transform="scale(1,-1)" /><text
|
||||
transform="scale(1.0403984,0.96117025)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6652"
|
||||
y="448.55054"
|
||||
x="175.87148"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:11.53426838px"
|
||||
y="448.55054"
|
||||
x="175.87148"
|
||||
id="tspan6654"
|
||||
sodipodi:role="line">Services</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.88435173;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6656"
|
||||
width="86.393044"
|
||||
height="36.704323"
|
||||
x="306.86328"
|
||||
y="-439.60837"
|
||||
transform="scale(1,-1)" /><rect
|
||||
transform="scale(1,-1)"
|
||||
y="-444.99475"
|
||||
x="310.26624"
|
||||
height="36.701977"
|
||||
width="86.876686"
|
||||
id="rect6658"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.88679528;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="305.30771"
|
||||
y="448.55054"
|
||||
id="text6660"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6662"
|
||||
x="305.30771"
|
||||
y="448.55054"
|
||||
style="font-size:11.53426838px">Repositories</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.76895118px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 265.33234,295.60379 c 0,42.65169 0,42.65169 0,0 z"
|
||||
id="path7643"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.46028023;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="m 270.43505,294.70585 c 0,39.4721 0,39.87903 0,39.87903"
|
||||
id="path7645"
|
||||
inkscape:connector-curvature="0" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:30.7580471px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="352.55331"
|
||||
y="333.03622"
|
||||
id="text4963"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0403984,0.96117025)"><tspan
|
||||
sodipodi:role="line"
|
||||
x="352.55331"
|
||||
y="333.03622"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.53426838px;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle"
|
||||
id="tspan4965">Delegates if no bean found</tspan></text>
|
||||
</g></svg>
|
||||
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 102 KiB |
@@ -1,9 +0,0 @@
|
||||
<div id="header">
|
||||
<h1>Spring Framework Documentation</h1>
|
||||
<!--
|
||||
<div class="details">
|
||||
<span id="revnumber">{revnumber}</span>
|
||||
</div>
|
||||
-->
|
||||
<span><strong>{revnumber}</strong></span>
|
||||
</div>
|
||||
@@ -1,38 +0,0 @@
|
||||
:noheader:
|
||||
= Spring Framework Documentation
|
||||
include::attributes.adoc[]
|
||||
|
||||
[horizontal]
|
||||
<<overview.adoc#overview, Overview>> :: history, design philosophy, feedback,
|
||||
getting started.
|
||||
<<core.adoc#spring-core, Core>> :: IoC Container, Events, Resources, i18n,
|
||||
Validation, Data Binding, Type Conversion, SpEL, AOP, AOT.
|
||||
<<testing.adoc#testing, Testing>> :: Mock Objects, TestContext Framework,
|
||||
Spring MVC Test, WebTestClient.
|
||||
<<data-access.adoc#spring-data-tier, Data Access>> :: Transactions, DAO Support,
|
||||
JDBC, R2DBC, O/R Mapping, XML Marshalling.
|
||||
<<web.adoc#spring-web, Web Servlet>> :: Spring MVC, WebSocket, SockJS,
|
||||
STOMP Messaging.
|
||||
<<web-reactive.adoc#spring-webflux, Web Reactive>> :: Spring WebFlux, WebClient,
|
||||
WebSocket, RSocket.
|
||||
<<integration.adoc#spring-integration, Integration>> :: REST Clients, JMS, JCA, JMX,
|
||||
Email, Tasks, Scheduling, Caching.
|
||||
<<languages.adoc#languages, Languages>> :: Kotlin, Groovy, Dynamic Languages.
|
||||
<<appendix.adoc#appendix, Appendix>> :: Spring properties.
|
||||
https://github.com/spring-projects/spring-framework/wiki[*Wiki*] :: What's New,
|
||||
Upgrade Notes, Supported Versions, and other cross-version information.
|
||||
|
||||
NOTE: This documentation is available in {docs-spring-framework}/reference/html/index.html[HTML] and {docs-spring-framework}/reference/pdf/spring-framework.pdf[PDF] formats.
|
||||
|
||||
Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,
|
||||
Alef Arendsen, Darren Davison, Dmitriy Kopylenko, Mark Pollack, Thierry Templier, Erwin
|
||||
Vervaet, Portia Tung, Ben Hale, Adrian Colyer, John Lewis, Costin Leau, Mark Fisher, Sam
|
||||
Brannen, Ramnivas Laddad, Arjen Poutsma, Chris Beams, Tareq Abedrabbo, Andy Clement, Dave
|
||||
Syer, Oliver Gierke, Rossen Stoyanchev, Phillip Webb, Rob Winch, Brian Clozel, Stephane
|
||||
Nicoll, Sebastien Deleuze, Jay Bryant, Mark Paluch
|
||||
|
||||
Copyright © 2002 - 2022 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Copies of this document may be made for your own use and for distribution to others,
|
||||
provided that you do not charge any fee for such copies and further provided that each
|
||||
copy contains this Copyright Notice, whether distributed in print or electronically.
|
||||