mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
209 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 015e1bec64 | |||
| 47ae15b7ee | |||
| df7b661702 | |||
| fe46a01a57 | |||
| 2f13e05b4f | |||
| 4b38dc8972 | |||
| 7387cb990e | |||
| 863570abb7 | |||
| 70907fd326 | |||
| 494cc22bcd | |||
| 044d68b336 | |||
| a95eb1d044 | |||
| b00c31a620 | |||
| 23cc44f16e | |||
| e1a065906e | |||
| 3bfddc501d | |||
| f9081bedb4 | |||
| 1ac8e48ebf | |||
| d4f4225e53 | |||
| c53184cb6d | |||
| f9f106936c | |||
| bcf7aecf0f | |||
| 5854d519a1 | |||
| 1ea7f741fe | |||
| 8c6fe2cb42 | |||
| 7a5a6893e3 | |||
| c8e8d6cd49 | |||
| 094ff8883d | |||
| 44f79f95a7 | |||
| 3eaec64ee8 | |||
| ff9c695599 | |||
| 6021822ce4 | |||
| 045f78e6c5 | |||
| 42568afb37 | |||
| ce001c23f7 | |||
| 93405fb289 | |||
| db056ae0e0 | |||
| 35d53af2ca | |||
| 63de2fab4c | |||
| 5d8aa635c6 | |||
| ad9049e68a | |||
| b9135788b9 | |||
| b62652aca1 | |||
| fce02d94b8 | |||
| 2dca5b6815 | |||
| a302c4ac45 | |||
| 507cf8ad14 | |||
| 7500caea52 | |||
| 7994b63c13 | |||
| 26e697b60c | |||
| ef66708aa6 | |||
| 30b3e24a32 | |||
| 0a31892475 | |||
| 6fb2c72a55 | |||
| c82d701a4e | |||
| d66cf0c32f | |||
| 562c323989 | |||
| 13a68c6060 | |||
| 6110919842 | |||
| c5aa0d12b0 | |||
| 6de67cc2df | |||
| b9d726fb84 | |||
| 2b57020c18 | |||
| 77298a19c9 | |||
| 55961544a7 | |||
| 5639aa7064 | |||
| 0c30618ae8 | |||
| 9317d8f43e | |||
| 692908b722 | |||
| c890d1e69d | |||
| 4c7cb858d2 | |||
| 5a49d657d8 | |||
| 8a1ae53166 | |||
| 0765a05434 | |||
| 072e5e8471 | |||
| a17912d19e | |||
| 610e7796d9 | |||
| 8efac21c2b | |||
| 40c7303702 | |||
| c00782a3e8 | |||
| 96f5314df6 | |||
| 2b628a1a0d | |||
| 349143864c | |||
| fc73f6bb2c | |||
| 119364f326 | |||
| 434735fbf6 | |||
| 8f4221deb3 | |||
| 2d646ca79e | |||
| 1245919331 | |||
| bcbd338fe2 | |||
| 945463b826 | |||
| 3ba3dd61d1 | |||
| cd523c7051 | |||
| 20ddd3254b | |||
| e30b842316 | |||
| b0675c031e | |||
| 0f71da5be6 | |||
| 9035a97e18 | |||
| d32a77a5f0 | |||
| d8e3ef7640 | |||
| ccb02a2355 | |||
| d0948f1f03 | |||
| ae0f23e942 | |||
| b40263e06b | |||
| 2f8dfb3e52 | |||
| d5c78c953d | |||
| dfac1d0510 | |||
| 14b83c3fcc | |||
| ae6e84bc7d | |||
| 4213a31a7d | |||
| 22454c8edf | |||
| 98da5a7b2b | |||
| 0a37552beb | |||
| 1b702fa6a2 | |||
| a2e438b2be | |||
| 9ff9d45283 | |||
| 1fee4c0c0b | |||
| dc87a2211c | |||
| 77b7344530 | |||
| 7cde4f1503 | |||
| 6c11fd3b5e | |||
| eec4a37d1c | |||
| 1e3dc4aeae | |||
| d4b54d834e | |||
| 3562cd759b | |||
| c1dc4e2c75 | |||
| 8feeec4a60 | |||
| 440a63a3d0 | |||
| 274ed1fe67 | |||
| 1b47f6c0b0 | |||
| 66e4c9b2bb | |||
| e608055021 | |||
| 199be0ad3c | |||
| af7753eac6 | |||
| cce74b8ba2 | |||
| dd7508d606 | |||
| 3bf56dda56 | |||
| a72209aad3 | |||
| 67f41b15eb | |||
| 3515acfa3d | |||
| 7fdd0c22b2 | |||
| a0f8a894f2 | |||
| 55f02db18e | |||
| 71e88cbf30 | |||
| 514a2e9568 | |||
| abfb439bfe | |||
| 4ba43b4737 | |||
| 2655657a51 | |||
| 404671416a | |||
| 260eafc819 | |||
| ef8b5763e6 | |||
| 6b89af824d | |||
| 86b4b2ef23 | |||
| faa8430fd7 | |||
| 76f870caca | |||
| 615315728b | |||
| 115442242f | |||
| 10c0e8af01 | |||
| b6e20a4cc9 | |||
| a8adec7673 | |||
| 2ae61c503e | |||
| c2b2f30669 | |||
| 239a7cd85f | |||
| 6e4317ebfb | |||
| 325d8834e3 | |||
| 0c76cb7e80 | |||
| 940011e233 | |||
| 92bbd8103b | |||
| 9c194699c7 | |||
| 25701ef984 | |||
| 87ef99df5e | |||
| 13ca2752ae | |||
| ef363b0f7a | |||
| f9db59e730 | |||
| 0dcca2304f | |||
| ad272a0c87 | |||
| be224e1f30 | |||
| 4bb0916202 | |||
| d3eda09c01 | |||
| 399f887128 | |||
| 4d005b6987 | |||
| 532a7a3a02 | |||
| b2d416fd5f | |||
| 7298c3d669 | |||
| 7bbd38b9e0 | |||
| 64d83a550e | |||
| 0df1630ab9 | |||
| 7cbc115da6 | |||
| b962239e11 | |||
| 872cf6b076 | |||
| b2bd319d47 | |||
| e3fa49063e | |||
| c302efdbbf | |||
| 12699696f4 | |||
| c4f2566070 | |||
| 6458643f15 | |||
| 2145545e69 | |||
| f6545cde38 | |||
| 601c64a65c | |||
| 964f1a6213 | |||
| 886cc2cce8 | |||
| 5bdd2d245c | |||
| d0513f7521 | |||
| 265c0c1505 | |||
| 886cf825cb | |||
| 03033f6c06 | |||
| 5ff2dfbe13 | |||
| fa44ab6336 | |||
| eed1a58b81 |
@@ -15,12 +15,10 @@ spring-test/test-output/
|
||||
.gradle
|
||||
argfile*
|
||||
pom.xml
|
||||
activemq-data/
|
||||
|
||||
/build
|
||||
buildSrc/build
|
||||
/spring-*/build
|
||||
/src/asciidoc/build
|
||||
target/
|
||||
|
||||
# Eclipse artifacts, including WTP generated manifests
|
||||
@@ -32,8 +30,6 @@ spring-*/src/main/java/META-INF/MANIFEST.MF
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea
|
||||
out
|
||||
test-output
|
||||
atlassian-ide-plugin.xml
|
||||
.gradletasknamecache
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
= How to contribute to the reference
|
||||
|
||||
The Spring Framework reference now uses http://asciidoctor.org/[asciidoctor]. This
|
||||
document describes how to contribute documentation updates.
|
||||
|
||||
== Building with Gradle
|
||||
|
||||
You can build the documentation using gradle using the `reference` task. For example, from
|
||||
the project root execute the following command:
|
||||
|
||||
./gradlew reference
|
||||
|
||||
the output will be available at `spring-framework/build/reference/htmlsingle/index.html`
|
||||
|
||||
== Live editing
|
||||
|
||||
One of the nice features about using asciidoctor is the support for live editing.
|
||||
|
||||
You will find a Guardfile already present at `spring-framework/src/asciidoc/Guardfile`.
|
||||
Make sure first to follow the setup instructions within the
|
||||
http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/[Editing AsciiDoc with Live Preview]
|
||||
document. Once you have done that, there are additional gems to install to make it work
|
||||
(assuming that you are using http://livereload.com/[LiveReload]):
|
||||
|
||||
gem install guard-rspec guard-livereload
|
||||
|
||||
When running `guard start` within the `src/asciidoc/` folder, any changes to the
|
||||
`src/asciidoc/index.adoc` file will automatically be written at
|
||||
`src/asciidoc/build/index.html`.
|
||||
|
||||
== Troubleshooting
|
||||
|
||||
* If you are using LiveReload, make sure to select _Allow access to file URLs_ in the
|
||||
LiveEdit plugin options of your browser.
|
||||
* The icon used to enable _LiveReload_ can be a bit confusing. The dot is empty when it is
|
||||
disabled and full when the plugin is active. Make sure to enable it on the tab
|
||||
displaying the `index.html` file.
|
||||
* Ensure you are _not_ running guard start at all as two instances could not run at the
|
||||
same time. To exit a current session in a clean way, just type e in the shell.
|
||||
|
||||
== Documentation notes
|
||||
|
||||
Some notes on documentation
|
||||
|
||||
* Documentation is wrapped at 90 chars, ensure that you manually wrap your edits
|
||||
* Tabs are used for indentation, do not use spaces
|
||||
* Follow the existing style when inserting `source` blocks
|
||||
* http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoctor Quick Reference]
|
||||
* http://asciidoctor.org/docs/user-manual/[Asciidoctor Manual]
|
||||
* http://asciidoctor.org/docs/asciidoc-writers-guide/[Asciidoctor Writers Guide]
|
||||
|
||||
+76
-80
@@ -1,28 +1,33 @@
|
||||
_Have something you'd like to contribute to the framework? We welcome pull
|
||||
requests but ask that you carefully read this document first to understand how
|
||||
requests, but ask that you carefully read this document first to understand how
|
||||
best to submit them; what kind of changes are likely to be accepted; and what
|
||||
to expect from the Spring team when evaluating your submission._
|
||||
|
||||
_Please refer back to this document as a checklist before issuing any pull
|
||||
request; this will save time for everyone!_
|
||||
|
||||
## Take Your First Steps
|
||||
## Understand the basics
|
||||
|
||||
### Understand the basics
|
||||
|
||||
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
|
||||
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
|
||||
excellent [help documentation][] first.
|
||||
|
||||
|
||||
### Search JIRA first; create an issue if necessary
|
||||
## Search JIRA first; create an issue if necessary
|
||||
|
||||
Is there already an issue that addresses your concern? Do a bit of searching
|
||||
in our [JIRA issue tracker][] to see if you can find something similar. If you
|
||||
do not find something similar, please create a new JIRA issue before submitting
|
||||
a pull request unless the change is truly trivial -- for example: typo fixes,
|
||||
removing compiler warnings, etc.
|
||||
Is there already an issue that addresses your concern? Do a bit of searching
|
||||
in our [JIRA issue tracker][] to see if you can find something similar. If not,
|
||||
please create a new issue before submitting a pull request unless the change is
|
||||
truly trivial, e.g. typo fixes, removing compiler warnings, etc.
|
||||
|
||||
### Sign the Contributor License Agreement
|
||||
## Discuss non-trivial contribution ideas with committers
|
||||
|
||||
If you're considering anything more than correcting a typo or fixing a minor
|
||||
bug, please discuss it on the [spring-framework-contrib][] mailing list before
|
||||
submitting a pull request. We're happy to provide guidance, but please spend an
|
||||
hour or two researching the subject on your own including searching the mailing
|
||||
list for prior discussions.
|
||||
|
||||
## Sign the Contributor License Agreement
|
||||
|
||||
If you have not previously done so, please fill out and submit the
|
||||
[SpringSource CLA form][]. You'll receive a token when this process is complete.
|
||||
@@ -37,34 +42,31 @@ your pull request:
|
||||
I have signed and agree to the terms of the SpringSource Individual
|
||||
Contributor License Agreement.
|
||||
|
||||
You do not need to include your token/id. Please add the above statement to all
|
||||
You do not need to include your token/id. Please add the statement above to all
|
||||
future pull requests as well, simply so that the Spring Framework team knows
|
||||
immediately that this process is complete.
|
||||
|
||||
## Create a Branch
|
||||
|
||||
### Branch from `master`
|
||||
## Create your branch from `3.2.x`
|
||||
|
||||
Master currently represents work toward Spring Framework 4.0. Please submit
|
||||
all pull requests there, even bug fixes and minor improvements. Backports to
|
||||
`3.2.x` will be considered on a case-by-case basis.
|
||||
If your pull request addresses a bug or improvement, please create your branch
|
||||
from Spring Framework's `3.2.x` branch. `master` is reserved for work on new features
|
||||
for the next major version of the framework. Rest assured that if your pull
|
||||
request is accepted and merged into `3.2.x`, these changes will also eventually
|
||||
be merged into `master`.
|
||||
|
||||
|
||||
### Use short branch names
|
||||
## Use short branch names
|
||||
|
||||
Branches used when submitting pull requests should preferably be named
|
||||
according to JIRA issues, e.g. 'SPR-1234'. Otherwise, use succinct, lower-case,
|
||||
dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. In
|
||||
[fork-and-edit][] cases, the GitHub default 'patch-1' is fine as well. This is
|
||||
important, because branch names show up in the merge commits that result from
|
||||
accepting pull requests and should be as expressive and concise as possible.
|
||||
accepting pull requests, and should be as expressive and concise as possible.
|
||||
|
||||
## Use Spring Framework Code Style
|
||||
|
||||
The complete [Spring Framework Code Style][] reference is available on the wiki, but
|
||||
here's a quick summary:
|
||||
|
||||
### Mind the whitespace
|
||||
## Mind the whitespace
|
||||
|
||||
Please carefully follow the whitespace and formatting conventions already
|
||||
present in the framework.
|
||||
@@ -76,16 +78,16 @@ present in the framework.
|
||||
1. Aim to wrap code at 90 characters, but favor readability over wrapping
|
||||
1. Preserve existing formatting; i.e. do not reformat code for its own sake
|
||||
1. Search the codebase using `git grep` and other tools to discover common
|
||||
naming conventions, etc.
|
||||
naming conventions, etc.
|
||||
1. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert
|
||||
if necessary
|
||||
if necessary
|
||||
|
||||
|
||||
### Add Apache license header to all new classes
|
||||
## Add Apache license header to all new classes
|
||||
|
||||
```java
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -103,42 +105,40 @@ present in the framework.
|
||||
package ...;
|
||||
```
|
||||
|
||||
### Update Apache license header in modified files as necessary
|
||||
## Update Apache license header to modified files as necessary
|
||||
|
||||
Always check the date range in the license header. For example, if you've
|
||||
modified a file in 2014 whose header still reads:
|
||||
modified a file in 2013 whose header still reads
|
||||
|
||||
```java
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
```
|
||||
|
||||
Then be sure to update it to 2014 accordingly:
|
||||
then be sure to update it to 2013 appropriately
|
||||
|
||||
```java
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
```
|
||||
|
||||
### Use @since tags for newly-added public API types and methods
|
||||
## Use @since tags for newly-added public API types and methods
|
||||
|
||||
For example:
|
||||
e.g.
|
||||
|
||||
```java
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @author First Last
|
||||
* @since 4.0
|
||||
* @since 3.2
|
||||
* @see ...
|
||||
*/
|
||||
```
|
||||
|
||||
## Prepare Your Commit
|
||||
## Submit JUnit test cases for all behavior changes
|
||||
|
||||
### Submit JUnit test cases for all behavior changes
|
||||
|
||||
Search the codebase to find related tests and add additional `@Test` methods
|
||||
as appropriate. It is also acceptable to submit test cases on a per JIRA issue
|
||||
basis, for example:
|
||||
Search the codebase to find related unit tests and add additional @Test methods
|
||||
within. It is also acceptable to submit test cases on a per JIRA issue basis,
|
||||
e.g.
|
||||
|
||||
```java
|
||||
package org.springframework.beans.factory.support;
|
||||
@@ -163,15 +163,15 @@ public class Spr8954Tests {
|
||||
```
|
||||
|
||||
|
||||
### Squash commits
|
||||
## Squash commits
|
||||
|
||||
Use `git rebase --interactive --autosquash`, `git add --patch`, and other tools
|
||||
to "squash" multiple commits into a single atomic commit. In addition to the man
|
||||
pages for git, there are many resources online to help you understand how these
|
||||
tools work. The [Rewriting History section of Pro Git][] provides a good overview.
|
||||
Use `git rebase --interactive`, `git add --patch` and other tools to "squash"
|
||||
multiple commits into atomic changes. In addition to the man pages for git,
|
||||
there are many resources online to help you understand how these tools work.
|
||||
Here is one: http://book.git-scm.com/4_interactive_rebasing.html.
|
||||
|
||||
|
||||
### Use real name in git commits
|
||||
## Use real name in git commits
|
||||
|
||||
Please configure git to use your real first and last name for any commits you
|
||||
intend to submit as pull requests. For example, this is not acceptable:
|
||||
@@ -183,26 +183,26 @@ submitted against the SpringSource contributor license agreement:
|
||||
|
||||
Author: First Last <user@mail.com>
|
||||
|
||||
This helps ensure traceability against the CLA and also goes a long way to
|
||||
This helps ensure traceability against the CLA, and also goes a long way to
|
||||
ensuring useful output from tools like `git shortlog` and others.
|
||||
|
||||
You can configure this via the account admin area in GitHub (useful for
|
||||
fork-and-edit cases); _globally_ on your machine with
|
||||
You can configure this globally via the account admin area GitHub (useful for
|
||||
fork-and-edit cases); globally with
|
||||
|
||||
git config --global user.name "First Last"
|
||||
git config --global user.email user@mail.com
|
||||
|
||||
or _locally_ for the `spring-framework` repository only by omitting the
|
||||
'--global' flag:
|
||||
or locally for the spring-framework repository only by omitting the '--global'
|
||||
flag:
|
||||
|
||||
cd spring-framework
|
||||
git config user.name "First Last"
|
||||
git config user.email user@mail.com
|
||||
|
||||
|
||||
### Format commit messages
|
||||
## Format commit messages
|
||||
|
||||
Please read and follow the [Commit Guidelines section of Pro Git][].
|
||||
Please read and follow the [commit guidelines section of Pro Git][].
|
||||
|
||||
Most importantly, please format your commit messages in the following way
|
||||
(adapted from the commit template in the link above):
|
||||
@@ -227,33 +227,31 @@ Most importantly, please format your commit messages in the following way
|
||||
|
||||
|
||||
1. Use imperative statements in the subject line, e.g. "Fix broken Javadoc link"
|
||||
1. Begin the subject line with a capitalized verb, e.g. "Add, Prune, Fix,
|
||||
Introduce, Avoid, etc."
|
||||
1. Begin the subject line sentence with a capitalized verb, e.g. "Add, Prune,
|
||||
Fix, Introduce, Avoid, etc."
|
||||
1. Do not end the subject line with a period
|
||||
1. Restrict the subject line to 50 characters or less if possible
|
||||
1. Keep the subject line to 50 characters or less if possible
|
||||
1. Wrap lines in the body at 72 characters or less
|
||||
1. Mention associated JIRA issue(s) at the end of the commit comment, prefixed
|
||||
with "Issue: " as above
|
||||
with "Issue: " as above
|
||||
1. In the body of the commit message, explain how things worked before this
|
||||
commit, what has changed, and how things work now
|
||||
commit, what has changed, and how things work now
|
||||
|
||||
For examples of this style, issue a `git log --author=cbeams` in the
|
||||
`spring-framework` git repository. For convenience, here are several such commits:
|
||||
spring-framework git repository. For convenience, here are several such commits:
|
||||
|
||||
- https://github.com/spring-projects/spring-framework/commit/08e2669b84ec0faa2f7904441fe39ac70b65b078
|
||||
- https://github.com/spring-projects/spring-framework/commit/1d9d3e6ff79ce9f0eca03b02cd1df705925575da
|
||||
- https://github.com/spring-projects/spring-framework/commit/8e0b1c3a5f957af3049cfa0438317177e16d6de6
|
||||
- https://github.com/spring-projects/spring-framework/commit/b787a68f2050df179f7036b209aa741230a02477
|
||||
https://github.com/SpringSource/spring-framework/commit/08e2669b84ec0faa2f7904441fe39ac70b65b078
|
||||
https://github.com/SpringSource/spring-framework/commit/1d9d3e6ff79ce9f0eca03b02cd1df705925575da
|
||||
https://github.com/SpringSource/spring-framework/commit/8e0b1c3a5f957af3049cfa0438317177e16d6de6
|
||||
https://github.com/SpringSource/spring-framework/commit/b787a68f2050df179f7036b209aa741230a02477
|
||||
|
||||
## Run the Final Checklist
|
||||
## Run all tests prior to submission
|
||||
|
||||
### Run all tests prior to submission
|
||||
|
||||
See the [building from source][] section of the `README` for instructions. Make
|
||||
See the [building from source][] section of the README for instructions. Make
|
||||
sure that all tests pass prior to submitting your pull request.
|
||||
|
||||
|
||||
### Submit your pull request
|
||||
## Submit your pull request
|
||||
|
||||
Subject line:
|
||||
|
||||
@@ -265,7 +263,7 @@ In the body:
|
||||
1. Explain your use case. What led you to submit this change? Why were existing
|
||||
mechanisms in the framework insufficient? Make a case that this is a
|
||||
general-purpose problem and that yours is a general-purpose solution, etc.
|
||||
1. Add any additional information and ask questions; start a conversation or
|
||||
1. Add any additional information and ask questions; start a conversation, or
|
||||
continue one from JIRA
|
||||
1. Mention the JIRA issue ID
|
||||
1. Also mention that you have submitted the CLA as described above
|
||||
@@ -276,12 +274,12 @@ the commit message. This is fine, but please also include the items above in the
|
||||
body of the request.
|
||||
|
||||
|
||||
### Mention your pull request on the associated JIRA issue
|
||||
## Mention your pull request on the associated JIRA issue
|
||||
|
||||
Add a comment to the associated JIRA issue(s) linking to your new pull request.
|
||||
|
||||
|
||||
### Expect discussion and rework
|
||||
## Expect discussion and rework
|
||||
|
||||
The Spring team takes a very conservative approach to accepting contributions to
|
||||
the framework. This is to keep code quality and stability as high as possible,
|
||||
@@ -293,15 +291,13 @@ strongly recommend discussing any serious submissions with the Spring Framework
|
||||
team _prior_ to engaging in serious development work.
|
||||
|
||||
Note that you can always force push (`git push -f`) reworked / rebased commits
|
||||
against the branch used to submit your pull request. In other words, you do not
|
||||
need to issue a new pull request when asked to make changes.
|
||||
against the branch used to submit your pull request. i.e. you do not need to
|
||||
issue a new pull request when asked to make changes.
|
||||
|
||||
[help documentation]: http://help.github.com/send-pull-requests
|
||||
[JIRA issue tracker]: https://jira.spring.io/browse/SPR
|
||||
[JIRA issue tracker]: https://jira.springsource.org/browse/SPR
|
||||
[spring-framework-contrib]: https://groups.google.com/forum/#!forum/spring-framework-contrib
|
||||
[SpringSource CLA form]: https://support.springsource.com/spring_committer_signup
|
||||
[fork-and-edit]: https://github.com/blog/844-forking-with-the-edit-button
|
||||
[Spring Framework Code Style]: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Code-Style
|
||||
[Rewriting History section of Pro Git]: http://git-scm.com/book/en/Git-Tools-Rewriting-History
|
||||
[Commit Guidelines section of Pro Git]: http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines
|
||||
[building from source]: https://github.com/spring-projects/spring-framework#building-from-source
|
||||
[commit guidelines section of Pro Git]: http://progit.org/book/ch5-2.html#commit_guidelines
|
||||
[building from source]: https://github.com/SpringSource/spring-framework#building-from-source
|
||||
|
||||
@@ -7,10 +7,12 @@ can focus on application-level business logic, without unnecessary ties to
|
||||
specific deployment environments.
|
||||
|
||||
The framework also serves as the foundation for [Spring Integration][], [Spring
|
||||
Batch][] and the rest of the Spring [family of projects][]. Browse the repositories
|
||||
under the [Spring organization][] on GitHub for a full list.
|
||||
Batch][] and the rest of the Spring [family of projects][]. Browse the
|
||||
repositories under the [SpringSource organization][] on GitHub for a full list.
|
||||
|
||||
## Downloading Artifacts
|
||||
[.NET][] and [Python][] variants are available as well.
|
||||
|
||||
## Downloading artifacts
|
||||
See [downloading Spring artifacts][] for Maven repository information. Unable to
|
||||
use Maven or other transitive dependency management tools? See [building a
|
||||
distribution with dependencies][].
|
||||
@@ -18,7 +20,7 @@ distribution with dependencies][].
|
||||
## Documentation
|
||||
See the current [Javadoc][] and [reference docs][].
|
||||
|
||||
## Getting Support
|
||||
## Getting support
|
||||
Check out the [Spring forums][] and the [spring][spring tag] and
|
||||
[spring-mvc][spring-mvc tag] tags on [Stack Overflow][]. [Commercial support][]
|
||||
is available too.
|
||||
@@ -30,30 +32,23 @@ bug? Please consider submitting a reproduction project via the
|
||||
[spring-framework-issues][] GitHub repository. The [readme][] there provides
|
||||
simple step-by-step instructions.
|
||||
|
||||
## Building from Source
|
||||
## Building from source
|
||||
The Spring Framework uses a [Gradle][]-based build system. In the instructions
|
||||
below, [`./gradlew`][] is invoked from the root of the source tree and serves as
|
||||
a cross-platform, self-contained bootstrap mechanism for the build.
|
||||
a cross-platform, self-contained bootstrap mechanism for the build. The only
|
||||
prerequisites are [Git][] and JDK 1.7+.
|
||||
|
||||
### Prerequisites
|
||||
### check out sources
|
||||
`git clone git://github.com/SpringSource/spring-framework.git`
|
||||
|
||||
[Git][] and [OpenJDK 8 early access build 100 or later][JDK8 build]
|
||||
### compile and test, build all jars, distribution zips and docs
|
||||
`./gradlew build`
|
||||
|
||||
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.8.0` folder
|
||||
extracted from the JDK download.
|
||||
|
||||
### Check out sources
|
||||
`git clone git@github.com:spring-projects/spring-framework.git`
|
||||
|
||||
### Import sources into your IDE
|
||||
Run `./import-into-eclipse.sh` or read `import-into-idea.md` as appropriate.
|
||||
> **Note:** Per the prerequisites above, ensure that you have JDK 8 configured properly in your IDE.
|
||||
|
||||
### Install all spring-\* jars into your local Maven cache
|
||||
### install all spring-\* jars into your local Maven cache
|
||||
`./gradlew install`
|
||||
|
||||
### Compile and test; build all jars, distribution zips, and docs
|
||||
`./gradlew build`
|
||||
### import sources into your IDE
|
||||
Run `./import-into-eclipse.sh` or read `import-into-idea.md` as appropriate.
|
||||
|
||||
... and discover more commands with `./gradlew tasks`. See also the [Gradle
|
||||
build and release FAQ][].
|
||||
@@ -61,41 +56,41 @@ build and release FAQ][].
|
||||
## Contributing
|
||||
[Pull requests][] are welcome; see the [contributor guidelines][] for details.
|
||||
|
||||
## Staying in Touch
|
||||
Follow [@SpringCentral][] as well as [@SpringFramework][] and its [team members][]
|
||||
on Twitter. In-depth articles can be found at [The Spring Blog][], and releases
|
||||
are announced via our [news feed][].
|
||||
## Staying in touch
|
||||
Follow [@springframework][] and its [team members][] on Twitter. In-depth
|
||||
articles can be found at the SpringSource [team blog][], and releases are
|
||||
announced via our [news feed][].
|
||||
|
||||
## License
|
||||
The Spring Framework is released under version 2.0 of the [Apache License][].
|
||||
|
||||
[Spring Integration]: https://github.com/spring-projects/spring-integration
|
||||
[Spring Batch]: https://github.com/spring-projects/spring-batch
|
||||
[family of projects]: http://spring.io/projects
|
||||
[Spring organization]: https://github.com/spring-projects
|
||||
[downloading Spring artifacts]: https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts
|
||||
[building a distribution with dependencies]: https://github.com/spring-projects/spring-framework/wiki/Building-a-distribution-with-dependencies
|
||||
[Javadoc]: http://docs.spring.io/spring-framework/docs/current/javadoc-api/
|
||||
[reference docs]: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/
|
||||
[Spring forums]: http://forum.spring.io/
|
||||
[Spring Integration]: https://github.com/SpringSource/spring-integration
|
||||
[Spring Batch]: https://github.com/SpringSource/spring-batch
|
||||
[family of projects]: http://springsource.org/projects
|
||||
[SpringSource organization]: https://github.com/SpringSource
|
||||
[.NET]: https://github.com/SpringSource/spring-net
|
||||
[Python]: https://github.com/SpringSource/spring-python
|
||||
[downloading Spring artifacts]: https://github.com/SpringSource/spring-framework/wiki/Downloading-Spring-artifacts
|
||||
[building a distribution with dependencies]: https://github.com/SpringSource/spring-framework/wiki/Building-a-distribution-with-dependencies
|
||||
[Javadoc]: http://static.springsource.org/spring-framework/docs/current/javadoc-api
|
||||
[reference docs]: http://static.springsource.org/spring-framework/docs/current/spring-framework-reference
|
||||
[Spring forums]: http://forum.springsource.org
|
||||
[spring tag]: http://stackoverflow.com/questions/tagged/spring
|
||||
[spring-mvc tag]: http://stackoverflow.com/questions/tagged/spring-mvc
|
||||
[Stack Overflow]: http://stackoverflow.com/faq
|
||||
[Commercial support]: http://spring.io/services
|
||||
[Spring Framework JIRA]: https://jira.spring.io/browse/SPR
|
||||
[the lifecycle of an issue]: https://github.com/spring-projects/spring-framework/wiki/The-Lifecycle-of-an-Issue
|
||||
[spring-framework-issues]: https://github.com/spring-projects/spring-framework-issues#readme
|
||||
[readme]: https://github.com/spring-projects/spring-framework-issues#readme
|
||||
[Commercial support]: http://springsource.com/support/springsupport
|
||||
[Spring Framework JIRA]: http://jira.springsource.org/browse/SPR
|
||||
[the lifecycle of an issue]: https://github.com/cbeams/spring-framework/wiki/The-Lifecycle-of-an-Issue
|
||||
[spring-framework-issues]: https://github.com/SpringSource/spring-framework-issues#readme
|
||||
[readme]: https://github.com/SpringSource/spring-framework-issues#readme
|
||||
[Gradle]: http://gradle.org
|
||||
[`./gradlew`]: http://vimeo.com/34436402
|
||||
[Git]: http://help.github.com/set-up-git-redirect
|
||||
[JDK8 build]: http://jdk8.java.net/download.html
|
||||
[Gradle build and release FAQ]: https://github.com/spring-projects/spring-framework/wiki/Gradle-build-and-release-FAQ
|
||||
[Gradle build and release FAQ]: https://github.com/SpringSource/spring-framework/wiki/Gradle-build-and-release-FAQ
|
||||
[Pull requests]: http://help.github.com/send-pull-requests
|
||||
[contributor guidelines]: https://github.com/spring-projects/spring-framework/blob/master/CONTRIBUTING.md
|
||||
[@SpringFramework]: https://twitter.com/springframework
|
||||
[@SpringCentral]: https://twitter.com/springcentral
|
||||
[team members]: https://twitter.com/springframework/team/members
|
||||
[The Spring Blog]: http://spring.io/blog/
|
||||
[news feed]: http://spring.io/blog/category/news
|
||||
[contributor guidelines]: https://github.com/SpringSource/spring-framework/blob/master/CONTRIBUTING.md
|
||||
[@springframework]: http://twitter.com/springframework
|
||||
[team members]: http://twitter.com/springframework/team/members
|
||||
[team blog]: http://blog.springsource.org
|
||||
[news feed]: http://www.springsource.org/news-events
|
||||
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
+372
-572
File diff suppressed because it is too large
Load Diff
@@ -21,17 +21,20 @@ import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.artifacts.maven.Conf2ScopeMapping
|
||||
import org.gradle.api.plugins.MavenPlugin
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
import org.gradle.plugins.ide.eclipse.model.EclipseClasspath;
|
||||
import org.gradle.plugins.ide.idea.IdeaPlugin
|
||||
import org.gradle.api.invocation.*
|
||||
|
||||
|
||||
/**
|
||||
* Gradle plugin that allows projects to merged together. Primarily developed to
|
||||
* allow Spring to support multiple incompatible versions of third-party
|
||||
* allow Spring to support multiple multiple incompatible versions of third-party
|
||||
* dependencies (for example Hibernate v3 and v4).
|
||||
* <p>
|
||||
* The 'merge' extension should be used to define how projects are merged, for example:
|
||||
* <pre class="code">
|
||||
* <pre>
|
||||
* configure(subprojects) {
|
||||
* apply plugin: MergePlugin
|
||||
* }
|
||||
@@ -73,13 +76,13 @@ class MergePlugin implements Plugin<Project> {
|
||||
|
||||
// Hook to perform the actual merge logic
|
||||
project.afterEvaluate{
|
||||
if (it.merge.into != null) {
|
||||
if(it.merge.into != null) {
|
||||
setup(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to build runtimeMerge dependencies
|
||||
if (!attachedProjectsEvaluated) {
|
||||
if(!attachedProjectsEvaluated) {
|
||||
project.gradle.projectsEvaluated{
|
||||
postProcessProjects(it)
|
||||
}
|
||||
@@ -99,7 +102,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
// invoking a task will invoke the task with the same name on 'into' project
|
||||
["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish"].each {
|
||||
def task = project.tasks.findByPath(it)
|
||||
if (task) {
|
||||
if(task) {
|
||||
task.enabled = false
|
||||
task.dependsOn(project.merge.into.tasks.findByPath(it))
|
||||
}
|
||||
@@ -117,7 +120,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
private void setupMaven(Project project) {
|
||||
project.configurations.each { configuration ->
|
||||
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
|
||||
if (mapping.scope) {
|
||||
if(mapping.scope) {
|
||||
Configuration intoConfiguration = project.merge.into.configurations.create(
|
||||
project.name + "-" + configuration.name)
|
||||
configuration.excludeRules.each {
|
||||
@@ -128,7 +131,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
configuration.dependencies.each {
|
||||
def intoCompile = project.merge.into.configurations.getByName("compile")
|
||||
// Protect against changing a compile scope dependency (SPR-10218)
|
||||
if (!intoCompile.dependencies.contains(it)) {
|
||||
if(!intoCompile.dependencies.contains(it)) {
|
||||
intoConfiguration.dependencies.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
|
||||
|
||||
/**
|
||||
* Gradle plugin that automatically updates testCompile dependencies to include
|
||||
* the test source sets of project dependencies.
|
||||
@@ -40,10 +41,11 @@ class TestSourceSetDependenciesPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
|
||||
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies, Project project) {
|
||||
for (def configurationName in ["compile", "optional", "provided", "testCompile"]) {
|
||||
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies,
|
||||
Project project) {
|
||||
for(def configurationName in ["compile", "optional", "provided", "testCompile"]) {
|
||||
Configuration configuration = project.getConfigurations().findByName(configurationName)
|
||||
if (configuration) {
|
||||
if(configuration) {
|
||||
configuration.dependencies.findAll { it instanceof ProjectDependency }.each {
|
||||
projectDependencies.add(it)
|
||||
collectProjectDependencies(projectDependencies, it.dependencyProject)
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.0.10.BUILD-SNAPSHOT
|
||||
version=3.2.5.RELEASE
|
||||
|
||||
@@ -5,12 +5,6 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
|
||||
apply plugin: "propdeps-eclipse"
|
||||
apply plugin: "propdeps-idea"
|
||||
|
||||
// Until eclipse fully supports Java 8 use 1.7 source level
|
||||
eclipse.jdt {
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
}
|
||||
|
||||
// Replace classpath entries with project dependencies (GRADLE-1116)
|
||||
eclipse.classpath.file.whenMerged { classpath ->
|
||||
def regexp = /.*?\/([^\/]+)\/build\/[^\/]+\/(?:main|test)/ // only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
|
||||
@@ -47,17 +41,6 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
|
||||
// https://jira.spring.io/browse/SPR-11836
|
||||
eclipse.classpath.file.whenMerged { classpath ->
|
||||
classpath.entries.findAll { it instanceof ProjectDependency }.each {
|
||||
// delete from original position
|
||||
classpath.entries.remove(it)
|
||||
// append to end of classpath
|
||||
classpath.entries.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Allow projects to be used as WPT modules
|
||||
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
|
||||
|
||||
|
||||
@@ -22,34 +22,30 @@ def customizePom(pom, gradleProject) {
|
||||
generatedPom.project {
|
||||
name = gradleProject.description
|
||||
description = gradleProject.description
|
||||
url = "https://github.com/spring-projects/spring-framework"
|
||||
url = "https://github.com/SpringSource/spring-framework"
|
||||
organization {
|
||||
name = "Spring IO"
|
||||
url = "https://projects.spring.io/spring-framework"
|
||||
name = "SpringSource"
|
||||
url = "http://springsource.org/spring-framework"
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name "The Apache Software License, Version 2.0"
|
||||
url "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
distribution "repo"
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = "https://github.com/spring-projects/spring-framework"
|
||||
connection = "scm:git:git://github.com/spring-projects/spring-framework"
|
||||
developerConnection = "scm:git:git://github.com/spring-projects/spring-framework"
|
||||
url = "https://github.com/SpringSource/spring-framework"
|
||||
connection = "scm:git:git://github.com/SpringSource/spring-framework"
|
||||
developerConnection = "scm:git:git://github.com/SpringSource/spring-framework"
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = "jhoeller"
|
||||
name = "Juergen Hoeller"
|
||||
email = "jhoeller@gopivotal.com"
|
||||
email = "jhoeller@vmware.com"
|
||||
}
|
||||
}
|
||||
issueManagement {
|
||||
system = "Jira"
|
||||
url = "https://jira.springsource.org/browse/SPR"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+4
-4
@@ -1,6 +1,6 @@
|
||||
#Wed Apr 30 13:06:57 CEST 2014
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
#Tue Jul 30 09:29:28 PDT 2013
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
GRADLE_OPTS="-XX:MaxMetaspaceSize=1024m -Xmx1024m $GRADLE_OPTS"
|
||||
GRADLE_OPTS="-XX:MaxPermSize=1024m -Xmx1024m $GRADLE_OPTS"
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
|
||||
Vendored
+1
-1
@@ -9,7 +9,7 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set GRADLE_OPTS=-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set GRADLE_OPTS=-XX:MaxPermSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
|
||||
@@ -17,7 +17,7 @@ echo been tested against STS %STS_TEST_VERSION%), but at the minimum you will
|
||||
echo need Eclipse + AJDT.
|
||||
echo.
|
||||
echo If you need to download and install STS, please do that now by
|
||||
echo visiting https://spring.io/tools/sts/all
|
||||
echo visiting http://springsource.org/downloads/sts
|
||||
echo.
|
||||
echo Otherwise, press enter and we'll begin.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ been tested against STS $STS_TEST_VERSION), but at the minimum you will
|
||||
need Eclipse + AJDT.
|
||||
|
||||
If you need to download and install STS, please do that now by
|
||||
visiting https://spring.io/tools/sts/all
|
||||
visiting http://springsource.org/downloads/sts
|
||||
|
||||
Otherwise, press enter and we'll begin.
|
||||
EOM
|
||||
|
||||
+2
-3
@@ -12,11 +12,10 @@ _Within your locally cloned spring-framework working directory:_
|
||||
|
||||
## Known issues
|
||||
|
||||
1. Those steps don't work currently for Intellij IDEA 13+
|
||||
2. `spring-aspects` does not compile out of the box due to references to aspect types unknown to IDEA.
|
||||
1. `spring-aspects` does not compile out of the box due to references to aspect types unknown to IDEA.
|
||||
See http://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the 'spring-aspects'
|
||||
module has been excluded from the overall project to avoid compilation errors.
|
||||
3. While all JUnit tests pass from the command line with Gradle, many will fail when run from IDEA.
|
||||
2. While all JUnit tests pass from the command line with Gradle, many will fail when run from IDEA.
|
||||
Resolving this is a work in progress. If attempting to run all JUnit tests from within IDEA, you will
|
||||
likely need to set the following VM options to avoid out of memory errors:
|
||||
-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
|
||||
|
||||
+2
-4
@@ -3,7 +3,6 @@ rootProject.name = "spring"
|
||||
include "spring-aop"
|
||||
include "spring-aspects"
|
||||
include "spring-beans"
|
||||
include "spring-beans-groovy"
|
||||
include "spring-context"
|
||||
include "spring-context-support"
|
||||
include "spring-core"
|
||||
@@ -12,18 +11,17 @@ include "spring-instrument"
|
||||
include "spring-instrument-tomcat"
|
||||
include "spring-jdbc"
|
||||
include "spring-jms"
|
||||
include "spring-messaging"
|
||||
include "spring-orm"
|
||||
include "spring-orm-hibernate4"
|
||||
include "spring-oxm"
|
||||
include "spring-struts"
|
||||
include "spring-test"
|
||||
include "spring-test-mvc"
|
||||
include "spring-tx"
|
||||
include "spring-web"
|
||||
include "spring-webmvc"
|
||||
include "spring-webmvc-portlet"
|
||||
include "spring-webmvc-tiles3"
|
||||
include "spring-websocket"
|
||||
include "spring-framework-bom"
|
||||
|
||||
// Exposes gradle buildSrc for IDE support
|
||||
include "buildSrc"
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,9 +19,9 @@ package org.springframework.aop;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A specialized type of {@link MethodMatcher} that takes into account introductions
|
||||
* when matching methods. If there are no introductions on the target class,
|
||||
* a method matcher may be able to optimize matching more effectively for example.
|
||||
* A specialized type of MethodMatcher that takes into account introductions when
|
||||
* matching methods. If there are no introductions on the target class, a method
|
||||
* matcher may be able to optimize matching more effectively for example.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
@@ -39,6 +39,6 @@ public interface IntroductionAwareMethodMatcher extends MethodMatcher {
|
||||
* asking is the subject on one or more introductions; {@code false} otherwise
|
||||
* @return whether or not this method matches statically
|
||||
*/
|
||||
boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions);
|
||||
boolean matches(Method method, Class targetClass, boolean hasIntroductions);
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,6 @@ public interface IntroductionInfo {
|
||||
* Return the additional interfaces introduced by this Advisor or Advice.
|
||||
* @return the introduced interfaces
|
||||
*/
|
||||
Class<?>[] getInterfaces();
|
||||
Class[] getInterfaces();
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ public interface TargetSource extends TargetClassAware {
|
||||
* target class.
|
||||
* @return the type of targets returned by this {@link TargetSource}
|
||||
*/
|
||||
@Override
|
||||
Class<?> getTargetClass();
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,8 +34,7 @@ class TrueClassFilter implements ClassFilter, Serializable {
|
||||
private TrueClassFilter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Class<?> clazz) {
|
||||
public boolean matches(Class clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,18 +35,15 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
private TrueMethodMatcher() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
public boolean matches(Method method, Class targetClass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class targetClass, Object[] args) {
|
||||
// Should never be invoked as isRuntime returns false.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -34,12 +34,10 @@ class TruePointcut implements Pointcut, Serializable {
|
||||
private TruePointcut() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassFilter getClassFilter() {
|
||||
return ClassFilter.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return MethodMatcher.TRUE;
|
||||
}
|
||||
|
||||
+21
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,8 +37,9 @@ import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.aop.support.MethodMatchers;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.PrioritizedParameterNameDiscoverer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -119,9 +120,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
/** Non-null if after returning advice binds the return value */
|
||||
private String returningName = null;
|
||||
|
||||
private Class<?> discoveredReturningType = Object.class;
|
||||
private Class discoveredReturningType = Object.class;
|
||||
|
||||
private Class<?> discoveredThrowingType = Object.class;
|
||||
private Class discoveredThrowingType = Object.class;
|
||||
|
||||
/**
|
||||
* Index for thisJoinPoint argument (currently only
|
||||
@@ -202,7 +203,6 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
return this.aspectInstanceFactory.getAspectClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.aspectInstanceFactory.getOrder();
|
||||
}
|
||||
@@ -212,7 +212,6 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.aspectName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAspectName() {
|
||||
return this.aspectName;
|
||||
}
|
||||
@@ -224,7 +223,6 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.declarationOrder = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeclarationOrder() {
|
||||
return this.declarationOrder;
|
||||
}
|
||||
@@ -240,7 +238,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
setArgumentNamesFromStringArray(tokens);
|
||||
}
|
||||
|
||||
public void setArgumentNamesFromStringArray(String... args) {
|
||||
public void setArgumentNamesFromStringArray(String[] args) {
|
||||
this.argumentNames = new String[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
this.argumentNames[i] = StringUtils.trimWhitespace(args[i]);
|
||||
@@ -253,7 +251,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
if (argumentNames != null) {
|
||||
if (aspectJAdviceMethod.getParameterTypes().length == argumentNames.length + 1) {
|
||||
// May need to add implicit join point arg name...
|
||||
Class<?> firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
|
||||
Class firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
|
||||
if (firstArgType == JoinPoint.class ||
|
||||
firstArgType == ProceedingJoinPoint.class ||
|
||||
firstArgType == JoinPoint.StaticPart.class) {
|
||||
@@ -292,7 +290,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> getDiscoveredReturningType() {
|
||||
protected Class getDiscoveredReturningType() {
|
||||
return this.discoveredReturningType;
|
||||
}
|
||||
|
||||
@@ -326,7 +324,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> getDiscoveredThrowingType() {
|
||||
protected Class getDiscoveredThrowingType() {
|
||||
return this.discoveredThrowingType;
|
||||
}
|
||||
|
||||
@@ -364,7 +362,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
int numUnboundArgs = this.adviceInvocationArgumentCount;
|
||||
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
Class[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
|
||||
numUnboundArgs--;
|
||||
}
|
||||
@@ -380,7 +378,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.argumentsIntrospected = true;
|
||||
}
|
||||
|
||||
private boolean maybeBindJoinPoint(Class<?> candidateParameterType) {
|
||||
private boolean maybeBindJoinPoint(Class candidateParameterType) {
|
||||
if (candidateParameterType.equals(JoinPoint.class)) {
|
||||
this.joinPointArgumentIndex = 0;
|
||||
return true;
|
||||
@@ -390,7 +388,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
}
|
||||
|
||||
private boolean maybeBindProceedingJoinPoint(Class<?> candidateParameterType) {
|
||||
private boolean maybeBindProceedingJoinPoint(Class candidateParameterType) {
|
||||
if (candidateParameterType.equals(ProceedingJoinPoint.class)) {
|
||||
if (!supportsProceedingJoinPoint()) {
|
||||
throw new IllegalArgumentException("ProceedingJoinPoint is only supported for around advice");
|
||||
@@ -407,7 +405,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean maybeBindJoinPointStaticPart(Class<?> candidateParameterType) {
|
||||
private boolean maybeBindJoinPointStaticPart(Class candidateParameterType) {
|
||||
if (candidateParameterType.equals(JoinPoint.StaticPart.class)) {
|
||||
this.joinPointStaticPartArgumentIndex = 0;
|
||||
return true;
|
||||
@@ -434,13 +432,15 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
|
||||
/**
|
||||
* Create a ParameterNameDiscoverer to be used for argument binding.
|
||||
* <p>The default implementation creates a {@link DefaultParameterNameDiscoverer}
|
||||
* and adds a specifically configured {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
* <p>The default implementation creates a {@link PrioritizedParameterNameDiscoverer}
|
||||
* containing a {@link LocalVariableTableParameterNameDiscoverer} and an
|
||||
* {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
*/
|
||||
protected ParameterNameDiscoverer createParameterNameDiscoverer() {
|
||||
// We need to discover them, or if that fails, guess,
|
||||
// and if we can't guess with 100% accuracy, fail.
|
||||
DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
|
||||
PrioritizedParameterNameDiscoverer discoverer = new PrioritizedParameterNameDiscoverer();
|
||||
discoverer.addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
|
||||
AspectJAdviceParameterNameDiscoverer adviceParameterNameDiscoverer =
|
||||
new AspectJAdviceParameterNameDiscoverer(this.pointcut.getExpression());
|
||||
adviceParameterNameDiscoverer.setReturningName(this.returningName);
|
||||
@@ -509,8 +509,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
numParametersToRemove++;
|
||||
}
|
||||
String[] pointcutParameterNames = new String[this.argumentNames.length - numParametersToRemove];
|
||||
Class<?>[] pointcutParameterTypes = new Class<?>[pointcutParameterNames.length];
|
||||
Class<?>[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
Class[] pointcutParameterTypes = new Class[pointcutParameterNames.length];
|
||||
Class[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < this.argumentNames.length; i++) {
|
||||
@@ -678,8 +678,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.adviceMethod = adviceMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
public boolean matches(Method method, Class targetClass) {
|
||||
return !this.adviceMethod.equals(method);
|
||||
}
|
||||
|
||||
|
||||
+9
-8
@@ -21,6 +21,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -28,6 +29,7 @@ import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.weaver.tools.PointcutParser;
|
||||
import org.aspectj.weaver.tools.PointcutPrimitive;
|
||||
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -140,8 +142,9 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
singleValuedAnnotationPcds.add("@withincode");
|
||||
singleValuedAnnotationPcds.add("@annotation");
|
||||
|
||||
Set<PointcutPrimitive> pointcutPrimitives = PointcutParser.getAllSupportedPointcutPrimitives();
|
||||
for (PointcutPrimitive primitive : pointcutPrimitives) {
|
||||
Set pointcutPrimitives = PointcutParser.getAllSupportedPointcutPrimitives();
|
||||
for (Iterator iterator = pointcutPrimitives.iterator(); iterator.hasNext();) {
|
||||
PointcutPrimitive primitive = (PointcutPrimitive) iterator.next();
|
||||
nonReferencePointcutTokens.add(primitive.getName());
|
||||
}
|
||||
nonReferencePointcutTokens.add("&&");
|
||||
@@ -170,7 +173,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
*/
|
||||
private String pointcutExpression;
|
||||
|
||||
private Class<?>[] argumentTypes;
|
||||
private Class[] argumentTypes;
|
||||
|
||||
private String[] parameterNameBindings;
|
||||
|
||||
@@ -219,7 +222,6 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* @param method the target {@link Method}
|
||||
* @return the parameter names
|
||||
*/
|
||||
@Override
|
||||
public String[] getParameterNames(Method method) {
|
||||
this.argumentTypes = method.getParameterTypes();
|
||||
this.numberOfRemainingUnboundArguments = this.argumentTypes.length;
|
||||
@@ -307,8 +309,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* @throws UnsupportedOperationException if
|
||||
* {@link #setRaiseExceptions(boolean) raiseExceptions} has been set to {@code true}
|
||||
*/
|
||||
@Override
|
||||
public String[] getParameterNames(Constructor<?> ctor) {
|
||||
public String[] getParameterNames(Constructor ctor) {
|
||||
if (this.raiseExceptions) {
|
||||
throw new UnsupportedOperationException("An advice method can never be a constructor");
|
||||
}
|
||||
@@ -728,7 +729,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* Return {@code true} if the given argument type is a subclass
|
||||
* of the given supertype.
|
||||
*/
|
||||
private boolean isSubtypeOf(Class<?> supertype, int argumentNumber) {
|
||||
private boolean isSubtypeOf(Class supertype, int argumentNumber) {
|
||||
return supertype.isAssignableFrom(this.argumentTypes[argumentNumber]);
|
||||
}
|
||||
|
||||
@@ -756,7 +757,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* Find the argument index with the given type, and bind the given
|
||||
* {@code varName} in that position.
|
||||
*/
|
||||
private void findAndBind(Class<?> argumentType, String varName) {
|
||||
private void findAndBind(Class argumentType, String varName) {
|
||||
for (int i = 0; i < this.argumentTypes.length; i++) {
|
||||
if (isUnbound(i) && isSubtypeOf(argumentType, i)) {
|
||||
bindParameterName(i, varName);
|
||||
|
||||
@@ -37,7 +37,6 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
@@ -47,12 +46,10 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+4
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,12 +40,10 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
return true;
|
||||
}
|
||||
@@ -55,7 +53,6 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
setReturningNameNoCheck(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
|
||||
if (shouldInvokeOnReturnValueOf(method, returnValue)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
|
||||
@@ -71,34 +68,12 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
* @return whether to invoke the advice method for the given return value
|
||||
*/
|
||||
private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) {
|
||||
Class<?> type = getDiscoveredReturningType();
|
||||
Class type = getDiscoveredReturningType();
|
||||
Type genericType = getDiscoveredReturningGenericType();
|
||||
// If we aren't dealing with a raw type, check if generic parameters are assignable.
|
||||
return (matchesReturnValue(type, method, returnValue) &&
|
||||
// If we aren't dealing with a raw type, check if generic parameters are assignable.
|
||||
return (ClassUtils.isAssignableValue(type, returnValue) &&
|
||||
(genericType == null || genericType == type ||
|
||||
TypeUtils.isAssignable(genericType, method.getGenericReturnType())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Following AspectJ semantics, if a return value is null (or return type is void),
|
||||
* then the return type of target method should be used to determine whether advice
|
||||
* is invoked or not. Also, even if the return type is void, if the type of argument
|
||||
* declared in the advice method is Object, then the advice must still get invoked.
|
||||
* @param type the type of argument declared in advice method
|
||||
* @param method the advice method
|
||||
* @param returnValue the return value of the target method
|
||||
* @return whether to invoke the advice method for the given return value and type
|
||||
*/
|
||||
private boolean matchesReturnValue(Class<?> type, Method method, Object returnValue) {
|
||||
if (returnValue != null) {
|
||||
return ClassUtils.isAssignableValue(type, returnValue);
|
||||
}
|
||||
else if (type.equals(Object.class) && method.getReturnType().equals(void.class)) {
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return ClassUtils.isAssignable(type, method.getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,12 +37,10 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
return true;
|
||||
}
|
||||
@@ -52,7 +50,6 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
setThrowingNameNoCheck(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
@@ -70,7 +67,8 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
* is only invoked if the thrown exception is a subtype of the given throwing type.
|
||||
*/
|
||||
private boolean shouldInvokeOnThrowing(Throwable t) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(t.getClass());
|
||||
Class throwingType = getDiscoveredThrowingType();
|
||||
return throwingType.isAssignableFrom(t.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,12 +41,10 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
super(aspectJAroundAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
return false;
|
||||
}
|
||||
@@ -57,7 +55,6 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
|
||||
+101
-125
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.weaver.BCException;
|
||||
import org.aspectj.weaver.patterns.NamePattern;
|
||||
import org.aspectj.weaver.reflect.ReflectionWorld;
|
||||
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
|
||||
import org.aspectj.weaver.reflect.ShadowMatchImpl;
|
||||
import org.aspectj.weaver.tools.ContextBasedMatcher;
|
||||
@@ -41,7 +42,6 @@ import org.aspectj.weaver.tools.PointcutParameter;
|
||||
import org.aspectj.weaver.tools.PointcutParser;
|
||||
import org.aspectj.weaver.tools.PointcutPrimitive;
|
||||
import org.aspectj.weaver.tools.ShadowMatch;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.IntroductionAwareMethodMatcher;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
@@ -55,7 +55,6 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -99,16 +98,14 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
|
||||
|
||||
private Class<?> pointcutDeclarationScope;
|
||||
private Class pointcutDeclarationScope;
|
||||
|
||||
private String[] pointcutParameterNames = new String[0];
|
||||
|
||||
private Class<?>[] pointcutParameterTypes = new Class<?>[0];
|
||||
private Class[] pointcutParameterTypes = new Class[0];
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private transient ClassLoader pointcutClassLoader;
|
||||
|
||||
private transient PointcutExpression pointcutExpression;
|
||||
|
||||
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
|
||||
@@ -126,7 +123,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
* @param paramNames the parameter names for the pointcut
|
||||
* @param paramTypes the parameter types for the pointcut
|
||||
*/
|
||||
public AspectJExpressionPointcut(Class<?> declarationScope, String[] paramNames, Class<?>[] paramTypes) {
|
||||
public AspectJExpressionPointcut(Class declarationScope, String[] paramNames, Class[] paramTypes) {
|
||||
this.pointcutDeclarationScope = declarationScope;
|
||||
if (paramNames.length != paramTypes.length) {
|
||||
throw new IllegalStateException(
|
||||
@@ -140,37 +137,34 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
/**
|
||||
* Set the declaration scope for the pointcut.
|
||||
*/
|
||||
public void setPointcutDeclarationScope(Class<?> pointcutDeclarationScope) {
|
||||
public void setPointcutDeclarationScope(Class pointcutDeclarationScope) {
|
||||
this.pointcutDeclarationScope = pointcutDeclarationScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parameter names for the pointcut.
|
||||
*/
|
||||
public void setParameterNames(String... names) {
|
||||
public void setParameterNames(String[] names) {
|
||||
this.pointcutParameterNames = names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parameter types for the pointcut.
|
||||
*/
|
||||
public void setParameterTypes(Class<?>... types) {
|
||||
public void setParameterTypes(Class[] types) {
|
||||
this.pointcutParameterTypes = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClassFilter getClassFilter() {
|
||||
checkReadyToMatch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
checkReadyToMatch();
|
||||
return this;
|
||||
@@ -186,13 +180,20 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
throw new IllegalStateException("Must set property 'expression' before attempting to match");
|
||||
}
|
||||
if (this.pointcutExpression == null) {
|
||||
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
|
||||
this.pointcutExpression = buildPointcutExpression();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
private PointcutExpression buildPointcutExpression() {
|
||||
ClassLoader cl = (this.beanFactory instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) this.beanFactory)
|
||||
.getBeanClassLoader() : Thread.currentThread()
|
||||
.getContextClassLoader());
|
||||
return buildPointcutExpression(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
@@ -201,7 +202,8 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
|
||||
for (int i = 0; i < pointcutParameters.length; i++) {
|
||||
pointcutParameters[i] = parser.createPointcutParameter(
|
||||
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
|
||||
this.pointcutParameterNames[i],
|
||||
this.pointcutParameterTypes[i]);
|
||||
}
|
||||
return parser.parsePointcutExpression(
|
||||
replaceBooleanOperators(getExpression()),
|
||||
@@ -242,30 +244,30 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
return this.pointcutExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Class<?> targetClass) {
|
||||
public boolean matches(Class targetClass) {
|
||||
checkReadyToMatch();
|
||||
try {
|
||||
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
} catch (ReflectionWorldException e) {
|
||||
logger.debug("PointcutExpression matching rejected target class", e);
|
||||
try {
|
||||
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
catch (ReflectionWorldException ex) {
|
||||
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
|
||||
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
|
||||
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
|
||||
if (fallbackExpression != null) {
|
||||
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
// Actually this is still a "maybe" - treat the pointcut as dynamic if we
|
||||
// don't know enough yet
|
||||
return getFallbackPointcutExpression(targetClass).couldMatchJoinPointsInType(targetClass);
|
||||
} catch (BCException ex) {
|
||||
logger.debug(
|
||||
"Fallback PointcutExpression matching rejected target class",
|
||||
ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (BCException ex) {
|
||||
logger.debug("PointcutExpression matching rejected target class", ex);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
|
||||
public boolean matches(Method method, Class targetClass, boolean beanHasIntroductions) {
|
||||
checkReadyToMatch();
|
||||
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
|
||||
ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);
|
||||
@@ -281,31 +283,20 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
else {
|
||||
// the maybe case
|
||||
if (beanHasIntroductions) {
|
||||
return true;
|
||||
}
|
||||
// A match test returned maybe - if there are any subtype sensitive variables
|
||||
// involved in the test (this, target, at_this, at_target, at_annotation) then
|
||||
// we say this is not a match as in Spring there will never be a different
|
||||
// runtime subtype.
|
||||
RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch);
|
||||
return (!walker.testsSubtypeSensitiveVars() || walker.testTargetInstanceOfResidue(targetClass));
|
||||
return (beanHasIntroductions || matchesIgnoringSubtypes(shadowMatch) || matchesTarget(shadowMatch, targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
public boolean matches(Method method, Class targetClass) {
|
||||
return matches(method, targetClass, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntime() {
|
||||
checkReadyToMatch();
|
||||
return this.pointcutExpression.mayNeedDynamicTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class targetClass, Object[] args) {
|
||||
checkReadyToMatch();
|
||||
ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
|
||||
ShadowMatch originalShadowMatch = getShadowMatch(method, method);
|
||||
@@ -345,37 +336,46 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
|
||||
return false;
|
||||
}
|
||||
if (joinPointMatch.matches()) {
|
||||
bindParameters(pmi, joinPointMatch);
|
||||
}
|
||||
}
|
||||
if (joinPointMatch.matches() && pmi != null) {
|
||||
bindParameters(pmi, joinPointMatch);
|
||||
}
|
||||
return joinPointMatch.matches();
|
||||
}
|
||||
|
||||
|
||||
protected String getCurrentProxiedBeanName() {
|
||||
return ProxyCreationContext.getCurrentProxiedBeanName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a new pointcut expression based on a target class's loader rather than the default.
|
||||
* Get a new pointcut expression based on a target class's loader, rather
|
||||
* than the default.
|
||||
*/
|
||||
private PointcutExpression getFallbackPointcutExpression(Class<?> targetClass) {
|
||||
try {
|
||||
ClassLoader classLoader = targetClass.getClassLoader();
|
||||
if (classLoader != null && classLoader != this.pointcutClassLoader) {
|
||||
return buildPointcutExpression(classLoader);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Failed to create fallback PointcutExpression", ex);
|
||||
}
|
||||
return null;
|
||||
private PointcutExpression getFallbackPointcutExpression(
|
||||
Class<?> targetClass) {
|
||||
ClassLoader classLoader = targetClass.getClassLoader();
|
||||
return classLoader == null ? this.pointcutExpression : buildPointcutExpression(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* A match test returned maybe - if there are any subtype sensitive variables
|
||||
* involved in the test (this, target, at_this, at_target, at_annotation) then
|
||||
* we say this is not a match as in Spring there will never be a different
|
||||
* runtime subtype.
|
||||
*/
|
||||
private boolean matchesIgnoringSubtypes(ShadowMatch shadowMatch) {
|
||||
return !(getRuntimeTestWalker(shadowMatch).testsSubtypeSensitiveVars());
|
||||
}
|
||||
|
||||
private boolean matchesTarget(ShadowMatch shadowMatch, Class targetClass) {
|
||||
return getRuntimeTestWalker(shadowMatch).testTargetInstanceOfResidue(targetClass);
|
||||
}
|
||||
|
||||
private RuntimeTestWalker getRuntimeTestWalker(ShadowMatch shadowMatch) {
|
||||
if (shadowMatch instanceof DefensiveShadowMatch) {
|
||||
return new RuntimeTestWalker(((DefensiveShadowMatch) shadowMatch).primary);
|
||||
return new RuntimeTestWalker(((DefensiveShadowMatch)shadowMatch).primary);
|
||||
}
|
||||
return new RuntimeTestWalker(shadowMatch);
|
||||
}
|
||||
@@ -396,51 +396,44 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
if (shadowMatch == null) {
|
||||
synchronized (this.shadowMatchCache) {
|
||||
// Not found - now check again with full lock...
|
||||
PointcutExpression fallbackExpression = null;
|
||||
Method methodToMatch = targetMethod;
|
||||
shadowMatch = this.shadowMatchCache.get(targetMethod);
|
||||
PointcutExpression fallbackPointcutExpression = null;
|
||||
shadowMatch = this.shadowMatchCache.get(methodToMatch);
|
||||
if (shadowMatch == null) {
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod);
|
||||
}
|
||||
catch (ReflectionWorldException ex) {
|
||||
catch (ReflectionWorld.ReflectionWorldException ex) {
|
||||
// Failed to introspect target method, probably because it has been loaded
|
||||
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
|
||||
// in a special ClassLoader. Let's try the original method instead...
|
||||
try {
|
||||
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
if (fallbackExpression != null) {
|
||||
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
|
||||
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
} catch (ReflectionWorld.ReflectionWorldException e) {
|
||||
if (targetMethod == originalMethod) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
}
|
||||
}
|
||||
catch (ReflectionWorldException ex2) {
|
||||
fallbackExpression = null;
|
||||
}
|
||||
}
|
||||
if (shadowMatch == null && targetMethod != originalMethod) {
|
||||
methodToMatch = originalMethod;
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorldException ex3) {
|
||||
// Could neither introspect the target class nor the proxy class ->
|
||||
// let's try the original method's declaring class before we give up...
|
||||
try {
|
||||
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
if (fallbackExpression != null) {
|
||||
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
|
||||
else {
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod);
|
||||
}
|
||||
catch (ReflectionWorld.ReflectionWorldException ex2) {
|
||||
// Could neither introspect the target class nor the proxy class ->
|
||||
// let's simply consider this method as non-matching.
|
||||
methodToMatch = originalMethod;
|
||||
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
try {
|
||||
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
} catch (ReflectionWorld.ReflectionWorldException e2) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ReflectionWorldException ex4) {
|
||||
fallbackExpression = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shadowMatch == null) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
}
|
||||
else if (shadowMatch.maybeMatches() && fallbackExpression != null) {
|
||||
if (shadowMatch.maybeMatches() && fallbackPointcutExpression!=null) {
|
||||
shadowMatch = new DefensiveShadowMatch(shadowMatch,
|
||||
fallbackExpression.matchesMethodExecution(methodToMatch));
|
||||
fallbackPointcutExpression.matchesMethodExecution(methodToMatch));
|
||||
}
|
||||
this.shadowMatchCache.put(targetMethod, shadowMatch);
|
||||
}
|
||||
@@ -513,12 +506,10 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
private static final String BEAN_DESIGNATOR_NAME = "bean";
|
||||
|
||||
@Override
|
||||
public String getDesignatorName() {
|
||||
return BEAN_DESIGNATOR_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextBasedMatcher parse(String expression) {
|
||||
return new BeanNameContextMatcher(expression);
|
||||
}
|
||||
@@ -540,36 +531,27 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
this.expressionPattern = new NamePattern(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Deprecated
|
||||
public boolean couldMatchJoinPointsInType(Class someClass) {
|
||||
return (contextMatch(someClass) == FuzzyBoolean.YES);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Deprecated
|
||||
public boolean couldMatchJoinPointsInType(Class someClass, MatchingContext context) {
|
||||
return (contextMatch(someClass) == FuzzyBoolean.YES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesDynamically(MatchingContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyBoolean matchesStatically(MatchingContext context) {
|
||||
return contextMatch(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayNeedDynamicTest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private FuzzyBoolean contextMatch(Class<?> targetType) {
|
||||
private FuzzyBoolean contextMatch(Class targetType) {
|
||||
String advisedBeanName = getCurrentProxiedBeanName();
|
||||
if (advisedBeanName == null) { // no proxy creation in progress
|
||||
// abstain; can't return YES, since that will make pointcut with negation fail
|
||||
@@ -619,11 +601,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
this.shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
|
||||
}
|
||||
|
||||
|
||||
private static class DefensiveShadowMatch implements ShadowMatch {
|
||||
|
||||
private final ShadowMatch primary;
|
||||
|
||||
private final ShadowMatch other;
|
||||
|
||||
public DefensiveShadowMatch(ShadowMatch primary, ShadowMatch other) {
|
||||
@@ -631,36 +611,32 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysMatches() {
|
||||
return this.primary.alwaysMatches();
|
||||
return primary.alwaysMatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maybeMatches() {
|
||||
return this.primary.maybeMatches();
|
||||
return primary.maybeMatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean neverMatches() {
|
||||
return this.primary.neverMatches();
|
||||
return primary.neverMatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) {
|
||||
public JoinPointMatch matchesJoinPoint(Object thisObject,
|
||||
Object targetObject, Object[] args) {
|
||||
try {
|
||||
return this.primary.matchesJoinPoint(thisObject, targetObject, args);
|
||||
}
|
||||
catch (ReflectionWorldException ex) {
|
||||
return this.other.matchesJoinPoint(thisObject, targetObject, args);
|
||||
return primary.matchesJoinPoint(thisObject, targetObject, args);
|
||||
} catch (ReflectionWorldException e) {
|
||||
return other.matchesJoinPoint(thisObject, targetObject, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatchingContext(MatchingContext aMatchContext) {
|
||||
this.primary.setMatchingContext(aMatchContext);
|
||||
this.other.setMatchingContext(aMatchContext);
|
||||
primary.setMatchingContext(aMatchContext);
|
||||
other.setMatchingContext(aMatchContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,6 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
|
||||
private final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
|
||||
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
@@ -40,24 +39,24 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
|
||||
this.pointcut.setExpression(expression);
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return this.pointcut.getExpression();
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.pointcut.setLocation(location);
|
||||
}
|
||||
|
||||
public void setParameterTypes(Class[] types) {
|
||||
this.pointcut.setParameterTypes(types);
|
||||
}
|
||||
|
||||
public void setParameterNames(String[] names) {
|
||||
this.pointcut.setParameterNames(names);
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return this.pointcut.getLocation();
|
||||
}
|
||||
|
||||
public void setParameterTypes(Class<?>[] types) {
|
||||
this.pointcut.setParameterTypes(types);
|
||||
}
|
||||
|
||||
public void setParameterNames(String... names) {
|
||||
this.pointcut.setParameterNames(names);
|
||||
public String getExpression() {
|
||||
return this.pointcut.getExpression();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,17 +35,14 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
+1
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,22 +56,18 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPerInstance() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
return this.advice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
if (this.order != null) {
|
||||
return this.order;
|
||||
|
||||
-4
@@ -48,7 +48,6 @@ public class AspectJWeaverMessageHandler implements IMessageHandler {
|
||||
private static final Log logger = LogFactory.getLog("AspectJ Weaver");
|
||||
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(IMessage message) throws AbortException {
|
||||
Kind messageKind = message.getKind();
|
||||
if (messageKind == IMessage.DEBUG) {
|
||||
@@ -88,18 +87,15 @@ public class AspectJWeaverMessageHandler implements IMessageHandler {
|
||||
return AJ_ID + aMessage.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIgnoring(Kind messageKind) {
|
||||
// We want to see everything, and allow configuration of log levels dynamically.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dontIgnore(Kind messageKind) {
|
||||
// We weren't ignoring anything anyway...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignore(Kind kind) {
|
||||
// We weren't ignoring anything anyway...
|
||||
}
|
||||
|
||||
+7
-13
@@ -34,7 +34,7 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||
*/
|
||||
public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
|
||||
private final Class<?> introducedInterface;
|
||||
private final Class introducedInterface;
|
||||
|
||||
private final ClassFilter typePatternClassFilter;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* @param typePattern type pattern the introduction is restricted to
|
||||
* @param defaultImpl the default implementation class
|
||||
*/
|
||||
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
|
||||
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Class defaultImpl) {
|
||||
this(interfaceType, typePattern, defaultImpl,
|
||||
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* @param typePattern type pattern the introduction is restricted to
|
||||
* @param delegateRef the delegate implementation object
|
||||
*/
|
||||
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
|
||||
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Object delegateRef) {
|
||||
this(interfaceType, typePattern, delegateRef.getClass(),
|
||||
new DelegatingIntroductionInterceptor(delegateRef));
|
||||
}
|
||||
@@ -71,14 +71,13 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* @param implementationClass implementation class
|
||||
* @param advice delegation advice
|
||||
*/
|
||||
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
|
||||
private DeclareParentsAdvisor(Class interfaceType, String typePattern, Class implementationClass, Advice advice) {
|
||||
this.introducedInterface = interfaceType;
|
||||
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
|
||||
|
||||
// Excludes methods implemented.
|
||||
ClassFilter exclusion = new ClassFilter() {
|
||||
@Override
|
||||
public boolean matches(Class<?> clazz) {
|
||||
public boolean matches(Class clazz) {
|
||||
return !(introducedInterface.isAssignableFrom(clazz));
|
||||
}
|
||||
};
|
||||
@@ -88,29 +87,24 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClassFilter getClassFilter() {
|
||||
return this.typePatternClassFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateInterfaces() throws IllegalArgumentException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPerInstance() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
return this.advice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getInterfaces() {
|
||||
return new Class<?>[] {this.introducedInterface};
|
||||
public Class[] getInterfaces() {
|
||||
return new Class[] {this.introducedInterface};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-42
@@ -27,8 +27,7 @@ import org.aspectj.lang.reflect.SourceLocation;
|
||||
import org.aspectj.runtime.internal.AroundClosure;
|
||||
|
||||
import org.springframework.aop.ProxyMethodInvocation;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -52,8 +51,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {
|
||||
|
||||
private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
private final ProxyMethodInvocation methodInvocation;
|
||||
|
||||
private Object[] defensiveCopyOfArgs;
|
||||
@@ -75,17 +72,14 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
this.methodInvocation = methodInvocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set$AroundClosure(AroundClosure aroundClosure) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object proceed() throws Throwable {
|
||||
return this.methodInvocation.invocableClone().proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object proceed(Object[] arguments) throws Throwable {
|
||||
Assert.notNull(arguments, "Argument array passed to proceed cannot be null");
|
||||
if (arguments.length != this.methodInvocation.getArguments().length) {
|
||||
@@ -100,7 +94,6 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
/**
|
||||
* Returns the Spring AOP proxy. Cannot be {@code null}.
|
||||
*/
|
||||
@Override
|
||||
public Object getThis() {
|
||||
return this.methodInvocation.getProxy();
|
||||
}
|
||||
@@ -108,12 +101,10 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
/**
|
||||
* Returns the Spring AOP target. May be {@code null} if there is no target.
|
||||
*/
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
return this.methodInvocation.getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getArgs() {
|
||||
if (this.defensiveCopyOfArgs == null) {
|
||||
Object[] argsSource = this.methodInvocation.getArguments();
|
||||
@@ -123,7 +114,6 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
return this.defensiveCopyOfArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature getSignature() {
|
||||
if (this.signature == null) {
|
||||
this.signature = new MethodSignatureImpl();
|
||||
@@ -131,7 +121,6 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getSourceLocation() {
|
||||
if (this.sourceLocation == null) {
|
||||
this.sourceLocation = new SourceLocationImpl();
|
||||
@@ -139,33 +128,27 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
return this.sourceLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKind() {
|
||||
return ProceedingJoinPoint.METHOD_EXECUTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
// TODO: It's just an adapter but returning 0 might still have side effects...
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinPoint.StaticPart getStaticPart() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return "execution(" + getSignature().toShortString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toLongString() {
|
||||
return "execution(" + getSignature().toLongString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "execution(" + getSignature().toString() + ")";
|
||||
}
|
||||
@@ -178,65 +161,53 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
|
||||
private volatile String[] parameterNames;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return methodInvocation.getMethod().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return methodInvocation.getMethod().getModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getDeclaringType() {
|
||||
public Class getDeclaringType() {
|
||||
return methodInvocation.getMethod().getDeclaringClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeclaringTypeName() {
|
||||
return methodInvocation.getMethod().getDeclaringClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getReturnType() {
|
||||
public Class getReturnType() {
|
||||
return methodInvocation.getMethod().getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getMethod() {
|
||||
return methodInvocation.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getParameterTypes() {
|
||||
public Class[] getParameterTypes() {
|
||||
return methodInvocation.getMethod().getParameterTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterNames() {
|
||||
if (this.parameterNames == null) {
|
||||
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
this.parameterNames = (new LocalVariableTableParameterNameDiscoverer()).getParameterNames(getMethod());
|
||||
}
|
||||
return this.parameterNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getExceptionTypes() {
|
||||
public Class[] getExceptionTypes() {
|
||||
return methodInvocation.getMethod().getExceptionTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return toString(false, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toLongString() {
|
||||
return toString(true, true, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(false, true, false, true);
|
||||
}
|
||||
@@ -256,7 +227,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
sb.append(".");
|
||||
sb.append(getMethod().getName());
|
||||
sb.append("(");
|
||||
Class<?>[] parametersTypes = getParameterTypes();
|
||||
Class[] parametersTypes = getParameterTypes();
|
||||
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
@@ -296,26 +267,21 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
*/
|
||||
private class SourceLocationImpl implements SourceLocation {
|
||||
|
||||
@Override
|
||||
public Class<?> getWithinType() {
|
||||
public Class getWithinType() {
|
||||
if (methodInvocation.getThis() == null) {
|
||||
throw new UnsupportedOperationException("No source location joinpoint available: target is null");
|
||||
}
|
||||
return methodInvocation.getThis().getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int getColumn() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,8 +18,6 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.aspectj.weaver.ReferenceType;
|
||||
import org.aspectj.weaver.ReferenceTypeDelegate;
|
||||
import org.aspectj.weaver.ResolvedType;
|
||||
import org.aspectj.weaver.ast.And;
|
||||
import org.aspectj.weaver.ast.Call;
|
||||
@@ -32,7 +30,6 @@ import org.aspectj.weaver.ast.Not;
|
||||
import org.aspectj.weaver.ast.Or;
|
||||
import org.aspectj.weaver.ast.Test;
|
||||
import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
|
||||
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
|
||||
import org.aspectj.weaver.reflect.ReflectionVar;
|
||||
import org.aspectj.weaver.reflect.ShadowMatchImpl;
|
||||
import org.aspectj.weaver.tools.ShadowMatch;
|
||||
@@ -58,36 +55,25 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
class RuntimeTestWalker {
|
||||
|
||||
private static final Field residualTestField;
|
||||
|
||||
private static final Field varTypeField;
|
||||
|
||||
private static final Field myClassField;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
residualTestField = ShadowMatchImpl.class.getDeclaredField("residualTest");
|
||||
varTypeField = ReflectionVar.class.getDeclaredField("varType");
|
||||
myClassField = ReflectionBasedReferenceTypeDelegate.class.getDeclaredField("myClass");
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
throw new IllegalStateException("The version of aspectjtools.jar / aspectjweaver.jar " +
|
||||
"on the classpath is incompatible with this version of Spring: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Test runtimeTest;
|
||||
|
||||
|
||||
public RuntimeTestWalker(ShadowMatch shadowMatch) {
|
||||
ShadowMatchImpl shadowMatchImplementation = (ShadowMatchImpl) shadowMatch;
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(residualTestField);
|
||||
this.runtimeTest = (Test) residualTestField.get(shadowMatch);
|
||||
Field testField = shadowMatchImplementation.getClass().getDeclaredField("residualTest");
|
||||
ReflectionUtils.makeAccessible(testField);
|
||||
this.runtimeTest = (Test) testField.get(shadowMatch);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
catch (NoSuchFieldException noSuchFieldEx) {
|
||||
throw new IllegalStateException("The version of aspectjtools.jar / aspectjweaver.jar " +
|
||||
"on the classpath is incompatible with this version of Spring: Expected field " +
|
||||
"'runtimeTest' is not present on ShadowMatchImpl class.");
|
||||
}
|
||||
catch (IllegalAccessException illegalAccessEx) {
|
||||
// Famous last words... but I don't see how this can happen given the
|
||||
// makeAccessible call above
|
||||
throw new IllegalStateException("Unable to access ShadowMatchImpl.residualTest field");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,12 +87,12 @@ class RuntimeTestWalker {
|
||||
new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest));
|
||||
}
|
||||
|
||||
public boolean testThisInstanceOfResidue(Class<?> thisClass) {
|
||||
public boolean testThisInstanceOfResidue(Class thisClass) {
|
||||
return (this.runtimeTest != null &&
|
||||
new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest));
|
||||
}
|
||||
|
||||
public boolean testTargetInstanceOfResidue(Class<?> targetClass) {
|
||||
public boolean testTargetInstanceOfResidue(Class targetClass) {
|
||||
return (this.runtimeTest != null &&
|
||||
new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest));
|
||||
}
|
||||
@@ -120,54 +106,53 @@ class RuntimeTestWalker {
|
||||
protected static final int AT_TARGET_VAR = 4;
|
||||
protected static final int AT_ANNOTATION_VAR = 8;
|
||||
|
||||
@Override
|
||||
public void visit(And e) {
|
||||
e.getLeft().accept(this);
|
||||
e.getRight().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Or e) {
|
||||
e.getLeft().accept(this);
|
||||
e.getRight().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Not e) {
|
||||
e.getBody().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Instanceof i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Literal literal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Call call) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FieldGetCall fieldGetCall) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(HasAnnotation hasAnnotation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MatchingContextBasedTest matchingContextTest) {
|
||||
}
|
||||
|
||||
protected int getVarType(ReflectionVar v) {
|
||||
try {
|
||||
Field varTypeField = ReflectionVar.class.getDeclaredField("varType");
|
||||
ReflectionUtils.makeAccessible(varTypeField);
|
||||
return (Integer) varTypeField.get(v);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
catch (NoSuchFieldException noSuchFieldEx) {
|
||||
throw new IllegalStateException("the version of aspectjtools.jar / aspectjweaver.jar " +
|
||||
"on the classpath is incompatible with this version of Spring:- expected field " +
|
||||
"'varType' is not present on ReflectionVar class");
|
||||
}
|
||||
catch (IllegalAccessException illegalAccessEx) {
|
||||
// Famous last words... but I don't see how this can happen given the
|
||||
// makeAccessible call above
|
||||
throw new IllegalStateException("Unable to access ReflectionVar.varType field");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,13 +160,11 @@ class RuntimeTestWalker {
|
||||
|
||||
private static abstract class InstanceOfResidueTestVisitor extends TestVisitorAdapter {
|
||||
|
||||
private final Class<?> matchClass;
|
||||
|
||||
private Class matchClass;
|
||||
private boolean matches;
|
||||
private int matchVarType;
|
||||
|
||||
private final int matchVarType;
|
||||
|
||||
public InstanceOfResidueTestVisitor(Class<?> matchClass, boolean defaultMatches, int matchVarType) {
|
||||
public InstanceOfResidueTestVisitor(Class matchClass, boolean defaultMatches, int matchVarType) {
|
||||
this.matchClass = matchClass;
|
||||
this.matches = defaultMatches;
|
||||
this.matchVarType = matchVarType;
|
||||
@@ -189,34 +172,19 @@ class RuntimeTestWalker {
|
||||
|
||||
public boolean instanceOfMatches(Test test) {
|
||||
test.accept(this);
|
||||
return this.matches;
|
||||
return matches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Instanceof i) {
|
||||
ResolvedType type = (ResolvedType) i.getType();
|
||||
int varType = getVarType((ReflectionVar) i.getVar());
|
||||
if (varType != this.matchVarType) {
|
||||
return;
|
||||
}
|
||||
Class<?> typeClass = null;
|
||||
ResolvedType type = (ResolvedType) i.getType();
|
||||
if (type instanceof ReferenceType) {
|
||||
ReferenceTypeDelegate delegate = ((ReferenceType) type).getDelegate();
|
||||
if (delegate instanceof ReflectionBasedReferenceTypeDelegate) {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(myClassField);
|
||||
typeClass = (Class<?>) myClassField.get(delegate);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Don't use ResolvedType.isAssignableFrom() as it won't be aware of (Spring) mixins
|
||||
if (typeClass == null) {
|
||||
typeClass = ClassUtils.forName(type.getName(), this.matchClass.getClassLoader());
|
||||
}
|
||||
Class typeClass = ClassUtils.forName(type.getName(), this.matchClass.getClassLoader());
|
||||
// Don't use ReflectionType.isAssignableFrom() as it won't be aware of (Spring) mixins
|
||||
this.matches = typeClass.isAssignableFrom(this.matchClass);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
@@ -231,7 +199,7 @@ class RuntimeTestWalker {
|
||||
*/
|
||||
private static class TargetInstanceOfResidueTestVisitor extends InstanceOfResidueTestVisitor {
|
||||
|
||||
public TargetInstanceOfResidueTestVisitor(Class<?> targetClass) {
|
||||
public TargetInstanceOfResidueTestVisitor(Class targetClass) {
|
||||
super(targetClass, false, TARGET_VAR);
|
||||
}
|
||||
|
||||
@@ -246,7 +214,7 @@ class RuntimeTestWalker {
|
||||
*/
|
||||
private static class ThisInstanceOfResidueTestVisitor extends InstanceOfResidueTestVisitor {
|
||||
|
||||
public ThisInstanceOfResidueTestVisitor(Class<?> thisClass) {
|
||||
public ThisInstanceOfResidueTestVisitor(Class thisClass) {
|
||||
super(thisClass, true, THIS_VAR);
|
||||
}
|
||||
|
||||
@@ -260,11 +228,8 @@ class RuntimeTestWalker {
|
||||
private static class SubtypeSensitiveVarTypeTestVisitor extends TestVisitorAdapter {
|
||||
|
||||
private final Object thisObj = new Object();
|
||||
|
||||
private final Object targetObj = new Object();
|
||||
|
||||
private final Object[] argsObjs = new Object[0];
|
||||
|
||||
private boolean testsSubtypeSensitiveVars = false;
|
||||
|
||||
public boolean testsSubtypeSensitiveVars(Test aTest) {
|
||||
@@ -275,8 +240,8 @@ class RuntimeTestWalker {
|
||||
@Override
|
||||
public void visit(Instanceof i) {
|
||||
ReflectionVar v = (ReflectionVar) i.getVar();
|
||||
Object varUnderTest = v.getBindingAtJoinPoint(this.thisObj, this.targetObj, this.argsObjs);
|
||||
if (varUnderTest == this.thisObj || varUnderTest == this.targetObj) {
|
||||
Object varUnderTest = v.getBindingAtJoinPoint(thisObj,targetObj,argsObjs);
|
||||
if ((varUnderTest == thisObj) || (varUnderTest == targetObj)) {
|
||||
this.testsSubtypeSensitiveVars = true;
|
||||
}
|
||||
}
|
||||
@@ -286,7 +251,7 @@ class RuntimeTestWalker {
|
||||
// If you thought things were bad before, now we sink to new levels of horror...
|
||||
ReflectionVar v = (ReflectionVar) hasAnn.getVar();
|
||||
int varType = getVarType(v);
|
||||
if (varType == AT_THIS_VAR || varType == AT_TARGET_VAR || varType == AT_ANNOTATION_VAR) {
|
||||
if ((varType == AT_THIS_VAR) || (varType == AT_TARGET_VAR) || (varType == AT_ANNOTATION_VAR)) {
|
||||
this.testsSubtypeSensitiveVars = true;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -29,14 +29,14 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
|
||||
private final Class<?> aspectClass;
|
||||
private final Class aspectClass;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SimpleAspectInstanceFactory for the given aspect class.
|
||||
* @param aspectClass the aspect class
|
||||
*/
|
||||
public SimpleAspectInstanceFactory(Class<?> aspectClass) {
|
||||
public SimpleAspectInstanceFactory(Class aspectClass) {
|
||||
Assert.notNull(aspectClass, "Aspect class must not be null");
|
||||
this.aspectClass = aspectClass;
|
||||
}
|
||||
@@ -44,12 +44,11 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
/**
|
||||
* Return the specified aspect class (never {@code null}).
|
||||
*/
|
||||
public final Class<?> getAspectClass() {
|
||||
public final Class getAspectClass() {
|
||||
return this.aspectClass;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Object getAspectInstance() {
|
||||
try {
|
||||
return this.aspectClass.newInstance();
|
||||
@@ -62,7 +61,6 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
return this.aspectClass.getClassLoader();
|
||||
}
|
||||
@@ -75,7 +73,6 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
* @see org.springframework.core.Ordered
|
||||
* @see #getOrderForAspectClass
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return getOrderForAspectClass(this.aspectClass);
|
||||
}
|
||||
|
||||
-3
@@ -44,12 +44,10 @@ public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Object getAspectInstance() {
|
||||
return this.aspectInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
return this.aspectInstance.getClass().getClassLoader();
|
||||
}
|
||||
@@ -62,7 +60,6 @@ public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
|
||||
* @see org.springframework.core.Ordered
|
||||
* @see #getOrderForAspectClass
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
if (this.aspectInstance instanceof Ordered) {
|
||||
return ((Ordered) this.aspectInstance).getOrder();
|
||||
|
||||
+1
-2
@@ -93,8 +93,7 @@ public class TypePatternClassFilter implements ClassFilter {
|
||||
* @return whether the advice should apply to this candidate target class
|
||||
* @throws IllegalStateException if no {@link #setTypePattern(String)} has been set
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(Class<?> clazz) {
|
||||
public boolean matches(Class clazz) {
|
||||
if (this.aspectJTypePatternMatcher == null) {
|
||||
throw new IllegalStateException("No 'typePattern' has been set via ctor/setter.");
|
||||
}
|
||||
|
||||
+23
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,9 +37,11 @@ import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.AjType;
|
||||
import org.aspectj.lang.reflect.AjTypeSystem;
|
||||
import org.aspectj.lang.reflect.PerClauseKind;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.framework.AopConfigException;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.PrioritizedParameterNameDiscoverer;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -57,6 +59,9 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory {
|
||||
|
||||
protected static final ParameterNameDiscoverer ASPECTJ_ANNOTATION_PARAMETER_NAME_DISCOVERER =
|
||||
new AspectJAnnotationParameterNameDiscoverer();
|
||||
|
||||
private static final String AJC_MAGIC = "ajc$";
|
||||
|
||||
|
||||
@@ -65,11 +70,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
* (there <i>should</i> only be one anyway...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||||
Class<?>[] classesToLookFor = new Class<?>[] {
|
||||
protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {
|
||||
Class<? extends Annotation>[] classesToLookFor = new Class[] {
|
||||
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
|
||||
for (Class<?> c : classesToLookFor) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
|
||||
for (Class<? extends Annotation> c : classesToLookFor) {
|
||||
AspectJAnnotation foundAnnotation = findAnnotation(method, c);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
@@ -91,16 +96,21 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
protected final ParameterNameDiscoverer parameterNameDiscoverer = new AspectJAnnotationParameterNameDiscoverer();
|
||||
protected final ParameterNameDiscoverer parameterNameDiscoverer;
|
||||
|
||||
|
||||
protected AbstractAspectJAdvisorFactory() {
|
||||
PrioritizedParameterNameDiscoverer prioritizedParameterNameDiscoverer = new PrioritizedParameterNameDiscoverer();
|
||||
prioritizedParameterNameDiscoverer.addDiscoverer(ASPECTJ_ANNOTATION_PARAMETER_NAME_DISCOVERER);
|
||||
this.parameterNameDiscoverer = prioritizedParameterNameDiscoverer;
|
||||
}
|
||||
|
||||
/**
|
||||
* We consider something to be an AspectJ aspect suitable for use by the Spring AOP system
|
||||
* if it has the @Aspect annotation, and was not compiled by ajc. The reason for this latter test
|
||||
* is that aspects written in the code-style (AspectJ language) also have the annotation present
|
||||
* when compiled by ajc with the -1.5 flag, yet they cannot be consumed by Spring AOP.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAspect(Class<?> clazz) {
|
||||
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
|
||||
}
|
||||
@@ -125,7 +135,6 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Class<?> aspectClass) throws AopConfigException {
|
||||
// If the parent has the annotation and isn't abstract it's an error
|
||||
if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
|
||||
@@ -154,7 +163,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
* formal parameters for the pointcut.
|
||||
*/
|
||||
protected AspectJExpressionPointcut createPointcutExpression(
|
||||
Method annotatedMethod, Class<?> declarationScope, String[] pointcutParameterNames) {
|
||||
Method annotatedMethod, Class declarationScope, String[] pointcutParameterNames) {
|
||||
|
||||
Class<?> [] pointcutParameterTypes = new Class<?>[0];
|
||||
if (pointcutParameterNames != null) {
|
||||
@@ -208,8 +217,8 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
|
||||
private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};
|
||||
|
||||
private static Map<Class<?>, AspectJAnnotationType> annotationTypes =
|
||||
new HashMap<Class<?>, AspectJAnnotationType>();
|
||||
private static Map<Class, AspectJAnnotationType> annotationTypes =
|
||||
new HashMap<Class, AspectJAnnotationType>();
|
||||
|
||||
static {
|
||||
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
|
||||
@@ -243,7 +252,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
|
||||
private AspectJAnnotationType determineAnnotationType(A annotation) {
|
||||
for (Class<?> type : annotationTypes.keySet()) {
|
||||
for (Class type : annotationTypes.keySet()) {
|
||||
if (type.isInstance(annotation)) {
|
||||
return annotationTypes.get(type);
|
||||
}
|
||||
@@ -300,12 +309,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
*/
|
||||
private static class AspectJAnnotationParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
|
||||
@Override
|
||||
public String[] getParameterNames(Method method) {
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
return new String[0];
|
||||
}
|
||||
AspectJAnnotation<?> annotation = findAspectJAnnotationOnMethod(method);
|
||||
AspectJAnnotation annotation = findAspectJAnnotationOnMethod(method);
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -322,8 +330,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterNames(Constructor<?> ctor) {
|
||||
public String[] getParameterNames(Constructor ctor) {
|
||||
throw new UnsupportedOperationException("Spring AOP cannot handle constructor advice");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -67,7 +67,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
|
||||
}
|
||||
|
||||
public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
|
||||
Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
|
||||
Assert.notNull(this.aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
|
||||
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInfrastructureClass(Class<?> beanClass) {
|
||||
protected boolean isInfrastructureClass(Class beanClass) {
|
||||
// Previously we setProxyTargetClass(true) in the constructor, but that has too
|
||||
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
|
||||
// aspects. I'm not entirely happy with that as there is no good reason not
|
||||
|
||||
+7
-7
@@ -50,7 +50,7 @@ import org.springframework.util.ClassUtils;
|
||||
public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
|
||||
/** Cache for singleton aspect instances */
|
||||
private static final Map<Class<?>, Object> aspectCache = new HashMap<Class<?>, Object>();
|
||||
private static final Map<Class, Object> aspectCache = new HashMap<Class, Object>();
|
||||
|
||||
private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
@@ -76,7 +76,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
* Create a new {@code AspectJProxyFactory}.
|
||||
* No target, only interfaces. Must add interceptors.
|
||||
*/
|
||||
public AspectJProxyFactory(Class<?>[] interfaces) {
|
||||
public AspectJProxyFactory(Class[] interfaces) {
|
||||
setInterfaces(interfaces);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
* @param aspectInstance the AspectJ aspect instance
|
||||
*/
|
||||
public void addAspect(Object aspectInstance) {
|
||||
Class<?> aspectClass = aspectInstance.getClass();
|
||||
Class aspectClass = aspectInstance.getClass();
|
||||
String aspectName = aspectClass.getName();
|
||||
AspectMetadata am = createAspectMetadata(aspectClass, aspectName);
|
||||
if (am.getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON) {
|
||||
@@ -104,7 +104,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
* Add an aspect of the supplied type to the end of the advice chain.
|
||||
* @param aspectClass the AspectJ aspect class
|
||||
*/
|
||||
public void addAspect(Class<?> aspectClass) {
|
||||
public void addAspect(Class aspectClass) {
|
||||
String aspectName = aspectClass.getName();
|
||||
AspectMetadata am = createAspectMetadata(aspectClass, aspectName);
|
||||
MetadataAwareAspectInstanceFactory instanceFactory = createAspectInstanceFactory(am, aspectClass, aspectName);
|
||||
@@ -128,7 +128,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
/**
|
||||
* Create an {@link AspectMetadata} instance for the supplied aspect type.
|
||||
*/
|
||||
private AspectMetadata createAspectMetadata(Class<?> aspectClass, String aspectName) {
|
||||
private AspectMetadata createAspectMetadata(Class aspectClass, String aspectName) {
|
||||
AspectMetadata am = new AspectMetadata(aspectClass, aspectName);
|
||||
if (!am.getAjType().isAspect()) {
|
||||
throw new IllegalArgumentException("Class [" + aspectClass.getName() + "] is not a valid aspect type");
|
||||
@@ -142,7 +142,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
* a {@link PrototypeAspectInstanceFactory} is returned.
|
||||
*/
|
||||
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
|
||||
AspectMetadata am, Class<?> aspectClass, String aspectName) {
|
||||
AspectMetadata am, Class aspectClass, String aspectName) {
|
||||
|
||||
MetadataAwareAspectInstanceFactory instanceFactory = null;
|
||||
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
|
||||
@@ -161,7 +161,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
* Get the singleton aspect instance for the supplied aspect type. An instance
|
||||
* is created if one cannot be found in the instance cache.
|
||||
*/
|
||||
private Object getSingletonAspectInstance(Class<?> aspectClass) {
|
||||
private Object getSingletonAspectInstance(Class aspectClass) {
|
||||
synchronized (aspectCache) {
|
||||
Object instance = aspectCache.get(aspectClass);
|
||||
if (instance != null) {
|
||||
|
||||
+5
-5
@@ -45,7 +45,7 @@ public class AspectMetadata {
|
||||
/**
|
||||
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
|
||||
*/
|
||||
private final AjType<?> ajType;
|
||||
private final AjType ajType;
|
||||
|
||||
/**
|
||||
* Spring AOP pointcut corresponding to the per clause of the
|
||||
@@ -71,9 +71,9 @@ public class AspectMetadata {
|
||||
this.aspectName = aspectName;
|
||||
|
||||
Class<?> currClass = aspectClass;
|
||||
AjType<?> ajType = null;
|
||||
AjType ajType = null;
|
||||
while (!currClass.equals(Object.class)) {
|
||||
AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);
|
||||
AjType ajTypeToCheck = AjTypeSystem.getAjType(currClass);
|
||||
if (ajTypeToCheck.isAspect()) {
|
||||
ajType = ajTypeToCheck;
|
||||
break;
|
||||
@@ -124,14 +124,14 @@ public class AspectMetadata {
|
||||
/**
|
||||
* Return AspectJ reflection information.
|
||||
*/
|
||||
public AjType<?> getAjType() {
|
||||
public AjType getAjType() {
|
||||
return this.ajType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the aspect class.
|
||||
*/
|
||||
public Class<?> getAspectClass() {
|
||||
public Class getAspectClass() {
|
||||
return this.ajType.getJavaClass();
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -66,19 +66,17 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
* @param name the name of the bean
|
||||
* @param type the type that should be introspected by AspectJ
|
||||
*/
|
||||
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
|
||||
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.name = name;
|
||||
this.aspectMetadata = new AspectMetadata(type, name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getAspectInstance() {
|
||||
return this.beanFactory.getBean(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
|
||||
@@ -88,7 +86,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AspectMetadata getAspectMetadata() {
|
||||
return this.aspectMetadata;
|
||||
}
|
||||
@@ -103,7 +100,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
* @see org.springframework.core.Ordered
|
||||
* @see org.springframework.core.annotation.Order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
Class<?> type = this.beanFactory.getType(this.name);
|
||||
if (type != null) {
|
||||
|
||||
+2
-2
@@ -96,7 +96,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
|
||||
// We must be careful not to instantiate beans eagerly as in this
|
||||
// case they would be cached by the Spring container but would not
|
||||
// have been weaved
|
||||
Class<?> beanType = this.beanFactory.getType(beanName);
|
||||
Class beanType = this.beanFactory.getType(beanName);
|
||||
if (beanType == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
|
||||
}
|
||||
|
||||
if (aspectNames.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
for (String aspectName : aspectNames) {
|
||||
|
||||
+2
-13
@@ -97,7 +97,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change
|
||||
* depending on the state of the advice.
|
||||
*/
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
@@ -107,7 +106,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
* are much richer. In AspectJ terminology, all a return of {@code true}
|
||||
* means here is that the aspect is not a SINGLETON.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPerInstance() {
|
||||
return (getAspectMetadata().getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON);
|
||||
}
|
||||
@@ -122,7 +120,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
/**
|
||||
* Lazily instantiate advice if necessary.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Advice getAdvice() {
|
||||
if (this.instantiatedAdvice == null) {
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
@@ -130,12 +127,10 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
return this.instantiatedAdvice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazy() {
|
||||
return this.lazy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAdviceInstantiated() {
|
||||
return (this.instantiatedAdvice != null);
|
||||
}
|
||||
@@ -154,22 +149,18 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
return this.declaredPointcut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.aspectInstanceFactory.getOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAspectName() {
|
||||
return this.aspectName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeclarationOrder() {
|
||||
return this.declarationOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
if (this.isBeforeAdvice == null) {
|
||||
determineAdviceType();
|
||||
@@ -177,7 +168,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
return this.isBeforeAdvice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterAdvice() {
|
||||
if (this.isAfterAdvice == null) {
|
||||
determineAdviceType();
|
||||
@@ -249,14 +239,13 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
public boolean matches(Method method, Class targetClass) {
|
||||
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut
|
||||
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) ||
|
||||
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class targetClass, Object[] args) {
|
||||
// This can match only on declared pointcut.
|
||||
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
|
||||
}
|
||||
|
||||
+1
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,7 +42,6 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized Object getAspectInstance() {
|
||||
if (this.materialized == null) {
|
||||
synchronized (this) {
|
||||
@@ -58,17 +57,14 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
return (this.materialized != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
return this.maaif.getAspectClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AspectMetadata getAspectMetadata() {
|
||||
return this.maaif.getAspectMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.maaif.getOrder();
|
||||
}
|
||||
|
||||
+1
-8
@@ -75,7 +75,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new InstanceComparator<Annotation>(
|
||||
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
|
||||
new Converter<Method, Annotation>() {
|
||||
@Override
|
||||
public Annotation convert(Method method) {
|
||||
AspectJAnnotation<?> annotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return annotation == null ? null : annotation.getAnnotation();
|
||||
@@ -83,7 +82,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}));
|
||||
comparator.addComparator(new ConvertingComparator<Method, String>(
|
||||
new Converter<Method, String>() {
|
||||
@Override
|
||||
public String convert(Method method) {
|
||||
return method.getName();
|
||||
}
|
||||
@@ -92,7 +90,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
|
||||
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
|
||||
final String aspectName = maaif.getAspectMetadata().getAspectName();
|
||||
@@ -131,7 +128,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
|
||||
final List<Method> methods = new LinkedList<Method>();
|
||||
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
// Exclude pointcuts
|
||||
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
|
||||
@@ -168,7 +164,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
|
||||
int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
@@ -190,13 +185,12 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return null;
|
||||
}
|
||||
AspectJExpressionPointcut ajexp =
|
||||
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
|
||||
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
|
||||
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
@@ -278,7 +272,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
|
||||
super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() {
|
||||
@Override
|
||||
public void before(Method method, Object[] args, Object target) {
|
||||
// Simply instantiate the aspect
|
||||
aif.getAspectInstance();
|
||||
|
||||
+1
-2
@@ -40,13 +40,12 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
|
||||
* @param aspectClass the aspect class
|
||||
* @param aspectName the aspect name
|
||||
*/
|
||||
public SimpleMetadataAwareAspectInstanceFactory(Class<?> aspectClass, String aspectName) {
|
||||
public SimpleMetadataAwareAspectInstanceFactory(Class aspectClass, String aspectName) {
|
||||
super(aspectClass);
|
||||
this.metadata = new AspectMetadata(aspectClass, aspectName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final AspectMetadata getAspectMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
-1
@@ -48,7 +48,6 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final AspectMetadata getAspectMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
+2
-4
@@ -46,7 +46,7 @@ import org.springframework.util.ClassUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
|
||||
|
||||
private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();
|
||||
private static final Comparator DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();
|
||||
|
||||
|
||||
/**
|
||||
@@ -98,7 +98,7 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
|
||||
protected boolean shouldSkip(Class beanClass, String beanName) {
|
||||
// TODO: Consider optimization by caching the list of the aspect names
|
||||
List<Advisor> candidateAdvisors = findCandidateAdvisors();
|
||||
for (Advisor advisor : candidateAdvisors) {
|
||||
@@ -126,13 +126,11 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object obj) {
|
||||
Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
|
||||
return this.comparator.compare(this.advisor, otherAdvisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fallbackCompareTo(Object obj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+13
-6
@@ -48,7 +48,7 @@ import org.springframework.util.Assert;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
class AspectJPrecedenceComparator implements Comparator<Advisor> {
|
||||
class AspectJPrecedenceComparator implements Comparator {
|
||||
|
||||
private static final int HIGHER_PRECEDENCE = -1;
|
||||
private static final int SAME_PRECEDENCE = 0;
|
||||
@@ -75,11 +75,18 @@ class AspectJPrecedenceComparator implements Comparator<Advisor> {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compare(Advisor o1, Advisor o2) {
|
||||
int advisorPrecedence = this.advisorComparator.compare(o1, o2);
|
||||
if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {
|
||||
advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
|
||||
public int compare(Object o1, Object o2) {
|
||||
if (!(o1 instanceof Advisor && o2 instanceof Advisor)) {
|
||||
throw new IllegalArgumentException(
|
||||
"AspectJPrecedenceComparator can only compare the order of Advisors, " +
|
||||
"but was passed [" + o1 + "] and [" + o2 + "]");
|
||||
}
|
||||
|
||||
Advisor advisor1 = (Advisor) o1;
|
||||
Advisor advisor2 = (Advisor) o2;
|
||||
int advisorPrecedence = this.advisorComparator.compare(advisor1, advisor2);
|
||||
if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(advisor1, advisor2)) {
|
||||
advisorPrecedence = comparePrecedenceWithinAspect(advisor1, advisor2);
|
||||
}
|
||||
return advisorPrecedence;
|
||||
}
|
||||
|
||||
-1
@@ -58,7 +58,6 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implements BeanDefinitionDecorator {
|
||||
|
||||
@Override
|
||||
public final BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definitionHolder, ParserContext parserContext) {
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
|
||||
-2
@@ -91,7 +91,6 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.advisorBeanName;
|
||||
}
|
||||
@@ -111,7 +110,6 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition {
|
||||
return this.beanReferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return this.advisorDefinition.getSource();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public abstract class AopConfigUtils {
|
||||
/**
|
||||
* Stores the auto proxy creator classes in escalation order.
|
||||
*/
|
||||
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();
|
||||
private static final List<Class> APC_PRIORITY_LIST = new ArrayList<Class>();
|
||||
|
||||
/**
|
||||
* Setup the escalation list.
|
||||
@@ -105,7 +105,7 @@ public abstract class AopConfigUtils {
|
||||
}
|
||||
|
||||
|
||||
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
|
||||
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
@@ -126,13 +126,13 @@ public abstract class AopConfigUtils {
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
private static int findPriorityForClass(Class<?> clazz) {
|
||||
private static int findPriorityForClass(Class clazz) {
|
||||
return APC_PRIORITY_LIST.indexOf(clazz);
|
||||
}
|
||||
|
||||
private static int findPriorityForClass(String className) {
|
||||
for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
|
||||
Class<?> clazz = APC_PRIORITY_LIST.get(i);
|
||||
Class clazz = APC_PRIORITY_LIST.get(i);
|
||||
if (clazz.getName().equals(className)) {
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ public class AopNamespaceHandler extends NamespaceHandlerSupport {
|
||||
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
|
||||
* and '{@code scoped-proxy}' tags.
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
// In 2.0 XSD as well as in 2.1 XSD.
|
||||
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -79,6 +79,28 @@ public abstract class AopNamespaceUtils {
|
||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Spring 2.5, in favor of
|
||||
* {@link #registerAutoProxyCreatorIfNecessary(ParserContext, Element)} and
|
||||
* {@link AopConfigUtils#registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry, Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Object source) {
|
||||
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
|
||||
parserContext.getRegistry(), source);
|
||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Spring 2.5, in favor of
|
||||
* {@link AopConfigUtils#forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||
}
|
||||
|
||||
|
||||
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
|
||||
if (sourceElement != null) {
|
||||
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
|
||||
|
||||
-1
@@ -37,7 +37,6 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
*/
|
||||
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
|
||||
extendBeanDefinition(element, parserContext);
|
||||
|
||||
+1
-2
@@ -95,7 +95,6 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
private ParseState parseState = new ParseState();
|
||||
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
CompositeComponentDefinition compositeDef =
|
||||
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
|
||||
@@ -405,7 +404,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
/**
|
||||
* Gets the advice implementation class corresponding to the supplied {@link Element}.
|
||||
*/
|
||||
private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
|
||||
private Class getAdviceClass(Element adviceElement, ParserContext parserContext) {
|
||||
String elementName = parserContext.getDelegate().getLocalName(adviceElement);
|
||||
if (BEFORE.equals(elementName)) {
|
||||
return AspectJMethodBeforeAdvice.class;
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,7 +57,6 @@ public class MethodLocatingFactoryBean implements FactoryBean<Method>, BeanFacto
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (!StringUtils.hasText(this.targetBeanName)) {
|
||||
throw new IllegalArgumentException("Property 'targetBeanName' is required");
|
||||
@@ -66,7 +65,7 @@ public class MethodLocatingFactoryBean implements FactoryBean<Method>, BeanFacto
|
||||
throw new IllegalArgumentException("Property 'methodName' is required");
|
||||
}
|
||||
|
||||
Class<?> beanClass = beanFactory.getType(this.targetBeanName);
|
||||
Class beanClass = beanFactory.getType(this.targetBeanName);
|
||||
if (beanClass == null) {
|
||||
throw new IllegalArgumentException("Can't determine type of bean with name '" + this.targetBeanName + "'");
|
||||
}
|
||||
@@ -79,17 +78,14 @@ public class MethodLocatingFactoryBean implements FactoryBean<Method>, BeanFacto
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Method getObject() throws Exception {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Method> getObjectType() {
|
||||
return Method.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,6 @@ public class PointcutComponentDefinition extends AbstractComponentDefinition {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.pointcutBeanName;
|
||||
}
|
||||
@@ -61,7 +60,6 @@ public class PointcutComponentDefinition extends AbstractComponentDefinition {
|
||||
return new BeanDefinition[] {this.pointcutDefinition};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSource() {
|
||||
return this.pointcutDefinition.getSource();
|
||||
}
|
||||
|
||||
-1
@@ -39,7 +39,6 @@ class ScopedProxyBeanDefinitionDecorator implements BeanDefinitionDecorator {
|
||||
private static final String PROXY_TARGET_CLASS = "proxy-target-class";
|
||||
|
||||
|
||||
@Override
|
||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
||||
boolean proxyTargetClass = true;
|
||||
if (node instanceof Element) {
|
||||
|
||||
+1
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,7 +47,6 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
|
||||
this.aspectBeanName = aspectBeanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
if (!StringUtils.hasText(this.aspectBeanName)) {
|
||||
@@ -60,12 +59,10 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
|
||||
* Look up the aspect bean from the {@link BeanFactory} and returns it.
|
||||
* @see #setAspectBeanName
|
||||
*/
|
||||
@Override
|
||||
public Object getAspectInstance() {
|
||||
return this.beanFactory.getBean(this.aspectBeanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
|
||||
@@ -75,7 +72,6 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
if (this.beanFactory.isSingleton(this.aspectBeanName) &&
|
||||
this.beanFactory.isTypeMatch(this.aspectBeanName, Ordered.class)) {
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,6 @@ class SpringConfiguredBeanDefinitionParser implements BeanDefinitionParser {
|
||||
"org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
|
||||
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
if (!parserContext.getRegistry().containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
|
||||
RootBeanDefinition def = new RootBeanDefinition();
|
||||
|
||||
+19
-40
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,7 +49,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
*/
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap<Class<?>, Boolean>(64);
|
||||
private final Map<Class, Boolean> eligibleBeans = new ConcurrentHashMap<Class, Boolean>(64);
|
||||
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,6 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
this.beforeExistingAdvisors = beforeExistingAdvisors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
@@ -74,28 +73,23 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof AopInfrastructureBean) {
|
||||
// Ignore AOP infrastructure such as scoped proxies.
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
|
||||
// Add our local Advisor to the existing proxy's Advisor chain...
|
||||
if (isEligible(bean, beanName)) {
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
if (this.beforeExistingAdvisors) {
|
||||
advised.addAdvisor(0, this.advisor);
|
||||
}
|
||||
@@ -104,47 +98,32 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
else {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
if (isEligible(bean, beanName)) {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
else {
|
||||
// No async proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
// No async proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given bean is eligible for advising with this
|
||||
* post-processor's {@link Advisor}.
|
||||
* <p>Delegates to {@link #isEligible(Class)} for target class checking.
|
||||
* <p>Implements caching of {@code canApply} results per bean target class.
|
||||
* Can be overridden e.g. to specifically exclude certain beans by name.
|
||||
* <p>Note: Only called for regular bean instances but not for existing
|
||||
* proxy instances which implement {@link Advised} and allow for adding
|
||||
* the local {@link Advisor} to the existing proxy's {@link Advisor} chain.
|
||||
* For the latter, {@link #isEligible(Class)} is being called directly,
|
||||
* with the actual target class behind the existing proxy (as determined
|
||||
* by {@link AopUtils#getTargetClass(Object)}).
|
||||
* @param bean the bean instance
|
||||
* @param beanName the name of the bean
|
||||
* @see #isEligible(Class)
|
||||
*/
|
||||
protected boolean isEligible(Object bean, String beanName) {
|
||||
return isEligible(bean.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given class is eligible for advising with this
|
||||
* post-processor's {@link Advisor}.
|
||||
* <p>Implements caching of {@code canApply} results per bean target class.
|
||||
* @param targetClass the class to check against
|
||||
* @see AopUtils#getTargetClass(Object)
|
||||
* @see AopUtils#canApply(Advisor, Class)
|
||||
*/
|
||||
protected boolean isEligible(Class<?> targetClass) {
|
||||
protected boolean isEligible(Object bean, String beanName) {
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||
Boolean eligible = this.eligibleBeans.get(targetClass);
|
||||
if (eligible != null) {
|
||||
return eligible;
|
||||
|
||||
+1
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -122,7 +122,6 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
this.proxyClassLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
if (this.proxyClassLoader == null) {
|
||||
this.proxyClassLoader = classLoader;
|
||||
@@ -130,7 +129,6 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (this.target == null) {
|
||||
throw new IllegalArgumentException("Property 'target' is required");
|
||||
@@ -192,7 +190,6 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getObject() {
|
||||
if (this.proxy == null) {
|
||||
throw new FactoryBeanNotInitializedException();
|
||||
@@ -200,7 +197,6 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
return this.proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
if (this.proxy != null) {
|
||||
return this.proxy.getClass();
|
||||
@@ -217,7 +213,6 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ import org.springframework.util.CollectionUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @see org.springframework.aop.framework.AopProxy
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
|
||||
/** use serialVersionUID from Spring 2.0 for interoperability */
|
||||
@@ -87,7 +88,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* Interfaces to be implemented by the proxy. Held in List to keep the order
|
||||
* of registration, to create JDK proxy with specified order of interfaces.
|
||||
*/
|
||||
private List<Class<?>> interfaces = new ArrayList<Class<?>>();
|
||||
private List<Class> interfaces = new ArrayList<Class>();
|
||||
|
||||
/**
|
||||
* List of Advisors. If an Advice is added, it will be wrapped
|
||||
@@ -113,7 +114,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* Create a AdvisedSupport instance with the given parameters.
|
||||
* @param interfaces the proxied interfaces
|
||||
*/
|
||||
public AdvisedSupport(Class<?>[] interfaces) {
|
||||
public AdvisedSupport(Class[] interfaces) {
|
||||
this();
|
||||
setInterfaces(interfaces);
|
||||
}
|
||||
@@ -136,12 +137,10 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
setTargetSource(new SingletonTargetSource(target));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetSource(TargetSource targetSource) {
|
||||
this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetSource getTargetSource() {
|
||||
return this.targetSource;
|
||||
}
|
||||
@@ -163,17 +162,14 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
this.targetSource = EmptyTargetSource.forClass(targetClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getTargetClass() {
|
||||
return this.targetSource.getTargetClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreFiltered(boolean preFiltered) {
|
||||
this.preFiltered = preFiltered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreFiltered() {
|
||||
return this.preFiltered;
|
||||
}
|
||||
@@ -201,7 +197,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
public void setInterfaces(Class<?>... interfaces) {
|
||||
Assert.notNull(interfaces, "Interfaces must not be null");
|
||||
this.interfaces.clear();
|
||||
for (Class<?> ifc : interfaces) {
|
||||
for (Class ifc : interfaces) {
|
||||
addInterface(ifc);
|
||||
}
|
||||
}
|
||||
@@ -232,14 +228,12 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
return this.interfaces.remove(intf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getProxiedInterfaces() {
|
||||
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
|
||||
return this.interfaces.toArray(new Class[this.interfaces.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterfaceProxied(Class<?> intf) {
|
||||
for (Class<?> proxyIntf : this.interfaces) {
|
||||
for (Class proxyIntf : this.interfaces) {
|
||||
if (intf.isAssignableFrom(proxyIntf)) {
|
||||
return true;
|
||||
}
|
||||
@@ -248,18 +242,15 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Advisor[] getAdvisors() {
|
||||
return this.advisorArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdvisor(Advisor advisor) {
|
||||
int pos = this.advisors.size();
|
||||
addAdvisor(pos, advisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
validateIntroductionAdvisor((IntroductionAdvisor) advisor);
|
||||
@@ -267,7 +258,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
addAdvisorInternal(pos, advisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAdvisor(Advisor advisor) {
|
||||
int index = indexOf(advisor);
|
||||
if (index == -1) {
|
||||
@@ -279,7 +269,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAdvisor(int index) throws AopConfigException {
|
||||
if (isFrozen()) {
|
||||
throw new AopConfigException("Cannot remove Advisor: Configuration is frozen.");
|
||||
@@ -303,13 +292,11 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
adviceChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Advisor advisor) {
|
||||
Assert.notNull(advisor, "Advisor must not be null");
|
||||
return this.advisors.indexOf(advisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException {
|
||||
Assert.notNull(a, "Advisor a must not be null");
|
||||
Assert.notNull(b, "Advisor b must not be null");
|
||||
@@ -322,6 +309,16 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all of the given advisors to this proxy configuration.
|
||||
* @param advisors the advisors to register
|
||||
* @deprecated as of Spring 3.0, in favor of {@link #addAdvisors}
|
||||
*/
|
||||
@Deprecated
|
||||
public void addAllAdvisors(Advisor[] advisors) {
|
||||
addAdvisors(Arrays.asList(advisors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all of the given advisors to this proxy configuration.
|
||||
* @param advisors the advisors to register
|
||||
@@ -354,8 +351,8 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
private void validateIntroductionAdvisor(IntroductionAdvisor advisor) {
|
||||
advisor.validateInterfaces();
|
||||
// If the advisor passed validation, we can make the change.
|
||||
Class<?>[] ifcs = advisor.getInterfaces();
|
||||
for (Class<?> ifc : ifcs) {
|
||||
Class[] ifcs = advisor.getInterfaces();
|
||||
for (Class ifc : ifcs) {
|
||||
addInterface(ifc);
|
||||
}
|
||||
}
|
||||
@@ -391,7 +388,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addAdvice(Advice advice) throws AopConfigException {
|
||||
int pos = this.advisors.size();
|
||||
addAdvice(pos, advice);
|
||||
@@ -400,7 +396,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
/**
|
||||
* Cannot add introductions this way unless the advice implements IntroductionInfo.
|
||||
*/
|
||||
@Override
|
||||
public void addAdvice(int pos, Advice advice) throws AopConfigException {
|
||||
Assert.notNull(advice, "Advice must not be null");
|
||||
if (advice instanceof IntroductionInfo) {
|
||||
@@ -417,7 +412,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAdvice(Advice advice) throws AopConfigException {
|
||||
int index = indexOf(advice);
|
||||
if (index == -1) {
|
||||
@@ -429,7 +423,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Advice advice) {
|
||||
Assert.notNull(advice, "Advice must not be null");
|
||||
for (int i = 0; i < this.advisors.size(); i++) {
|
||||
@@ -462,7 +455,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* @param adviceClass the advice class to check
|
||||
* @return the count of the interceptors of this class or subclasses
|
||||
*/
|
||||
public int countAdvicesOfType(Class<?> adviceClass) {
|
||||
public int countAdvicesOfType(Class adviceClass) {
|
||||
int count = 0;
|
||||
if (adviceClass != null) {
|
||||
for (Advisor advisor : this.advisors) {
|
||||
@@ -482,7 +475,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* @param targetClass the target class
|
||||
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
*/
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {
|
||||
MethodCacheKey cacheKey = new MethodCacheKey(method);
|
||||
List<Object> cached = this.methodCache.get(cacheKey);
|
||||
if (cached == null) {
|
||||
@@ -520,7 +513,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
copyFrom(other);
|
||||
this.targetSource = targetSource;
|
||||
this.advisorChainFactory = other.advisorChainFactory;
|
||||
this.interfaces = new ArrayList<Class<?>>(other.interfaces);
|
||||
this.interfaces = new ArrayList<Class>(other.interfaces);
|
||||
for (Advisor advisor : advisors) {
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
validateIntroductionAdvisor((IntroductionAdvisor) advisor);
|
||||
@@ -561,7 +554,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toProxyConfigString() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@ public interface AdvisorChainFactory {
|
||||
* for the given advisor chain configuration.
|
||||
* @param config the AOP configuration in the form of an Advised object
|
||||
* @param method the proxied method
|
||||
* @param targetClass the target class (may be {@code null} to indicate a proxy without
|
||||
* target object, in which case the method's declaring class is the next best option)
|
||||
* @param targetClass the target class
|
||||
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
*/
|
||||
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass);
|
||||
List<Object> getInterceptorsAndDynamicInterceptionAdvice(
|
||||
Advised config, Method method, Class targetClass);
|
||||
|
||||
}
|
||||
|
||||
@@ -78,13 +78,13 @@ public abstract class AopProxyUtils {
|
||||
* @see Advised
|
||||
* @see org.springframework.aop.SpringProxy
|
||||
*/
|
||||
public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
|
||||
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
public static Class[] completeProxiedInterfaces(AdvisedSupport advised) {
|
||||
Class[] specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
if (specifiedInterfaces.length == 0) {
|
||||
// No user-specified interfaces: check whether target class is an interface.
|
||||
Class<?> targetClass = advised.getTargetClass();
|
||||
Class targetClass = advised.getTargetClass();
|
||||
if (targetClass != null && targetClass.isInterface()) {
|
||||
specifiedInterfaces = new Class<?>[] {targetClass};
|
||||
specifiedInterfaces = new Class[] {targetClass};
|
||||
}
|
||||
}
|
||||
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
|
||||
@@ -96,7 +96,7 @@ public abstract class AopProxyUtils {
|
||||
if (addAdvised) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
|
||||
Class[] proxiedInterfaces = new Class[specifiedInterfaces.length + nonUserIfcCount];
|
||||
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
|
||||
if (addSpringProxy) {
|
||||
proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
|
||||
@@ -115,8 +115,8 @@ public abstract class AopProxyUtils {
|
||||
* in the original order (never {@code null} or empty)
|
||||
* @see Advised
|
||||
*/
|
||||
public static Class<?>[] proxiedUserInterfaces(Object proxy) {
|
||||
Class<?>[] proxyInterfaces = proxy.getClass().getInterfaces();
|
||||
public static Class[] proxiedUserInterfaces(Object proxy) {
|
||||
Class[] proxyInterfaces = proxy.getClass().getInterfaces();
|
||||
int nonUserIfcCount = 0;
|
||||
if (proxy instanceof SpringProxy) {
|
||||
nonUserIfcCount++;
|
||||
@@ -124,7 +124,7 @@ public abstract class AopProxyUtils {
|
||||
if (proxy instanceof Advised) {
|
||||
nonUserIfcCount++;
|
||||
}
|
||||
Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount];
|
||||
Class[] userInterfaces = new Class[proxyInterfaces.length - nonUserIfcCount];
|
||||
System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length);
|
||||
Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces");
|
||||
return userInterfaces;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,19 +25,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.AopInvocationException;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.RawTargetAccess;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.CallbackFilter;
|
||||
import org.springframework.cglib.proxy.Dispatcher;
|
||||
@@ -46,7 +34,18 @@ import org.springframework.cglib.proxy.Factory;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.cglib.proxy.NoOp;
|
||||
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
|
||||
import org.springframework.cglib.transform.impl.MemorySafeUndeclaredThrowableStrategy;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.AopInvocationException;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.RawTargetAccess;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -80,7 +79,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see DefaultAopProxyFactory
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class CglibAopProxy implements AopProxy, Serializable {
|
||||
final class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
// Constants for CGLIB callback array indices
|
||||
private static final int AOP_PROXY = 0;
|
||||
@@ -147,12 +146,10 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getProxy() {
|
||||
return getProxy(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProxy(ClassLoader classLoader) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
|
||||
@@ -184,22 +181,31 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
}
|
||||
enhancer.setSuperclass(proxySuperClass);
|
||||
enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
|
||||
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
|
||||
enhancer.setInterceptDuringConstruction(false);
|
||||
|
||||
Callback[] callbacks = getCallbacks(rootClass);
|
||||
Class<?>[] types = new Class<?>[callbacks.length];
|
||||
enhancer.setCallbacks(callbacks);
|
||||
enhancer.setCallbackFilter(new ProxyCallbackFilter(
|
||||
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
|
||||
|
||||
Class<?>[] types = new Class[callbacks.length];
|
||||
for (int x = 0; x < types.length; x++) {
|
||||
types[x] = callbacks[x].getClass();
|
||||
}
|
||||
// fixedInterceptorMap only populated at this point, after getCallbacks call above
|
||||
enhancer.setCallbackFilter(new ProxyCallbackFilter(
|
||||
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
|
||||
enhancer.setCallbackTypes(types);
|
||||
|
||||
// Generate the proxy class and create a proxy instance.
|
||||
return createProxyClassAndInstance(enhancer, callbacks);
|
||||
Object proxy;
|
||||
if (this.constructorArgs != null) {
|
||||
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
|
||||
}
|
||||
else {
|
||||
proxy = enhancer.create();
|
||||
}
|
||||
|
||||
return proxy;
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
|
||||
@@ -219,14 +225,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
|
||||
enhancer.setInterceptDuringConstruction(false);
|
||||
enhancer.setCallbacks(callbacks);
|
||||
return (this.constructorArgs != null ?
|
||||
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
|
||||
enhancer.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the CGLIB {@link Enhancer}. Subclasses may wish to override this to return a custom
|
||||
* {@link Enhancer} implementation.
|
||||
@@ -255,14 +253,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* for each one found.
|
||||
*/
|
||||
private void doValidateClass(Class<?> proxySuperClass) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
Method[] methods = proxySuperClass.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (!Object.class.equals(method.getDeclaringClass()) && !Modifier.isStatic(method.getModifiers()) &&
|
||||
Modifier.isFinal(method.getModifiers())) {
|
||||
logger.warn("Unable to proxy method [" + method + "] because it is final: " +
|
||||
"All calls to this method via a proxy will NOT be routed to the target instance.");
|
||||
}
|
||||
Method[] methods = proxySuperClass.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (!Object.class.equals(method.getDeclaringClass()) && Modifier.isFinal(method.getModifiers())) {
|
||||
logger.warn("Unable to proxy method [" + method + "] because it is final: " +
|
||||
"All calls to this method via a proxy will be routed directly to the proxy.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,7 +309,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Callback[] fixedCallbacks = new Callback[methods.length];
|
||||
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
|
||||
|
||||
// TODO: small memory optimisation here (can skip creation for methods with no advice)
|
||||
// TODO: small memory optimisation here (can skip creation for
|
||||
// methods with no advice)
|
||||
for (int x = 0; x < methods.length; x++) {
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
|
||||
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
|
||||
@@ -341,15 +337,16 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
|
||||
// Massage return value if necessary
|
||||
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||
// Special case: it returned "this". Note that we can't help
|
||||
// if the target sets a reference to itself in another returned object.
|
||||
if (retVal != null && retVal == target &&
|
||||
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||
// Special case: it returned "this".
|
||||
// Note that we can't help if the target sets a reference
|
||||
// to itself in another returned object.
|
||||
retVal = proxy;
|
||||
}
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
|
||||
throw new AopInvocationException(
|
||||
"Null return value from advice does not match primitive return type for: " + method);
|
||||
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
@@ -389,7 +386,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
@@ -409,7 +405,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object oldProxy = null;
|
||||
try {
|
||||
@@ -437,7 +432,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.targetSource = targetSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
@@ -462,7 +456,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.targetSource = targetSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object oldProxy = null;
|
||||
Object target = this.targetSource.getTarget();
|
||||
@@ -492,7 +485,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object loadObject() {
|
||||
return this.target;
|
||||
}
|
||||
@@ -510,7 +502,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.advised = advised;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object loadObject() throws Exception {
|
||||
return this.advised;
|
||||
}
|
||||
@@ -529,7 +520,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.advised = advised;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
|
||||
Object other = args[0];
|
||||
if (proxy == other) {
|
||||
@@ -562,7 +552,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.advised = advised;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
|
||||
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
|
||||
}
|
||||
@@ -586,7 +575,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args,
|
||||
this.targetClass, this.adviceChain, methodProxy);
|
||||
@@ -604,13 +592,12 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
|
||||
|
||||
private final AdvisedSupport advised;
|
||||
private AdvisedSupport advised;
|
||||
|
||||
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
|
||||
this.advised = advised;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object oldProxy = null;
|
||||
boolean setProxyContext = false;
|
||||
@@ -622,8 +609,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
setProxyContext = true;
|
||||
}
|
||||
// May be null. Get as late as possible to minimize the time we
|
||||
// "own" the target, in case it comes from a pool...
|
||||
// May be null Get as late as possible to minimize the time we
|
||||
// "own" the target, in case it comes from a pool.
|
||||
target = getTarget();
|
||||
if (target != null) {
|
||||
targetClass = target.getClass();
|
||||
@@ -689,13 +676,13 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final MethodProxy methodProxy;
|
||||
|
||||
private final boolean publicMethod;
|
||||
private boolean protectedMethod;
|
||||
|
||||
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
this.methodProxy = methodProxy;
|
||||
this.publicMethod = Modifier.isPublic(method.getModifiers());
|
||||
this.protectedMethod = Modifier.isProtected(method.getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,11 +691,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.publicMethod) {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
if (this.protectedMethod) {
|
||||
return super.invokeJoinpoint();
|
||||
}
|
||||
else {
|
||||
return super.invokeJoinpoint();
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -767,7 +754,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* DynamicUnadvisedInterceptor already considers this.</dd>
|
||||
* </dl>
|
||||
*/
|
||||
@Override
|
||||
public int accept(Method method) {
|
||||
if (AopUtils.isFinalizeMethod(method)) {
|
||||
logger.debug("Found finalize() method - using NO_OVERRIDE");
|
||||
@@ -829,8 +815,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// of the target type. If so we know it never needs to have return type
|
||||
// massage and can use a dispatcher.
|
||||
// If the proxy is being exposed, then must use the interceptor the
|
||||
// correct one is already configured. If the target is not static, then
|
||||
// cannot use a dispatcher because the target cannot be released.
|
||||
// correct one is already configured. If the target is not static cannot
|
||||
// use a Dispatcher because the target can not then be released.
|
||||
if (exposeProxy || !isStatic) {
|
||||
return INVOKE_TARGET;
|
||||
}
|
||||
@@ -862,7 +848,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof ProxyCallbackFilter)) {
|
||||
|
||||
+9
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,25 +46,22 @@ import org.springframework.aop.support.MethodMatchers;
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
|
||||
|
||||
@Override
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
|
||||
Advised config, Method method, Class<?> targetClass) {
|
||||
Advised config, Method method, Class targetClass) {
|
||||
|
||||
// This is somewhat tricky... We have to process introductions first,
|
||||
// This is somewhat tricky... we have to process introductions first,
|
||||
// but we need to preserve order in the ultimate list.
|
||||
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
|
||||
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
|
||||
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
|
||||
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
|
||||
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
|
||||
|
||||
for (Advisor advisor : config.getAdvisors()) {
|
||||
if (advisor instanceof PointcutAdvisor) {
|
||||
// Add it conditionally.
|
||||
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
|
||||
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
|
||||
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
|
||||
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
|
||||
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
|
||||
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
|
||||
if (mm.isRuntime()) {
|
||||
// Creating a new object instance in the getInterceptors() method
|
||||
// isn't a problem as we normally cache created chains.
|
||||
@@ -80,7 +77,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
}
|
||||
else if (advisor instanceof IntroductionAdvisor) {
|
||||
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
|
||||
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
|
||||
if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
|
||||
Interceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
interceptorList.addAll(Arrays.asList(interceptors));
|
||||
}
|
||||
@@ -90,19 +87,18 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
interceptorList.addAll(Arrays.asList(interceptors));
|
||||
}
|
||||
}
|
||||
|
||||
return interceptorList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the Advisors contain matching introductions.
|
||||
*/
|
||||
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
|
||||
private static boolean hasMatchingIntroductions(Advised config, Class targetClass) {
|
||||
for (int i = 0; i < config.getAdvisors().length; i++) {
|
||||
Advisor advisor = config.getAdvisors()[i];
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
|
||||
if (ia.getClassFilter().matches(actualClass)) {
|
||||
if (ia.getClassFilter().matches(targetClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,10 +48,10 @@ import org.springframework.aop.SpringProxy;
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
|
||||
@Override
|
||||
|
||||
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
|
||||
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
|
||||
Class<?> targetClass = config.getTargetClass();
|
||||
Class targetClass = config.getTargetClass();
|
||||
if (targetClass == null) {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
"Either an interface or a target is required for proxy creation.");
|
||||
@@ -59,7 +59,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
if (targetClass.isInterface()) {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
}
|
||||
return new ObjenesisCglibAopProxy(config);
|
||||
return CglibProxyFactory.createCglibProxy(config);
|
||||
}
|
||||
else {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
@@ -72,7 +72,20 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
* (or no proxy interfaces specified at all).
|
||||
*/
|
||||
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
|
||||
Class<?>[] interfaces = config.getProxiedInterfaces();
|
||||
Class[] interfaces = config.getProxiedInterfaces();
|
||||
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner factory class used to just introduce a CGLIB dependency
|
||||
* when actually creating a CGLIB proxy.
|
||||
*/
|
||||
private static class CglibProxyFactory {
|
||||
|
||||
public static AopProxy createCglibProxy(AdvisedSupport advisedSupport) {
|
||||
return new CglibAopProxy(advisedSupport);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,7 +75,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
*/
|
||||
|
||||
/** We use a static Log to avoid serialization issues */
|
||||
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
|
||||
private static Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
|
||||
|
||||
/** Config used to configure this proxy */
|
||||
private final AdvisedSupport advised;
|
||||
@@ -106,17 +106,15 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getProxy() {
|
||||
return getProxy(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProxy(ClassLoader classLoader) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
|
||||
}
|
||||
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
|
||||
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
|
||||
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
|
||||
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
|
||||
}
|
||||
@@ -126,8 +124,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
* on the supplied set of interfaces.
|
||||
* @param proxiedInterfaces the interfaces to introspect
|
||||
*/
|
||||
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
|
||||
for (Class<?> proxiedInterface : proxiedInterfaces) {
|
||||
private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {
|
||||
for (Class proxiedInterface : proxiedInterfaces) {
|
||||
Method[] methods = proxiedInterface.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if (AopUtils.isEqualsMethod(method)) {
|
||||
@@ -149,14 +147,13 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
* <p>Callers will see exactly the exception thrown by the target,
|
||||
* unless a hook method throws an exception.
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
MethodInvocation invocation;
|
||||
Object oldProxy = null;
|
||||
boolean setProxyContext = false;
|
||||
|
||||
TargetSource targetSource = this.advised.targetSource;
|
||||
Class<?> targetClass = null;
|
||||
Class targetClass = null;
|
||||
Object target = null;
|
||||
|
||||
try {
|
||||
@@ -215,10 +212,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
// is type-compatible. Note that we can't help if the target sets
|
||||
// a reference to itself in another returned object.
|
||||
retVal = proxy;
|
||||
}
|
||||
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
|
||||
throw new AopInvocationException(
|
||||
"Null return value from advice does not match primitive return type for: " + method);
|
||||
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
|
||||
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.framework;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.Factory;
|
||||
import org.springframework.objenesis.ObjenesisException;
|
||||
import org.springframework.objenesis.ObjenesisStd;
|
||||
|
||||
/**
|
||||
* Objenesis based extension of {@link CglibAopProxy} to create proxy instances without
|
||||
* invoking the constructor of the class.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 4.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class ObjenesisCglibAopProxy extends CglibAopProxy {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ObjenesisCglibAopProxy.class);
|
||||
|
||||
private final ObjenesisStd objenesis;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link ObjenesisCglibAopProxy} using the given {@link AdvisedSupport}.
|
||||
* @param config must not be {@literal null}.
|
||||
*/
|
||||
public ObjenesisCglibAopProxy(AdvisedSupport config) {
|
||||
super(config);
|
||||
this.objenesis = new ObjenesisStd(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
|
||||
try {
|
||||
Factory factory = (Factory) this.objenesis.newInstance(enhancer.createClass());
|
||||
factory.setCallbacks(callbacks);
|
||||
return factory;
|
||||
}
|
||||
catch (ObjenesisException ex) {
|
||||
// Fallback to regular proxy construction on unsupported JVMs
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", ex);
|
||||
}
|
||||
return super.createProxyClassAndInstance(enhancer, callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.framework;
|
||||
import org.aopalliance.intercept.Interceptor;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -46,8 +47,9 @@ public class ProxyFactory extends ProxyCreatorSupport {
|
||||
* @param target the target object to be proxied
|
||||
*/
|
||||
public ProxyFactory(Object target) {
|
||||
setTarget(target);
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
setInterfaces(ClassUtils.getAllInterfaces(target));
|
||||
setTarget(target);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -133,7 +133,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @see #setInterfaces
|
||||
* @see AbstractSingletonProxyFactoryBean#setProxyInterfaces
|
||||
*/
|
||||
public void setProxyInterfaces(Class<?>[] proxyInterfaces) throws ClassNotFoundException {
|
||||
public void setProxyInterfaces(Class[] proxyInterfaces) throws ClassNotFoundException {
|
||||
setInterfaces(proxyInterfaces);
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @see org.aopalliance.aop.Advice
|
||||
* @see org.springframework.aop.target.SingletonTargetSource
|
||||
*/
|
||||
public void setInterceptorNames(String... interceptorNames) {
|
||||
public void setInterceptorNames(String[] interceptorNames) {
|
||||
this.interceptorNames = interceptorNames;
|
||||
}
|
||||
|
||||
@@ -218,14 +218,12 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
this.classLoaderConfigured = (classLoader != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
if (!this.classLoaderConfigured) {
|
||||
this.proxyClassLoader = classLoader;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
checkInterceptorNames();
|
||||
@@ -239,7 +237,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* {@code getObject()} for a proxy.
|
||||
* @return a fresh AOP proxy reflecting the current state of this factory
|
||||
*/
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
initializeAdvisorChain();
|
||||
if (isSingleton()) {
|
||||
@@ -260,14 +257,13 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* a single one), the target bean type, or the TargetSource's target class.
|
||||
* @see org.springframework.aop.TargetSource#getTargetClass
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
synchronized (this) {
|
||||
if (this.singletonInstance != null) {
|
||||
return this.singletonInstance.getClass();
|
||||
}
|
||||
}
|
||||
Class<?>[] ifcs = getProxiedInterfaces();
|
||||
Class[] ifcs = getProxiedInterfaces();
|
||||
if (ifcs.length == 1) {
|
||||
return ifcs[0];
|
||||
}
|
||||
@@ -282,7 +278,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return this.singleton;
|
||||
}
|
||||
@@ -297,7 +292,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @return the merged interface as Class
|
||||
* @see java.lang.reflect.Proxy#getProxyClass
|
||||
*/
|
||||
protected Class<?> createCompositeInterface(Class<?>[] interfaces) {
|
||||
protected Class createCompositeInterface(Class[] interfaces) {
|
||||
return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader);
|
||||
}
|
||||
|
||||
@@ -311,7 +306,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
this.targetSource = freshTargetSource();
|
||||
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
|
||||
// Rely on AOP infrastructure to tell us what interfaces to proxy.
|
||||
Class<?> targetClass = getTargetClass();
|
||||
Class targetClass = getTargetClass();
|
||||
if (targetClass == null) {
|
||||
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
|
||||
}
|
||||
@@ -401,7 +396,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @return {@code true} if it's an Advisor or Advice
|
||||
*/
|
||||
private boolean isNamedBeanAnAdvisorOrAdvice(String beanName) {
|
||||
Class<?> namedBeanClass = this.beanFactory.getType(beanName);
|
||||
Class namedBeanClass = this.beanFactory.getType(beanName);
|
||||
if (namedBeanClass != null) {
|
||||
return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
|
||||
}
|
||||
@@ -643,12 +638,10 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
return beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPerInstance() {
|
||||
throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
|
||||
}
|
||||
|
||||
+3
-14
@@ -68,7 +68,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
|
||||
protected Object[] arguments;
|
||||
|
||||
private final Class<?> targetClass;
|
||||
private final Class targetClass;
|
||||
|
||||
/**
|
||||
* Lazily initialized map of user-specific attributes for this invocation.
|
||||
@@ -79,7 +79,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
|
||||
* that need dynamic checks.
|
||||
*/
|
||||
protected final List<?> interceptorsAndDynamicMethodMatchers;
|
||||
protected final List interceptorsAndDynamicMethodMatchers;
|
||||
|
||||
/**
|
||||
* Index from 0 of the current interceptor we're invoking.
|
||||
@@ -103,7 +103,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
*/
|
||||
protected ReflectiveMethodInvocation(
|
||||
Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
Class targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
|
||||
this.proxy = proxy;
|
||||
this.target = target;
|
||||
@@ -114,17 +114,14 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Object getProxy() {
|
||||
return this.proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object getThis() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AccessibleObject getStaticPart() {
|
||||
return this.method;
|
||||
}
|
||||
@@ -134,23 +131,19 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* May or may not correspond with a method invoked on an underlying
|
||||
* implementation of that interface.
|
||||
*/
|
||||
@Override
|
||||
public final Method getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object[] getArguments() {
|
||||
return (this.arguments != null ? this.arguments : new Object[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArguments(Object[] arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object proceed() throws Throwable {
|
||||
// We start with an index of -1 and increment early.
|
||||
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
|
||||
@@ -199,7 +192,6 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* current interceptor index.
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public MethodInvocation invocableClone() {
|
||||
Object[] cloneArguments = null;
|
||||
if (this.arguments != null) {
|
||||
@@ -218,7 +210,6 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* current interceptor index.
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public MethodInvocation invocableClone(Object[] arguments) {
|
||||
// Force initialization of the user attributes Map,
|
||||
// for having a shared Map reference in the clone.
|
||||
@@ -239,7 +230,6 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setUserAttribute(String key, Object value) {
|
||||
if (value != null) {
|
||||
if (this.userAttributes == null) {
|
||||
@@ -254,7 +244,6 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getUserAttribute(String key) {
|
||||
return (this.userAttributes != null ? this.userAttributes.get(key) : null);
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,12 +48,10 @@ public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof AdvisorAdapter){
|
||||
this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);
|
||||
|
||||
-2
@@ -34,12 +34,10 @@ import org.springframework.aop.AfterReturningAdvice;
|
||||
@SuppressWarnings("serial")
|
||||
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
|
||||
|
||||
@Override
|
||||
public boolean supportsAdvice(Advice advice) {
|
||||
return (advice instanceof AfterReturningAdvice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodInterceptor getInterceptor(Advisor advisor) {
|
||||
AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
|
||||
return new AfterReturningAdviceInterceptor(advice);
|
||||
|
||||
-1
@@ -47,7 +47,6 @@ public class AfterReturningAdviceInterceptor implements MethodInterceptor, After
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
Object retVal = mi.proceed();
|
||||
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
|
||||
|
||||
-3
@@ -53,7 +53,6 @@ public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Se
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
|
||||
if (adviceObject instanceof Advisor) {
|
||||
return (Advisor) adviceObject;
|
||||
@@ -75,7 +74,6 @@ public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Se
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
|
||||
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
|
||||
Advice advice = advisor.getAdvice();
|
||||
@@ -93,7 +91,6 @@ public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Se
|
||||
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
|
||||
this.adapters.add(adapter);
|
||||
}
|
||||
|
||||
-2
@@ -34,12 +34,10 @@ import org.springframework.aop.MethodBeforeAdvice;
|
||||
@SuppressWarnings("serial")
|
||||
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
|
||||
|
||||
@Override
|
||||
public boolean supportsAdvice(Advice advice) {
|
||||
return (advice instanceof MethodBeforeAdvice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodInterceptor getInterceptor(Advisor advisor) {
|
||||
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
|
||||
return new MethodBeforeAdviceInterceptor(advice);
|
||||
|
||||
-1
@@ -46,7 +46,6 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Seriali
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
|
||||
return mi.proceed();
|
||||
|
||||
-2
@@ -34,12 +34,10 @@ import org.springframework.aop.ThrowsAdvice;
|
||||
@SuppressWarnings("serial")
|
||||
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
|
||||
|
||||
@Override
|
||||
public boolean supportsAdvice(Advice advice) {
|
||||
return (advice instanceof ThrowsAdvice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodInterceptor getInterceptor(Advisor advisor) {
|
||||
return new ThrowsAdviceInterceptor(advisor.getAdvice());
|
||||
}
|
||||
|
||||
+2
-3
@@ -61,7 +61,7 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
private final Object throwsAdvice;
|
||||
|
||||
/** Methods on throws advice, keyed by exception class */
|
||||
private final Map<Class<?>, Method> exceptionHandlerMap = new HashMap<Class<?>, Method>();
|
||||
private final Map<Class, Method> exceptionHandlerMap = new HashMap<Class, Method>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
* @return a handler for the given exception type
|
||||
*/
|
||||
private Method getExceptionHandler(Throwable exception) {
|
||||
Class<?> exceptionClass = exception.getClass();
|
||||
Class exceptionClass = exception.getClass();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]");
|
||||
}
|
||||
@@ -119,7 +119,6 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
|
||||
+4
-4
@@ -65,8 +65,8 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
|
||||
|
||||
|
||||
@Override
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
|
||||
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
|
||||
List advisors = findEligibleAdvisors(beanClass, beanName);
|
||||
if (advisors.isEmpty()) {
|
||||
return DO_NOT_PROXY;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
|
||||
* @see #sortAdvisors
|
||||
* @see #extendAdvisors
|
||||
*/
|
||||
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
|
||||
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
|
||||
List<Advisor> candidateAdvisors = findCandidateAdvisors();
|
||||
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
|
||||
extendAdvisors(eligibleAdvisors);
|
||||
@@ -111,7 +111,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
|
||||
* @see ProxyCreationContext#getCurrentProxiedBeanName()
|
||||
*/
|
||||
protected List<Advisor> findAdvisorsThatCanApply(
|
||||
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
|
||||
List<Advisor> candidateAdvisors, Class beanClass, String beanName) {
|
||||
|
||||
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
|
||||
try {
|
||||
|
||||
+25
-82
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,10 +20,8 @@ import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
@@ -40,18 +38,14 @@ import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
|
||||
import org.springframework.aop.target.SingletonTargetSource;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.Aware;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
@@ -142,11 +136,11 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
|
||||
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(64);
|
||||
|
||||
private final Set<String> targetSourcedBeans =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
|
||||
// using a ConcurrentHashMap as a Set
|
||||
private final Map<String, Boolean> targetSourcedBeans = new ConcurrentHashMap<String, Boolean>(16);
|
||||
|
||||
private final Set<Object> earlyProxyReferences =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>(16));
|
||||
// using a ConcurrentHashMap as a Set
|
||||
private final Map<Object, Boolean> earlyProxyReferences = new ConcurrentHashMap<Object, Boolean>(16);
|
||||
|
||||
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16);
|
||||
|
||||
@@ -161,7 +155,6 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
@@ -205,7 +198,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* Ordering is significant: The TargetSource returned from the first matching
|
||||
* TargetSourceCreator (that is, the first that returns non-null) will be used.
|
||||
*/
|
||||
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
|
||||
public void setCustomTargetSourceCreators(TargetSourceCreator[] targetSourceCreators) {
|
||||
this.customTargetSourceCreators = targetSourceCreators;
|
||||
}
|
||||
|
||||
@@ -216,7 +209,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* This is perfectly valid, if "specific" interceptors such as matching
|
||||
* Advisors are all we want.
|
||||
*/
|
||||
public void setInterceptorNames(String... interceptorNames) {
|
||||
public void setInterceptorNames(String[] interceptorNames) {
|
||||
this.interceptorNames = interceptorNames;
|
||||
}
|
||||
|
||||
@@ -239,14 +232,12 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
this.classLoaderConfigured = (classLoader != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
if (!this.classLoaderConfigured) {
|
||||
this.proxyClassLoader = classLoader;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
@@ -260,31 +251,25 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
|
||||
Object cacheKey = getCacheKey(beanClass, beanName);
|
||||
return this.proxyTypes.get(cacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
}
|
||||
this.earlyProxyReferences.put(cacheKey, Boolean.TRUE);
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
|
||||
Object cacheKey = getCacheKey(beanClass, beanName);
|
||||
|
||||
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
|
||||
if (beanName == null || !this.targetSourcedBeans.containsKey(beanName)) {
|
||||
if (this.advisedBeans.containsKey(cacheKey)) {
|
||||
return null;
|
||||
}
|
||||
@@ -300,7 +285,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
if (beanName != null) {
|
||||
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
|
||||
if (targetSource != null) {
|
||||
this.targetSourcedBeans.add(beanName);
|
||||
this.targetSourcedBeans.put(beanName, Boolean.TRUE);
|
||||
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
|
||||
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
|
||||
this.proxyTypes.put(cacheKey, proxy.getClass());
|
||||
@@ -311,19 +296,16 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||
|
||||
return pvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
@@ -333,11 +315,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* identified as one to proxy by the subclass.
|
||||
* @see #getAdvicesAndAdvisorsForBean
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean != null) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
}
|
||||
@@ -363,7 +344,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* @return a proxy wrapping the bean, or the raw bean instance as-is
|
||||
*/
|
||||
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
|
||||
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
|
||||
if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {
|
||||
return bean;
|
||||
}
|
||||
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
|
||||
@@ -471,12 +452,12 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
|
||||
if (!proxyFactory.isProxyTargetClass()) {
|
||||
if (shouldProxyTargetClass(beanClass, beanName)) {
|
||||
proxyFactory.setProxyTargetClass(true);
|
||||
}
|
||||
else {
|
||||
evaluateProxyInterfaces(beanClass, proxyFactory);
|
||||
if (!shouldProxyTargetClass(beanClass, beanName)) {
|
||||
// Must allow for introductions; can't just set interfaces to
|
||||
// the target's interfaces only.
|
||||
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
|
||||
for (Class<?> targetInterface : targetInterfaces) {
|
||||
proxyFactory.addInterface(targetInterface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,8 +478,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given bean should be proxied with its target class rather than its interfaces.
|
||||
* <p>Checks the {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
|
||||
* Determine whether the given bean should be proxied with its target
|
||||
* class rather than its interfaces. Checks the
|
||||
* {@link #setProxyTargetClass "proxyTargetClass" setting} as well as the
|
||||
* {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
|
||||
* of the corresponding bean definition.
|
||||
* @param beanClass the class of the bean
|
||||
* @param beanName the name of the bean
|
||||
@@ -506,49 +489,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* @see AutoProxyUtils#shouldProxyTargetClass
|
||||
*/
|
||||
protected boolean shouldProxyTargetClass(Class<?> beanClass, String beanName) {
|
||||
return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
|
||||
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the interfaces on the given bean class and apply them to the ProxyFactory,
|
||||
* if appropriate.
|
||||
* <p>Calls {@link #isConfigurationCallbackInterface} to filter for reasonable
|
||||
* proxy interfaces, falling back to a target-class proxy otherwise.
|
||||
* @param beanClass the class of the bean
|
||||
* @param proxyFactory the ProxyFactory for the bean
|
||||
*/
|
||||
private void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
|
||||
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
|
||||
boolean hasReasonableProxyInterface = false;
|
||||
for (Class<?> ifc : targetInterfaces) {
|
||||
if (!isConfigurationCallbackInterface(ifc) && ifc.getMethods().length > 0) {
|
||||
hasReasonableProxyInterface = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasReasonableProxyInterface) {
|
||||
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
|
||||
for (Class<?> ifc : targetInterfaces) {
|
||||
proxyFactory.addInterface(ifc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
proxyFactory.setProxyTargetClass(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given interface is just a container callback and
|
||||
* therefore not to be considered as a reasonable proxy interface.
|
||||
* <p>If no reasonable proxy interface is found for a given bean, it will get
|
||||
* proxied with its full target class, assuming that as the user's intention.
|
||||
* @param ifc the interface to check
|
||||
* @return whether the given interface is just a container callback
|
||||
*/
|
||||
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
|
||||
return (ifc.equals(InitializingBean.class) || ifc.equals(DisposableBean.class) ||
|
||||
ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
|
||||
return (isProxyTargetClass() ||
|
||||
(this.beanFactory instanceof ConfigurableListableBeanFactory &&
|
||||
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,7 +60,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
|
||||
*/
|
||||
public void setBeanNames(String... beanNames) {
|
||||
public void setBeanNames(String[] beanNames) {
|
||||
Assert.notEmpty(beanNames, "'beanNames' must not be empty");
|
||||
this.beanNames = new ArrayList<String>(beanNames.length);
|
||||
for (String mappedName : beanNames) {
|
||||
@@ -73,7 +73,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
* Identify as bean to proxy if the bean name is in the configured list of names.
|
||||
*/
|
||||
@Override
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
|
||||
if (this.beanNames != null) {
|
||||
for (String mappedName : this.beanNames) {
|
||||
if (FactoryBean.class.isAssignableFrom(beanClass)) {
|
||||
|
||||
-1
@@ -79,7 +79,6 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
|
||||
return this.advisorBeanNamePrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
// If no infrastructure bean name prefix has been set, override it.
|
||||
if (this.advisorBeanNamePrefix == null) {
|
||||
|
||||
-3
@@ -66,7 +66,6 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
new HashMap<String, DefaultListableBeanFactory>();
|
||||
|
||||
|
||||
@Override
|
||||
public final void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (!(beanFactory instanceof ConfigurableBeanFactory)) {
|
||||
throw new IllegalStateException("Cannot do auto-TargetSource creation with a BeanFactory " +
|
||||
@@ -87,7 +86,6 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
// Implementation of the TargetSourceCreator interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final TargetSource getTargetSource(Class<?> beanClass, String beanName) {
|
||||
AbstractBeanFactoryBasedTargetSource targetSource =
|
||||
createBeanFactoryBasedTargetSource(beanClass, beanName);
|
||||
@@ -161,7 +159,6 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
|
||||
* Destroys the internal BeanFactory on shutdown of the TargetSourceCreator.
|
||||
* @see #getInternalBeanFactoryForBean
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
synchronized (this.internalBeanFactories) {
|
||||
for (DefaultListableBeanFactory bf : this.internalBeanFactories.values()) {
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
* TargetSourceCreator that enforces a LazyInitTargetSource for each bean
|
||||
* that is defined as "lazy-init". This will lead to a proxy created for
|
||||
* each of those beans, allowing to fetch a reference to such a bean
|
||||
* without actually initializing the target bean instance.
|
||||
* without actually initialized the target bean instance.
|
||||
*
|
||||
* <p>To be registered as custom TargetSourceCreator for an auto-proxy creator,
|
||||
* in combination with custom interceptors for specific beans or for the
|
||||
@@ -60,7 +60,7 @@ public class LazyInitTargetSourceCreator extends AbstractBeanFactoryBasedTargetS
|
||||
|
||||
@Override
|
||||
protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(
|
||||
Class<?> beanClass, String beanName) {
|
||||
Class beanClass, String beanName) {
|
||||
|
||||
if (getBeanFactory() instanceof ConfigurableListableBeanFactory) {
|
||||
BeanDefinition definition =
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class QuickTargetSourceCreator extends AbstractBeanFactoryBasedTargetSour
|
||||
|
||||
@Override
|
||||
protected final AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(
|
||||
Class<?> beanClass, String beanName) {
|
||||
Class beanClass, String beanName) {
|
||||
|
||||
if (beanName.startsWith(PREFIX_COMMONS_POOL)) {
|
||||
CommonsPoolTargetSource cpts = new CommonsPoolTargetSource();
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ public abstract class AbstractMonitoringInterceptor extends AbstractTraceInterce
|
||||
protected String createInvocationTraceName(MethodInvocation invocation) {
|
||||
StringBuilder sb = new StringBuilder(getPrefix());
|
||||
Method method = invocation.getMethod();
|
||||
Class<?> clazz = method.getDeclaringClass();
|
||||
Class clazz = method.getDeclaringClass();
|
||||
if (this.logTargetClassInvocation && clazz.isInstance(invocation.getThis())) {
|
||||
clazz = invocation.getThis().getClass();
|
||||
}
|
||||
|
||||
+1
-2
@@ -105,7 +105,6 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
* to the {@code invokeUnderTrace} method for handling.
|
||||
* @see #invokeUnderTrace(org.aopalliance.intercept.MethodInvocation, org.apache.commons.logging.Log)
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
Log logger = getLoggerForInvocation(invocation);
|
||||
if (isInterceptorEnabled(invocation, logger)) {
|
||||
@@ -142,7 +141,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
* @return the target class for the given object
|
||||
* @see #setHideProxyClassNames
|
||||
*/
|
||||
protected Class<?> getClassForLogging(Object target) {
|
||||
protected Class getClassForLogging(Object target) {
|
||||
return (this.hideProxyClassNames ? AopUtils.getTargetClass(target) : target.getClass());
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
@@ -79,8 +80,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
/**
|
||||
* Set the {@link BeanFactory} to be used when looking up executors by qualifier.
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
|
||||
+6
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,11 +62,11 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
|
||||
/**
|
||||
* Create a new {@code AsyncExecutionInterceptor}.
|
||||
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to
|
||||
* @param executor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to.
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor defaultExecutor) {
|
||||
super(defaultExecutor);
|
||||
public AsyncExecutionInterceptor(Executor executor) {
|
||||
super(executor);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
* @return {@link Future} if the original method returns {@code Future}; {@code null}
|
||||
* otherwise.
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
|
||||
@@ -91,7 +90,6 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
|
||||
Future<?> result = executor.submit(
|
||||
new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
try {
|
||||
Object result = invocation.proceed();
|
||||
@@ -119,15 +117,14 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
* Subclasses may override to provide support for extracting qualifier information,
|
||||
* e.g. via an annotation on the given method.
|
||||
* @return always {@code null}
|
||||
* @since 3.1.2
|
||||
* @see #determineAsyncExecutor(Method)
|
||||
* @since 3.1.2
|
||||
*/
|
||||
@Override
|
||||
protected String getExecutorQualifier(Method method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
-1
@@ -47,7 +47,6 @@ public class ConcurrencyThrottleInterceptor extends ConcurrencyThrottleSupport
|
||||
setConcurrencyLimit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||
beforeAccess();
|
||||
try {
|
||||
|
||||
+35
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -151,7 +151,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
/**
|
||||
* The {@code Set} of allowed placeholders.
|
||||
*/
|
||||
private static final Set<Object> ALLOWED_PLACEHOLDERS =
|
||||
private static final Set ALLOWED_PLACEHOLDERS =
|
||||
new Constants(CustomizableTraceInterceptor.class).getValues("PLACEHOLDER_");
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
return returnValue;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (stopWatch.isRunning()) {
|
||||
if(stopWatch.isRunning()) {
|
||||
stopWatch.stop();
|
||||
}
|
||||
exitThroughException = true;
|
||||
@@ -268,7 +268,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
}
|
||||
finally {
|
||||
if (!exitThroughException) {
|
||||
if (stopWatch.isRunning()) {
|
||||
if(stopWatch.isRunning()) {
|
||||
stopWatch.stop();
|
||||
}
|
||||
writeToLog(logger,
|
||||
@@ -325,19 +325,18 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
if (PLACEHOLDER_METHOD_NAME.equals(match)) {
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(methodInvocation.getMethod().getName()));
|
||||
matcher.appendReplacement(output, escape(methodInvocation.getMethod().getName()));
|
||||
}
|
||||
else if (PLACEHOLDER_TARGET_CLASS_NAME.equals(match)) {
|
||||
String className = getClassForLogging(methodInvocation.getThis()).getName();
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(className));
|
||||
matcher.appendReplacement(output, escape(className));
|
||||
}
|
||||
else if (PLACEHOLDER_TARGET_CLASS_SHORT_NAME.equals(match)) {
|
||||
String shortName = ClassUtils.getShortName(getClassForLogging(methodInvocation.getThis()));
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(shortName));
|
||||
matcher.appendReplacement(output, escape(shortName));
|
||||
}
|
||||
else if (PLACEHOLDER_ARGUMENTS.equals(match)) {
|
||||
matcher.appendReplacement(output,
|
||||
Matcher.quoteReplacement(StringUtils.arrayToCommaDelimitedString(methodInvocation.getArguments())));
|
||||
matcher.appendReplacement(output, escape(StringUtils.arrayToCommaDelimitedString(methodInvocation.getArguments())));
|
||||
}
|
||||
else if (PLACEHOLDER_ARGUMENT_TYPES.equals(match)) {
|
||||
appendArgumentTypes(methodInvocation, matcher, output);
|
||||
@@ -346,7 +345,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
appendReturnValue(methodInvocation, matcher, output, returnValue);
|
||||
}
|
||||
else if (throwable != null && PLACEHOLDER_EXCEPTION.equals(match)) {
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(throwable.toString()));
|
||||
matcher.appendReplacement(output, escape(throwable.toString()));
|
||||
}
|
||||
else if (PLACEHOLDER_INVOCATION_TIME.equals(match)) {
|
||||
matcher.appendReplacement(output, Long.toString(invocationTime));
|
||||
@@ -380,7 +379,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
matcher.appendReplacement(output, "null");
|
||||
}
|
||||
else {
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(returnValue.toString()));
|
||||
matcher.appendReplacement(output, escape(returnValue.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,13 +394,12 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
* @param output the {@code StringBuffer} containing the output
|
||||
*/
|
||||
private void appendArgumentTypes(MethodInvocation methodInvocation, Matcher matcher, StringBuffer output) {
|
||||
Class<?>[] argumentTypes = methodInvocation.getMethod().getParameterTypes();
|
||||
Class[] argumentTypes = methodInvocation.getMethod().getParameterTypes();
|
||||
String[] argumentTypeShortNames = new String[argumentTypes.length];
|
||||
for (int i = 0; i < argumentTypeShortNames.length; i++) {
|
||||
argumentTypeShortNames[i] = ClassUtils.getShortName(argumentTypes[i]);
|
||||
}
|
||||
matcher.appendReplacement(output,
|
||||
Matcher.quoteReplacement(StringUtils.arrayToCommaDelimitedString(argumentTypeShortNames)));
|
||||
matcher.appendReplacement(output, escape(StringUtils.arrayToCommaDelimitedString(argumentTypeShortNames)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,4 +417,27 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces {@code $} in inner class names with {@code \$}.
|
||||
* <p>This code is equivalent to JDK 1.5's {@code quoteReplacement}
|
||||
* method in the Matcher class itself. We're keeping our own version
|
||||
* here for JDK 1.4 compliance reasons only.
|
||||
*/
|
||||
private String escape(String input) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
if (c == '\\') {
|
||||
sb.append("\\\\");
|
||||
}
|
||||
else if (c == '$') {
|
||||
sb.append("\\$");
|
||||
}
|
||||
else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user