Compare commits

..

64 Commits

Author SHA1 Message Date
Spring Buildmaster dd42a21f39 Release version 4.2.5.RELEASE 2016-02-25 01:35:50 -08:00
Juergen Hoeller cafb99a33d Polishing
(cherry picked from commit 028a690)
2016-02-24 17:59:15 +01:00
Juergen Hoeller 9c5cabf4ba Refined ApplicationContextInitializer assignability exception
(cherry picked from commit ca19920)
2016-02-24 17:58:29 +01:00
Juergen Hoeller 97b017781a TimerScheduledFuture correctly calculates getDelay result
Issue: SPR-13977
(cherry picked from commit a68b910)
2016-02-24 17:56:30 +01:00
Juergen Hoeller 9f2b3ca8b8 Polishing
(cherry picked from commit 1899fb3)
2016-02-23 00:05:44 +01:00
Juergen Hoeller 3f795e64c6 Avoid NPE in case of @Lazy @Autowired(required=false)
Issue: SPR-13967
(cherry picked from commit b9fe6d8)
2016-02-23 00:05:17 +01:00
Juergen Hoeller 99dc7769a6 Latest dependency updates (EhCache 3.0 M5, Groovy 2.4.6, Gson 2.6.1, Hibernate ORM 5.0.8, Hibernate Validator 5.2.4, SLF4J 1.7.16, SnakeYAML 1.17, Undertow 1.3.18) 2016-02-23 00:04:49 +01:00
Juergen Hoeller a620770470 Polishing 2016-02-19 16:02:25 +01:00
Juergen Hoeller 167ba8387a ScriptUtils.executeSqlScript logs SQLWarnings at debug level
Issue: SPR-13959
(cherry picked from commit 9235345)
2016-02-19 15:59:47 +01:00
Juergen Hoeller 4320161172 Shared EntityManager Query unwrapping before passing it to addNamedQuery
Issue: SPR-13957
(cherry picked from commit 7fcb277)
2016-02-19 15:59:24 +01:00
Juergen Hoeller 659e44146c Consistent equals implementations across class hierarchies
Issue: SPR-13951
(cherry picked from commit ac44f9e)
2016-02-19 15:56:36 +01:00
Juergen Hoeller 08f2ab942c DefaultMessageListenerContainer stops if recovery failed after interrupt signal
Issue: SPR-11787
(cherry picked from commit 1253b45)
2016-02-19 15:54:52 +01:00
Juergen Hoeller d2b9dbf181 BeanMethodInterceptor does not pass on null arguments for singleton beans
Issue: SPR-13887
(cherry picked from commit 5ed9046)
2016-02-19 15:54:26 +01:00
Sebastien Deleuze 09db26af2b Improve Jackson 2.7 compatibility
This commit introduces a conditional call in
AbstractJackson2HttpMessageConverter#getJavaType() in order to avoid
calling TypeFactory#constructType() with a null contextClass parameter,
since this is not supported by Jackson 2.7 anymore.

It allows to use Spring Framework 4.2.x with Jackson 2.7.1+ for most use
cases, but with some limitations. For example, with Jackson 2.7
TypeVariable resolution from method parameters does not work.

As a consequence, after this commit Spring Framework 4.2.x still fully
supports Jackson up to version 2.6, but improves Jackson 2.7 compatibility.
Full support for Jackson 2.7 is provided as of Spring Framework 4.3.x.

Issue: SPR-13853
2016-02-11 13:45:49 +01:00
Juergen Hoeller 19c5462b13 Polishing 2016-02-10 20:48:10 +01:00
Juergen Hoeller 5047e90625 AbstractMarshaller defensively uses DocumentBuilderFactory within synchronized block
Issue: SPR-13935
(cherry picked from commit f61b998)
2016-02-10 20:47:54 +01:00
Juergen Hoeller cf3e460a8b ReflectiveMethodResolver lets local static methods override java.lang.Class methods
Issue: SPR-13918
(cherry picked from commit 43bcab9)
2016-02-10 20:47:41 +01:00
Juergen Hoeller c960d9733d DisposableBeanAdapter ignores bridge method conflicts
Issue: SPR-13922
(cherry picked from commit 903ae48)
2016-02-10 20:47:31 +01:00
Juergen Hoeller 9e7f6ba0b1 PathMatchingResourcePatternResolver consistently logs retrieval results
Issue: SPR-13923
(cherry picked from commit 449f704)
2016-02-10 20:47:24 +01:00
Juergen Hoeller d8a7b6f0f8 Latest dependency updates (Hibernate Validator 5.2.3, Joda-Time 2.9.2, OkHttp 2.7.4, SLF4J 1.7.15, Netty 4.0.34, Tomcat 8.0.32, Undertow 1.3.17) 2016-02-10 20:40:18 +01:00
Rossen Stoyanchev 6ef2d827c6 Reduce log level for @ExceptionHandler failure
Issue: SPR-13932
2016-02-09 12:58:08 -05:00
Rossen Stoyanchev b1a46ccbd9 Fix NPE in InvocableHandlerMethod
Issue: SPR-13917
2016-02-04 23:33:04 -05:00
Rossen Stoyanchev f053cdec51 Improve close in ConcurrentWebSocketSessionDecorator
Before this commit the concurrent session wrapper mainly protected the
sending of messages. The close itself however may also cause a message
to be sent as is the case of the SockJS protocol.

This change protects the close and checks if the session has exceeded
send time or buffer limits in which case the close status is changed
to SESSION_NOT_RELIABLE (introduced in commit cbd5af3a) which in turn
signals that extra care should be exercised when closing the session.

Issue: SPR-13904
2016-02-04 17:22:36 -05:00
Rossen Stoyanchev 39c05c56c4 BufferedImage converter writes Content-Type again
Issue: SPR-13906
2016-02-04 15:01:13 -05:00
Juergen Hoeller 4418331429 Polishing
(cherry picked from commit e903106)
2016-02-04 20:50:21 +01:00
Juergen Hoeller e48315549e AbstractXlsView does not explicitly flush (for compatibility with WebSphere Liberty)
Issue: SPR-13910
(cherry picked from commit 28e8af2)
2016-02-04 20:49:48 +01:00
Sam Brannen 484dd96606 Throw exception if TxMgr cannot be retrieved for @Transactional test
Prior to this commit, a @Transactional integration test would silently
be executed without a transaction if the transaction manager could not
be retrieved from the application context -- for example, it no such
bean was defined or if multiple beans were present but none satisfied
the qualifier.

This commit addresses this issue by throwing an IllegalStateException
if the PlatformTransactionManager cannot be retrieved for a
@Transactional test.

Issue: SPR-13895
(cherry picked from commit 6d2b9a0136)
2016-02-03 18:18:55 +01:00
Juergen Hoeller bb12e0ea70 Latest dependency updates (AspectJ 1.8.8, Hibernate ORM 5.0.7, Jackson 2.6.5, Jetty 9.3.7, Undertow 1.3.14, SLF4J 1.7.14) 2016-01-26 22:25:22 +01:00
Juergen Hoeller 30ef893c28 Polishing 2016-01-26 22:23:56 +01:00
Juergen Hoeller a58eee6ad1 RequestParamMethodArgumentResolver defensively handles MethodParameter nesting level and java.util.Optional access
Issue: SPR-13850
2016-01-26 22:07:27 +01:00
Juergen Hoeller 0866aa923a LocalSessionFactoryBuilder provides ClassLoader to Hibernate BootstrapServiceRegistry
Issue: SPR-13879
2016-01-26 20:35:30 +01:00
Juergen Hoeller d152259673 Clarify component scan include-filter semantics
Issue: SPR-13844
(cherry picked from commit 837cb75)
2016-01-26 20:30:34 +01:00
Juergen Hoeller 14babb78b4 Clarify environment property precedence rules
Issue: SPR-13845
(cherry picked from commit ebad8db)
2016-01-26 20:30:05 +01:00
Juergen Hoeller 4fc6ead548 SessionDisconnectEvent actually preserves given session user
Issue: SPR-13871
(cherry picked from commit cdc9bf7)
2016-01-26 20:29:08 +01:00
Juergen Hoeller c1f233c787 Shared EntityManager does not insist on actualTransactionActive flag anymore
Issue: SPR-13838
(cherry picked from commit 50829c9)
2016-01-26 20:28:07 +01:00
Juergen Hoeller 77b8f4d6af ImportStack extends ArrayDeque instead of Stack and relies on standard contains implementation
Issue: SPR-13852
(cherry picked from commit e14c2de)
2016-01-26 20:27:28 +01:00
Juergen Hoeller 8516de62e3 FastByteArrayInputStream consistently returns -1 when no data available
Issue: SPR-13858
(cherry picked from commit 5d4547d)
2016-01-26 20:26:44 +01:00
Brian Clozel bcebc9db7e Register prefixed path patterns with FixedVersionStrategy
Prior to this change, configuring a `FixedVersionStrategy` like so
would configure a single "/js/**" path pattern:

```
versionResourceResolver.addFixedVersionStrategy("v1.0.0","/js/**");
```

This commit makes sure that for each path pattern, its prefixed version
is added to the map. For example, the previous configuration also
adds "/v1.0.0/js/**".

Issue: SPR-13883
cherry-picked from 84fe46cd
2016-01-22 19:03:52 +01:00
Brian Clozel fc34b0c592 Reorder HTTP headers processing in RequestMappingHandlerAdapter
Prior to this change, the `RequestMappingHandlerAdapter` would first add
a "Cache-Control" HTTP header to the response (depending on its
`WebContentGenerator` configuration and `@SessionAttributes` on the
handler class); then, the Adapter would delegate the actual handler the
processing of the request.
This leads to issues, as the handler does not have full control to the
response and has to deal with pre-existing headers in the response. This
means that the Adapter and the handler can add incompatible
Cache-Control directives without knowing it, since one cannot see the
headers added by the other until the response is committed.

This commit switches the order of execution: first, the handler is
called (possibly adding HTTP headers), then the RMHA processes the
response and adds "Cache-Control" directives *only if there's no
Cache-Control header already defined*.

Issue: SPR-13867
cherry-picked from 8f1d06f19
2016-01-22 16:36:48 +01:00
Brian Clozel a4cb3cf900 Fix OutOfBoundsException in ResourceUrlEncodingFilter
Prior to this change, the `ResourceUrlEncodingFilter` would try to
lookup resources URLs as soon as the given URL would be longer than the
expected context+servlet prefix path. This can lead to
OutOfBoundsExceptions when the provided URL does not start with that
prefix and still has the required length.

This commit makes sure that all candidate URLs for resources lookup are
prefixed with the cached servlet and context path. This underlines the
fact that the `ResourceUrlEncodingFilter` does not support relative URLs
for now and delegates to the native servlet implementation in that case.

Issue: SPR-13861
cherry-picked from 2f6d86b7
2016-01-21 17:39:37 +01:00
Rossen Stoyanchev 33112df237 Fix second failing test 2016-01-20 23:13:34 -05:00
Rossen Stoyanchev e159086201 Fix failing test 2016-01-20 21:39:41 -05:00
Rossen Stoyanchev ab16adab2e Avoid double encoding URI in ServletServerHttpRequest
Issue: SPR-13876
2016-01-20 17:58:07 -05:00
Ian Chan 29692fcc21 Catch RejectedExecutionException in WebAsyncManager
Issue: SPR-13836
2016-01-14 15:50:20 -05:00
Rossen Stoyanchev 73df50db3c Fix javadoc issue in ResponseEntityExceptionHandler
Issue: SPR-13869
2016-01-14 14:28:15 -05:00
Brian Clozel 3af62bd0dd Polish
Issue: SPR-13817
(cherry picked from d681f77d)
2016-01-05 17:33:04 +01:00
Brian Clozel 1581597092 Preserve ETag HTTP header for versioned resources
Prior to this change, a resource handler chain configured with a
`VersionResourceResolver` would add the resource version to the request
attributes when serving that resource. This approach would not work when
a `CachingResourceResolver` is configured and the resource is already
cached. Indeed, that code path is not executed when the resource is
resolved from the cache.

This commit adds a new `VersionedResource` interface that's used by the
`VersionResourceResolver`, adding a `getVersion()` method that returns
the version string for that resource. This way, the version information
is cached with the resource itself and the request attributes are no
longer used for this.

Issue: SPR-13817
(cherry picked from commit 473cf9c)
2016-01-05 15:04:05 +01:00
Juergen Hoeller 84e5234eb5 Avoid getTypeForFactoryBean warn logging for lazy-init beans
Issue: SPR-13833
(cherry picked from commit 04f3181)
2015-12-31 11:52:55 +01:00
Juergen Hoeller 24e58c1ac3 Refined RequestMappingHandlerMapping bean definition
Issue: SPR-13832
(cherry picked from commit 9bffb9e)
2015-12-31 11:52:47 +01:00
holub 15da48eba5 Update SockJS client code snippet 2015-12-30 10:29:01 +01:00
Juergen Hoeller 342d760f70 Polishing
(cherry picked from commit 27c2e8c)
2015-12-29 21:51:04 +01:00
Juergen Hoeller acecda7153 Avoid sensitive Proxy.getInvocationHandler call in synthesizeAnnotation
Issue: SPR-13829
(cherry picked from commit aecb8b6)
2015-12-29 21:50:49 +01:00
Juergen Hoeller 4a863c9066 Upgrade to Undertow 1.3.11
(cherry picked from commit 873b173)
2015-12-29 11:26:52 +01:00
Juergen Hoeller 35b8696523 Polishing 2015-12-29 11:24:56 +01:00
Juergen Hoeller e1bdf5577e StatementCreatorUtils always tries getParameterType on Oracle 12c driver
Issue: SPR-13825
(cherry picked from commit e48ec4f)
2015-12-29 11:23:49 +01:00
Juergen Hoeller deae872912 Consistent use of varargs plus related polishing 2015-12-22 23:50:05 +01:00
Juergen Hoeller 36940e003d Polishing 2015-12-21 22:38:25 +01:00
Juergen Hoeller 935d714333 SimpleNamespaceContext implements all subtleties of the NamespaceContext contract
Issue: SPR-13713
(cherry picked from commit f8860e2)
2015-12-21 22:35:47 +01:00
Juergen Hoeller 9021f8fd71 Upgrade to JavaMail 1.5.5 and Hibernate ORM 5.0.6
(cherry picked from commit 06056e6)
2015-12-21 22:35:23 +01:00
Juergen Hoeller 6f2f3595e9 Backported import and declaration cleanup 2015-12-18 00:18:09 +01:00
Juergen Hoeller d59a97c101 Polishing 2015-12-18 00:02:48 +01:00
Juergen Hoeller 7344dd259c Allow for explicit spring-websocket-4.2.xsd declarations
Issue: SPR-13804
2015-12-18 00:02:14 +01:00
Juergen Hoeller f3ac64153e Correct spring-websocket-4.2 versus spring-websocket-4.1 xsd declarations
Issue: SPR-13804
(cherry picked from commit 2fd48c9)
2015-12-17 18:34:47 +01:00
Stephane Nicoll 7b35103135 Switch to 4.2.5.BUILD-SNAPSHOT 2015-12-17 12:53:44 +01:00
2707 changed files with 43877 additions and 97176 deletions
-44
View File
@@ -1,44 +0,0 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open
and welcoming community, we pledge to respect all people who contribute through reporting
issues, posting feature requests, updating documentation, submitting pull requests or
patches, and other activities.
We are committed to making participation in this project a harassment-free experience for
everyone, regardless of level of experience, gender, gender identity and expression,
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments,
commits, code, wiki edits, issues, and other contributions that are not aligned to this
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
consistently applying these principles to every aspect of managing this project. Project
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an
individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
be reviewed and investigated and will result in a response that is deemed necessary and
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
with regard to the reporter of an incident.
This Code of Conduct is adapted from the
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
+13 -8
View File
@@ -6,10 +6,6 @@ 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!_
## Code of Conduct
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.adoc).
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Take Your First Steps
### Understand the basics
@@ -33,6 +29,14 @@ 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.
### 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 Individual Contributor License Agreement (ICLA)
If you have not previously done so, please fill out and submit the
@@ -88,14 +92,15 @@ present in the framework.
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.
1. UTF-8 encoding for Java sources
1. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert
if necessary
### Add Apache license header to all new classes
```java
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -123,11 +128,11 @@ modified a file in 2015 whose header still reads:
* Copyright 2002-2011 the original author or authors.
```
Then be sure to update it to 2016 accordingly:
Then be sure to update it to 2015 accordingly:
```java
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
```
### Use @since tags for newly-added public API types and methods
-4
View File
@@ -10,10 +10,6 @@ The framework also serves as the foundation for [Spring Integration][], [Spring
and the rest of the Spring [family of projects][]. Browse the repositories under
the [Spring organization][] on GitHub for a full list.
## Code of Conduct
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.adoc).
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Downloading Artifacts
See [downloading Spring artifacts][] for Maven repository information. Unable to
use Maven or other transitive dependency management tools?
+226 -212
View File
@@ -10,10 +10,6 @@ buildscript {
}
}
plugins {
id "org.sonarqube" version "1.1"
}
ext {
linkHomepage = 'https://projects.spring.io/spring-framework'
linkCi = 'https://build.spring.io/browse/SPR'
@@ -31,55 +27,57 @@ configure(allprojects) { project ->
group = "org.springframework"
version = qualifyVersionIfNecessary(version)
ext.aspectjVersion = "1.8.9"
ext.caffeineVersion = "2.3.5"
ext.aspectjVersion = "1.8.8"
ext.eclipselinkVersion = "2.4.2"
ext.ehcacheVersion = "2.10.4"
ext.ehcacheVersion = "2.10.1"
ext.ehcachejcacheVersion = "1.0.1"
ext.ehcache3Version = "3.1.4"
ext.ejbVersion = "3.0"
ext.fileuploadVersion = "1.3.3"
ext.ehcache3Version = "3.0.0.m5"
ext.ejbApiVersion = "3.0"
ext.fileuploadVersion = "1.3.1"
ext.freemarkerVersion = "2.3.23"
ext.groovyVersion = "2.4.15"
ext.gsonVersion = "2.8.2"
ext.guavaVersion = "20.0"
ext.groovyVersion = "2.4.6"
ext.gsonVersion = "2.6.1"
ext.guavaVersion = "19.0"
ext.hamcrestVersion = "1.3"
ext.hibernate3Version = "3.6.10.Final"
ext.hibernate4Version = "4.3.11.Final"
ext.hibernate5Version = "5.2.10.Final"
ext.hibernate5Version = "5.0.8.Final"
ext.hibval4Version = "4.3.2.Final"
ext.hibval5Version = "5.2.5.Final"
ext.hsqldbVersion = "2.3.4"
ext.httpasyncVersion = "4.1.3"
ext.httpclientVersion = "4.5.5"
ext.jackson2Version = "2.8.11.1"
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
ext.javamailVersion = "1.5.6"
ext.jettyVersion = "9.3.14.v20161028" // as of 9.3.15, Jetty has hard Servlet 3.1 requirement
ext.jetty94Version = "9.4.6.v20170531" // for spring-websocket support, optimized for Jetty 9.4
ext.jodaVersion = "2.9.9"
ext.jrubyVersion = "1.7.27" // JRuby 9000 primarily supported through JSR-223 (StandardScriptFactory)
ext.hibval5Version = "5.2.4.Final"
ext.hsqldbVersion = "2.3.3"
ext.htmlunitVersion = "2.19"
ext.httpasyncVersion = "4.1.1"
ext.httpclientVersion = "4.5.1"
ext.jackson2Version = "2.6.5"
ext.jasperreportsVersion = "6.2.0"
ext.javamailVersion = "1.5.5"
ext.jettyVersion = "9.3.7.v20160115"
ext.jodaVersion = "2.9.2"
ext.jrubyVersion = "1.7.23" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
ext.jsonassertVersion = "1.2.3"
ext.jsonpathVersion = "2.1.0"
ext.jtaVersion = "1.2"
ext.junitVersion = "4.12"
ext.log4jVersion = "1.2.17"
ext.nettyVersion = "4.1.25.Final"
ext.okhttpVersion = "2.7.5"
ext.okhttp3Version = "3.8.1"
ext.openjpaVersion = "2.4.2"
ext.poiVersion = "3.14"
ext.reactorVersion = "2.0.8.RELEASE"
ext.romeVersion = "1.7.4"
ext.slf4jVersion = "1.7.21"
ext.nettyVersion = "4.0.34.Final"
ext.okhttpVersion = "2.7.4"
ext.openjpaVersion = "2.4.0"
ext.poiVersion = "3.13"
ext.protobufVersion = "2.6.1"
ext.reactorVersion = "2.0.7.RELEASE"
ext.romeVersion = "1.5.1"
ext.seleniumVersion = "2.48.2"
ext.slf4jVersion = "1.7.16"
ext.snakeyamlVersion = "1.17"
ext.snifferVersion = "1.16"
ext.snifferVersion = "1.14"
ext.testngVersion = "6.9.10"
ext.tiles2Version = "2.2.2"
ext.tiles3Version = "3.0.7"
ext.tomcatVersion = "8.5.31"
ext.tiles3Version = "3.0.5"
ext.tomcatVersion = "8.0.32"
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
ext.undertowVersion = "1.3.33.Final"
ext.undertowVersion = "1.3.18.Final"
ext.woodstoxVersion = "5.0.1"
ext.xmlunitVersion = "1.6"
ext.xstreamVersion = "1.4.9"
ext.xstreamVersion = "1.4.8"
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
@@ -111,13 +109,11 @@ configure(allprojects) { project ->
compileJava {
sourceCompatibility = 1.6
targetCompatibility = 1.6
options.encoding = 'UTF-8'
}
compileTestJava {
sourceCompatibility = 1.8
targetCompatibility = 1.8
options.encoding = 'UTF-8'
options.compilerArgs += "-parameters"
}
@@ -134,6 +130,8 @@ configure(allprojects) { project ->
repositories {
maven { url "https://repo.spring.io/libs-release" }
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } // reactor 2.0.6 snapshot
}
dependencies {
@@ -199,13 +197,13 @@ configure(allprojects) { project ->
"http://portals.apache.org/pluto/portlet-2.0-apidocs/",
"http://tiles.apache.org/tiles-request/apidocs/",
"http://tiles.apache.org/framework/apidocs/",
"http://aopalliance.sourceforge.net/doc/",
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"http://ehcache.org/apidocs/${ehcacheVersion}",
"http://ehcache.org/apidocs/${ehcache3Version}",
"http://quartz-scheduler.org/api/2.2.1/",
"http://fasterxml.github.io/jackson-core/javadoc/2.8/",
"http://fasterxml.github.io/jackson-databind/javadoc/2.8/",
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.8/",
"http://ehcache.org/apidocs/",
"http://quartz-scheduler.org/api/2.2.0/",
"http://fasterxml.github.com/jackson-core/javadoc/2.3.0/",
"http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/",
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.3.0/",
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/"
] as String[]
}
@@ -217,12 +215,13 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
configurations {
jacoco
}
dependencies {
jacoco("org.jacoco:org.jacoco.agent:0.7.5.201505241946:runtime")
jacoco("org.jacoco:org.jacoco.agent:0.7.1.201405082137:runtime")
}
gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(':sonarqube')) {
if (taskGraph.hasTask(':sonarRunner')) {
test.jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=org.springframework.*"
}
}
@@ -250,16 +249,16 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
options.links(project.ext.javadocLinks)
options.addStringOption('Xdoclint:none', '-quiet')
// Suppress warnings due to cross-module @see and @link references.
// Note that global 'api' task does display all warnings.
// suppress warnings due to cross-module @see and @link references;
// note that global 'api' task does display all warnings.
logging.captureStandardError LogLevel.INFO
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
// Don't include or exclude anything explicitly by default. See SPR-12085.
// don't include or exclude anything explicitly by default. See SPR-12085.
}
task javadocJar(type: Jar) {
@@ -275,7 +274,6 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
project("spring-build-src") {
description = "Exposes gradle buildSrc for IDE support"
apply plugin: "groovy"
dependencies {
@@ -289,12 +287,12 @@ project("spring-build-src") {
project("spring-core") {
description = "Spring Core"
// As of Spring 4.0.3, spring-core includes asm 5.x and repackages cglib 3.2, inlining
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.x and is therefore
// As of Spring 4.0.3, spring-core includes asm 5.0 and repackages cglib 3.2, inlining
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.0 and is therefore
// further transformed by the JarJar task to depend on org.springframework.asm; this
// avoids including two different copies of asm unnecessarily.
def cglibVersion = "3.2.6"
def objenesisVersion = "2.6"
def cglibVersion = "3.2.0"
def objenesisVersion = "2.2"
configurations {
jarjar
@@ -314,9 +312,9 @@ project("spring-core") {
configurations.cglib.each { originalJar ->
zipfileset(src: originalJar)
}
// Repackage net.sf.cglib => org.springframework.cglib
// repackage net.sf.cglib => org.springframework.cglib
rule(pattern: "net.sf.cglib.**", result: "org.springframework.cglib.@1")
// As mentioned above, transform cglib's internal asm dependencies from
// as mentioned above, transform cglib"s internal asm dependencies from
// org.objectweb.asm => org.springframework.asm. Doing this counts on the
// the fact that Spring and cglib depend on the same version of asm!
rule(pattern: "org.objectweb.asm.**", result: "org.springframework.asm.@1")
@@ -337,7 +335,7 @@ project("spring-core") {
configurations.objenesis.each { originalJar ->
zipfileset(src: originalJar)
}
// Repackage org.objenesis => org.springframework.objenesis
// repackage org.objenesis => org.springframework.objenesis
rule(pattern: "org.objenesis.**", result: "org.springframework.objenesis.@1")
}
}
@@ -354,17 +352,17 @@ project("spring-core") {
compile("commons-logging:commons-logging:1.2")
optional("commons-codec:commons-codec:1.10")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("net.sf.jopt-simple:jopt-simple:5.0.3")
optional("log4j:log4j:${log4jVersion}")
optional("net.sf.jopt-simple:jopt-simple:4.9")
optional("log4j:log4j:1.2.17")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.3") {
testCompile("com.fasterxml.woodstox:woodstox-core:${woodstoxVersion}") {
exclude group: "stax", module: "stax-api"
}
}
jar {
// Inline repackaged cglib classes directly into spring-core jar
// inline repackaged cglib classes directly into the spring-core jar
dependsOn cglibRepackJar
from(zipTree(cglibRepackJar.archivePath)) {
include "org/springframework/cglib/**"
@@ -386,14 +384,13 @@ project("spring-beans") {
optional("javax.inject:javax.inject:1")
optional("javax.el:javax.el-api:2.2.5")
optional("org.yaml:snakeyaml:${snakeyamlVersion}")
testCompile("log4j:log4j:${log4jVersion}")
testCompile("log4j:log4j:1.2.17")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
}
}
}
project("spring-beans-groovy") {
description "Groovy Bean Definitions"
merge.into = project(":spring-beans")
apply plugin: "groovy"
@@ -402,8 +399,8 @@ project("spring-beans-groovy") {
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
}
// This module's Java and Groovy sources need to be compiled together.
compileJava.enabled = false
// this module's Java and Groovy sources need to be compiled together
compileJava.enabled=false
sourceSets {
main {
groovy {
@@ -426,6 +423,7 @@ project("spring-aop") {
compile(project(":spring-core"))
compile(files(project(":spring-core").cglibRepackJar))
compile(files(project(":spring-core").objenesisRepackJar))
compile("aopalliance:aopalliance:1.0")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("commons-pool:commons-pool:1.6")
optional("org.apache.commons:commons-pool2:2.4.2")
@@ -469,74 +467,42 @@ project("spring-instrument-tomcat") {
project("spring-context") {
description = "Spring Context"
apply plugin: "groovy"
dependencies {
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-expression"))
compile(project(":spring-core"))
compile(files(project(":spring-core").cglibRepackJar))
optional(project(":spring-instrument"))
optional("javax.inject:javax.inject:1")
optional("javax.ejb:ejb-api:${ejbVersion}")
optional("javax.ejb:ejb-api:${ejbApiVersion}")
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
optional("javax.money:money-api:1.0.1")
optional("javax.money:money-api:1.0")
optional("org.eclipse.persistence:javax.persistence:2.0.0")
optional("javax.validation:validation-api:1.0.0.GA")
optional("org.hibernate:hibernate-validator:${hibval4Version}")
optional("joda-time:joda-time:${jodaVersion}")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.beanshell:bsh:2.0b5")
optional("org.beanshell:bsh:2.0b4")
optional("org.jruby:jruby:${jrubyVersion}")
testCompile("javax.inject:javax.inject-tck:1")
testCompile("org.javamoney:moneta:1.1")
testCompile("org.javamoney:moneta:1.0")
testCompile("commons-dbcp:commons-dbcp:1.4")
testCompile("org.apache.commons:commons-pool2:2.4.2")
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
}
}
project("spring-oxm") {
description = "Spring Object/XML Marshalling"
apply from: "oxm.gradle"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional("org.codehaus.castor:castor-xml:1.4.1") {
exclude group: 'stax', module: 'stax-api'
exclude group: "org.springframework", module: "spring-context"
}
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
exclude group: 'stax', module: 'stax-api'
}
optional("com.thoughtworks.xstream:xstream:${xstreamVersion}") {
exclude group: 'xpp3', module: 'xpp3_min'
exclude group: 'xmlpull', module: 'xmlpull'
}
optional("org.jibx:jibx-run:1.2.6")
testCompile(project(":spring-context"))
testCompile("org.ogce:xpp3:1.1.6")
testCompile("org.codehaus.jettison:jettison:1.3.8") {
exclude group: 'stax', module: 'stax-api'
}
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile(files(genCastor.classesDir).builtBy(genCastor))
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
}
}
project("spring-messaging") {
description = "Spring Messaging"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-context"))
optional(project(":spring-oxm"))
optional("io.projectreactor:reactor-core:${reactorVersion}")
optional("io.projectreactor:reactor-net:${reactorVersion}") {
@@ -562,9 +528,10 @@ project("spring-messaging") {
}
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
testCompile("io.netty:netty-all:${nettyVersion}")
testCompile("commons-dbcp:commons-dbcp:1.4")
testCompile("log4j:log4j:${log4jVersion}")
testCompile("log4j:log4j:1.2.17")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
}
@@ -578,13 +545,58 @@ project("spring-tx") {
compile(project(":spring-core"))
optional(project(":spring-aop"))
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
optional("aopalliance:aopalliance:1.0")
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
optional("javax.resource:connector-api:1.5")
optional("javax.ejb:ejb-api:${ejbVersion}")
optional("javax.ejb:ejb-api:${ejbApiVersion}")
optional("com.ibm.websphere:uow:6.0.2.17")
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile("org.eclipse.persistence:javax.persistence:2.0.0")
testCompile("org.codehaus.groovy:groovy-all:${groovyVersion}")
}
}
project("spring-oxm") {
description = "Spring Object/XML Marshalling"
apply from: "oxm.gradle"
compileTestJava {
// necessary to avoid java.lang.VerifyError on jibx compilation
// see http://jira.codehaus.org/browse/JIBX-465
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
if (!System.getProperty("java.version").contains("1.8.")) {
// necessary because castor and xjc tasks cannot find the JDK's compiler on JDK 9
compileTestJava.enabled = false
}
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional("org.codehaus.castor:castor-xml:1.4.0") {
exclude group: 'stax', module: 'stax-api'
exclude group: "org.springframework", module: "spring-context"
}
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
exclude group: 'stax', module: 'stax-api'
}
optional("com.thoughtworks.xstream:xstream:${xstreamVersion}") {
exclude group: 'xpp3', module: 'xpp3_min'
exclude group: 'xmlpull', module: 'xmlpull'
}
optional("org.jibx:jibx-run:1.2.6")
testCompile(project(":spring-context"))
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("xpp3:xpp3:1.1.4c")
testCompile("org.codehaus.jettison:jettison:1.3.7") {
exclude group: 'stax', module: 'stax-api'
}
if (compileTestJava.enabled) {
testCompile(files(genCastor.classesDir).builtBy(genCastor))
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
}
}
}
@@ -592,14 +604,15 @@ project("spring-jms") {
description = "Spring JMS"
dependencies {
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-aop"))
compile(project(":spring-context"))
compile(project(":spring-messaging"))
compile(project(":spring-tx"))
provided("javax.jms:jms-api:1.1-rev-1")
optional(project(":spring-oxm"))
optional("aopalliance:aopalliance:1.0")
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
optional("javax.resource:connector-api:1.5")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
@@ -617,9 +630,9 @@ project("spring-jdbc") {
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
optional("com.mchange:c3p0:0.9.5.2")
optional("org.hsqldb:hsqldb:${hsqldbVersion}")
optional("com.h2database:h2:1.4.193")
optional("org.apache.derby:derby:10.13.1.1")
optional("org.apache.derby:derbyclient:10.13.1.1")
optional("com.h2database:h2:1.4.190")
optional("org.apache.derby:derby:10.12.1.1")
optional("org.apache.derby:derbyclient:10.12.1.1")
}
}
@@ -627,17 +640,16 @@ project("spring-context-support") {
description = "Spring Context Support"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.mail:javax.mail-api:${javamailVersion}")
optional("javax.cache:cache-api:1.0.0")
optional("com.google.guava:guava:${guavaVersion}")
optional("com.github.ben-manes.caffeine:caffeine:${caffeineVersion}")
optional("net.sf.ehcache:ehcache:${ehcacheVersion}")
optional("org.quartz-scheduler:quartz:2.2.3")
optional("org.quartz-scheduler:quartz:2.2.2")
optional("org.codehaus.fabric3.api:commonj:1.1.0")
optional("org.apache.velocity:velocity:1.7")
optional("org.freemarker:freemarker:${freemarkerVersion}")
@@ -658,14 +670,11 @@ project("spring-context-support") {
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
testRuntime("org.ehcache:jcache:${ehcachejcacheVersion}")
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
testRuntime("org.terracotta:management-model:2.3.0")
}
}
project("spring-web") {
description = "Spring Web"
apply plugin: "groovy"
// Re-generate Protobuf classes from *.proto files and move them in test sources
@@ -695,6 +704,7 @@ project("spring-web") {
optional("javax.el:javax.el-api:2.2.5")
optional("javax.faces:javax.faces-api:2.2")
optional("javax.validation:validation-api:1.0.0.GA")
optional("aopalliance:aopalliance:1.0")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("com.caucho:hessian:4.0.38")
optional("commons-fileupload:commons-fileupload:${fileuploadVersion}")
@@ -702,9 +712,8 @@ project("spring-web") {
optional("org.apache.httpcomponents:httpasyncclient:${httpasyncVersion}")
optional("io.netty:netty-all:${nettyVersion}")
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
optional("com.squareup.okhttp3:okhttp:${okhttp3Version}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
optional("com.google.code.gson:gson:${gsonVersion}")
optional("com.rometools:rome:${romeVersion}")
optional("org.eclipse.jetty:jetty-servlet:${jettyVersion}") {
@@ -713,25 +722,69 @@ project("spring-web") {
optional("org.eclipse.jetty:jetty-server:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet-api"
}
optional("log4j:log4j:${log4jVersion}")
optional("com.google.protobuf:protobuf-java:2.6.1")
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
optional("log4j:log4j:1.2.17")
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.2")
optional("com.google.protobuf:protobuf-java:${protobufVersion}")
optional("javax.mail:javax.mail-api:${javamailVersion}")
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("org.skyscreamer:jsonassert:1.4.0")
testCompile("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
}
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.8.11")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.11")
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson2Version}")
testCompile("com.squareup.okhttp3:mockwebserver:${okhttp3Version}")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson2Version}")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk7:${jackson2Version}")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2Version}")
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
}
}
project("spring-websocket") {
description = "Spring WebSocket"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-context"))
compile(project(":spring-web"))
optional(project(":spring-messaging"))
optional(project(":spring-webmvc"))
optional("javax.servlet:javax.servlet-api:3.1.0")
optional("javax.websocket:javax.websocket-api:1.0")
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
}
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
optional("io.undertow:undertow-core:${undertowVersion}")
optional("io.undertow:undertow-servlet:${undertowVersion}") {
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
}
optional("io.undertow:undertow-websockets-jsr:${undertowVersion}") {
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
}
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
testCompile("io.projectreactor:reactor-net:${reactorVersion}")
testCompile("io.netty:netty-all:${nettyVersion}")
testCompile("log4j:log4j:1.2.17")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
project("spring-orm") {
description = "Spring Object/Relational Mapping"
@@ -743,6 +796,7 @@ project("spring-orm") {
optional(project(":spring-aop"))
optional(project(":spring-context"))
optional(project(":spring-web"))
optional("aopalliance:aopalliance:1.0")
optional("org.eclipse.persistence:javax.persistence:2.0.5")
optional("org.eclipse.persistence:org.eclipse.persistence.core:${eclipselinkVersion}")
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipselinkVersion}") {
@@ -783,6 +837,7 @@ project("spring-orm-hibernate4") {
optional("org.hibernate:hibernate-core:${hibernate4Version}")
optional("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
optional("javax.servlet:javax.servlet-api:3.0.1")
optional("aopalliance:aopalliance:1.0")
testCompile("javax.validation:validation-api:1.1.0.GA")
testCompile("org.hibernate:hibernate-validator:${hibval5Version}")
testCompile("javax.el:javax.el-api:2.2.5")
@@ -799,8 +854,10 @@ project("spring-orm-hibernate5") {
provided(project(":spring-tx"))
optional(project(":spring-web"))
optional("org.hibernate:hibernate-core:${hibernate5Version}")
optional("org.hibernate:hibernate-entitymanager:${hibernate5Version}")
optional("javax.servlet:javax.servlet-api:3.0.1")
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
optional("aopalliance:aopalliance:1.0")
}
}
@@ -808,14 +865,13 @@ project("spring-webmvc") {
description = "Spring Web MVC"
dependencies {
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(files(project(":spring-core").objenesisRepackJar))
compile(project(":spring-expression"))
compile(project(":spring-web"))
provided("javax.servlet:javax.servlet-api:3.1.0")
provided("javax.servlet:javax.servlet-api:3.0.1")
optional(project(":spring-context-support")) // for Velocity support
optional(project(":spring-oxm")) // for MarshallingView
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
@@ -837,7 +893,7 @@ project("spring-webmvc") {
exclude group: "org.springframework", module: "spring-context"
}
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
optional("com.rometools:rome:${romeVersion}")
optional("javax.el:javax.el-api:2.2.5")
optional("org.apache.tiles:tiles-api:${tiles3Version}")
@@ -857,7 +913,9 @@ project("spring-webmvc") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
exclude group: "org.springframework", module: "spring-web"
}
optional('org.webjars:webjars-locator:0.32-1')
optional('org.webjars:webjars-locator:0.28')
testCompile(project(":spring-aop"))
testCompile("rhino:js:1.7R1")
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("dom4j:dom4j:1.6.1") {
exclude group: "xml-apis", module: "xml-apis"
@@ -877,13 +935,12 @@ project("spring-webmvc") {
testCompile("org.hibernate:hibernate-validator:${hibval4Version}")
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
testCompile("commons-fileupload:commons-fileupload:${fileuploadVersion}")
testCompile("commons-io:commons-io:1.4")
testCompile("commons-io:commons-io:1.3")
testCompile("joda-time:joda-time:${jodaVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("org.mozilla:rhino:1.7.7.2")
testRuntime("org.jruby:jruby:${jrubyVersion}")
testRuntime("org.python:jython-standalone:2.5.3")
testRuntime("org.webjars:underscorejs:1.8.3")
testCompile("org.jruby:jruby:${jrubyVersion}")
testCompile("org.python:jython-standalone:2.5.3")
testCompile("org.webjars:underscorejs:1.8.3")
}
}
@@ -934,66 +991,19 @@ project("spring-webmvc-portlet") {
}
}
project("spring-websocket") {
description = "Spring WebSocket"
dependencies {
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-web"))
optional(project(":spring-messaging"))
optional(project(":spring-webmvc"))
optional("javax.servlet:javax.servlet-api:3.1.0")
optional("javax.websocket:javax.websocket-api:1.0")
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
}
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-server:${jetty94Version}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-client:${jetty94Version}")
optional("org.eclipse.jetty:jetty-client:${jetty94Version}")
optional("io.undertow:undertow-core:${undertowVersion}")
optional("io.undertow:undertow-servlet:${undertowVersion}") {
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
}
optional("io.undertow:undertow-websockets-jsr:${undertowVersion}") {
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
}
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
testCompile("io.projectreactor:reactor-net:${reactorVersion}")
testCompile("io.netty:netty-all:${nettyVersion}")
testCompile("log4j:log4j:${log4jVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
project("spring-test") {
description = "Spring TestContext Framework"
dependencies {
compile(project(":spring-core"))
optional(project(":spring-aop"))
optional(project(":spring-beans"))
optional(project(":spring-context"))
optional(project(":spring-jdbc"))
optional(project(":spring-orm"))
optional(project(":spring-tx"))
optional(project(":spring-orm"))
optional(project(":spring-web"))
optional(project(":spring-webmvc"))
optional(project(":spring-webmvc-portlet"))
optional(project(":spring-websocket"))
optional("junit:junit:${junitVersion}")
optional("org.testng:testng:${testngVersion}")
optional("javax.inject:javax.inject:1")
@@ -1005,20 +1015,18 @@ project("spring-test") {
}
optional("javax.portlet:portlet-api:2.0")
optional("javax.el:javax.el-api:2.2.5")
optional("javax.websocket:javax.websocket-api:1.0")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.hamcrest:hamcrest-core:${hamcrestVersion}")
optional("com.jayway.jsonpath:json-path:${jsonpathVersion}")
optional("org.skyscreamer:jsonassert:${jsonassertVersion}")
optional("xmlunit:xmlunit:${xmlunitVersion}")
optional("net.sourceforge.htmlunit:htmlunit:2.23")
optional("org.seleniumhq.selenium:htmlunit-driver:2.23.2")
optional("org.seleniumhq.selenium:selenium-java:2.53.1")
optional("org.skyscreamer:jsonassert:1.4.0")
optional("com.jayway.jsonpath:json-path:2.3.0")
optional("net.sourceforge.htmlunit:htmlunit:${htmlunitVersion}")
optional("org.seleniumhq.selenium:selenium-htmlunit-driver:${seleniumVersion}")
testCompile(project(":spring-context-support"))
testCompile(project(":spring-oxm"))
testCompile("javax.mail:javax.mail-api:${javamailVersion}")
testCompile("javax.ejb:ejb-api:${ejbVersion}")
testCompile("javax.ejb:ejb-api:${ejbApiVersion}")
testCompile("org.hibernate:hibernate-core:${hibernate4Version}")
testCompile("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
testCompile("org.hibernate:hibernate-validator:${hibval5Version}")
@@ -1036,7 +1044,8 @@ project("spring-test") {
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
testCompile("javax.cache:cache-api:1.0.0")
testRuntime("log4j:log4j:${log4jVersion}")
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
testRuntime("org.terracotta:management-model:2.0.0")
}
task testNG(type: Test) {
@@ -1071,8 +1080,8 @@ project("spring-aspects") {
dependencies {
aspects(project(":spring-orm"))
ajc("org.aspectj:aspectjtools:${aspectjVersion}")
rt("org.aspectj:aspectjrt:${aspectjVersion}")
ajc("org.aspectj:aspectjtools:1.9.0.BETA-3") // for the ability to build on JDK 9, not exposed in the POMs yet
rt("org.aspectj:aspectjrt:${aspectjVersion}") // regular AspectJ version here, to be exposed in the POMs
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
provided("org.eclipse.persistence:javax.persistence:2.0.0")
optional(project(":spring-aop")) // for @Async support
@@ -1090,7 +1099,8 @@ project("spring-aspects") {
eclipse.project {
natures += "org.eclipse.ajdt.ui.ajnature"
buildCommands = [new org.gradle.plugins.ide.eclipse.model.BuildCommand("org.eclipse.ajdt.core.ajbuilder")]
buildCommands = [new org.gradle.plugins.ide.eclipse.model.
BuildCommand("org.eclipse.ajdt.core.ajbuilder")]
}
}
@@ -1129,8 +1139,10 @@ project("spring-framework-bom") {
}
}
sonarqube {
properties {
apply plugin: 'sonar-runner'
sonarRunner {
sonarProperties {
property "sonar.projectName", "Spring Framework"
property "sonar.profile", "Spring Framework"
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
@@ -1158,7 +1170,9 @@ configure(rootProject) {
separateOutputDirs = false
backends = ['docbook']
options doctype: 'book', eruby: 'erubis'
attributes 'spring-version': project.version, 'revnumber': project.version, 'docinfo': ""
attributes 'spring-version': project.version,
'revnumber' : project.version,
'docinfo' : ""
}
reference {
@@ -1181,7 +1195,7 @@ configure(rootProject) {
// don't publish the default jar for the root project
configurations.archives.artifacts.clear()
dependencies { // for integration tests
dependencies { // for integration tests
testCompile(project(":spring-aop"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-context"))
@@ -1230,11 +1244,11 @@ configure(rootProject) {
doFirst {
classpath = files(
// Ensure Servlet 3.x and Hibernate 4.x have precedence on the javadoc
// ensure Servlet 3.x and Hibernate 4.x have precedence on the javadoc
// classpath over their respective 2.5 and 3.x variants
project(":spring-webmvc").sourceSets.main.compileClasspath.files.find { it =~ "servlet-api" },
rootProject.sourceSets.test.compileClasspath.files.find { it =~ "hibernate-core" },
// Ensure the javadoc process can resolve types compiled from .aj sources
// ensure the javadoc process can resolve types compiled from .aj sources
project(":spring-aspects").sourceSets.main.output
)
classpath += files(subprojects.collect { it.sourceSets.main.compileClasspath })
@@ -1294,7 +1308,7 @@ configure(rootProject) {
baseName = "spring-framework"
classifier = "dist"
description = "Builds -${classifier} archive, containing all jars and docs, " +
"suitable for community download page."
"suitable for community download page."
ext.baseDir = "${baseName}-${project.version}";
@@ -1367,7 +1381,7 @@ configure(rootProject) {
task wrapper(type: Wrapper) {
description = "Generates gradlew[.bat] scripts"
gradleVersion = "2.14.1"
gradleVersion = "2.5"
doLast() {
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
@@ -1384,14 +1398,14 @@ configure(rootProject) {
}
configure([project(':spring-build-src'), project(':spring-framework-bom')]) {
sonarqube {
sonarRunner {
skipProject = true
}
}
configure(project(':spring-core')) {
sonarqube {
properties {
sonarRunner {
sonarProperties {
property "sonar.exclusions",
"src/main/java/org/springframework/cglib/**/*,src/main/java/org/springframework/asm/**/*"
}
+1 -1
View File
@@ -1 +1 @@
version=4.3.18.RELEASE
version=4.2.5.RELEASE
+2 -2
View File
@@ -29,8 +29,8 @@ def customizePom(pom, gradleProject) {
}
licenses {
license {
name "Apache License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0"
name "The Apache Software License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
distribution "repo"
}
}
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
#Wed Aug 17 21:21:18 CEST 2016
#Thu Jul 09 16:54:55 EEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip
Vendored
+27 -27
View File
@@ -6,31 +6,13 @@
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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"
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -49,7 +31,6 @@ die ( ) {
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -60,11 +41,31 @@ case "`uname`" in
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -90,7 +91,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,7 +115,6 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
Vendored
+5 -5
View File
@@ -8,15 +8,15 @@
@rem Set local scope for the variables with windows NT shell
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 DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -47,7 +47,7 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
+3 -3
View File
@@ -29,8 +29,8 @@ REM - generates OXM test classes to avoid errors on import into Eclipse
REM - generates metadata for all subprojects
REM - skips metadata gen for the root project (-x :eclipse) to work
REM around Eclipse's inability to import hierarchical project structures
REM SET COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
SET COMMAND=gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
REM SET COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
SET COMMAND=gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
echo.
echo -----------------------------------------------------------------------
@@ -69,7 +69,7 @@ echo When the above is complete, return here and press the enter key.
pause
set COMMAND=gradlew --no-daemon :eclipse
set COMMAND=gradlew :eclipse
echo.
echo -----------------------------------------------------------------------
+2 -2
View File
@@ -42,7 +42,7 @@ read
# - generates metadata for all subprojects
# - skips metadata gen for the root project (-x :eclipse) to work
# around Eclipse's inability to import hierarchical project structures
COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
cat <<EOM
@@ -84,7 +84,7 @@ EOM
read
COMMAND="./gradlew --no-daemon :eclipse"
COMMAND="./gradlew :eclipse"
cat <<EOM
@@ -1,28 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.aop;
/**
* Tag interface for Advice. Implementations can be any type
* of advice, such as Interceptors.
*
* @author Rod Johnson
* @version $Id: Advice.java,v 1.1 2004/03/19 17:02:16 johnsonr Exp $
*/
public interface Advice {
}
@@ -1,48 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.aop;
/**
* Superclass for all AOP infrastructure exceptions.
* Unchecked, as such exceptions are fatal and end user
* code shouldn't be forced to catch them.
*
* @author Rod Johnson
* @author Bob Lee
* @author Juergen Hoeller
*/
@SuppressWarnings("serial")
public class AspectException extends RuntimeException {
/**
* Constructor for AspectException.
* @param message the exception message
*/
public AspectException(String message) {
super(message);
}
/**
* Constructor for AspectException.
* @param message the exception message
* @param cause the root cause, if any
*/
public AspectException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,59 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
/**
* Intercepts the construction of a new object.
*
* <p>The user should implement the {@link
* #construct(ConstructorInvocation)} method to modify the original
* behavior. E.g. the following class implements a singleton
* interceptor (allows only one unique instance for the intercepted
* class):
*
* <pre class=code>
* class DebuggingInterceptor implements ConstructorInterceptor {
* Object instance=null;
*
* Object construct(ConstructorInvocation i) throws Throwable {
* if(instance==null) {
* return instance=i.proceed();
* } else {
* throw new Exception("singleton does not allow multiple instance");
* }
* }
* }
* </pre>
*
* @author Rod Johnson
*/
public interface ConstructorInterceptor extends Interceptor {
/**
* Implement this method to perform extra treatments before and
* after the construction of a new object. Polite implementations
* would certainly like to invoke {@link Joinpoint#proceed()}.
* @param invocation the construction joinpoint
* @return the newly created object, which is also the result of
* the call to {@link Joinpoint#proceed()}; might be replaced by
* the interceptor
* @throws Throwable if the interceptors or the target object
* throws an exception
*/
Object construct(ConstructorInvocation invocation) throws Throwable;
}
@@ -1,41 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
import java.lang.reflect.Constructor;
/**
* Description of an invocation to a constuctor, given to an
* interceptor upon constructor-call.
*
* <p>A constructor invocation is a joinpoint and can be intercepted
* by a constructor interceptor.
*
* @author Rod Johnson
* @see ConstructorInterceptor
*/
public interface ConstructorInvocation extends Invocation {
/**
* Get the constructor being called.
* <p>This method is a friendly implementation of the
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the constructor being called
*/
Constructor<?> getConstructor();
}
@@ -1,69 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
import org.aopalliance.aop.Advice;
/**
* This interface represents a generic interceptor.
*
* <p>A generic interceptor can intercept runtime events that occur
* within a base program. Those events are materialized by (reified
* in) joinpoints. Runtime joinpoints can be invocations, field
* access, exceptions...
*
* <p>This interface is not used directly. Use the sub-interfaces
* to intercept specific events. For instance, the following class
* implements some specific interceptors in order to implement a
* debugger:
*
* <pre class=code>
* class DebuggingInterceptor implements MethodInterceptor,
* ConstructorInterceptor, FieldInterceptor {
*
* Object invoke(MethodInvocation i) throws Throwable {
* debug(i.getMethod(), i.getThis(), i.getArgs());
* return i.proceed();
* }
*
* Object construct(ConstructorInvocation i) throws Throwable {
* debug(i.getConstructor(), i.getThis(), i.getArgs());
* return i.proceed();
* }
*
* Object get(FieldAccess fa) throws Throwable {
* debug(fa.getField(), fa.getThis(), null);
* return fa.proceed();
* }
*
* Object set(FieldAccess fa) throws Throwable {
* debug(fa.getField(), fa.getThis(), fa.getValueToSet());
* return fa.proceed();
* }
*
* void debug(AccessibleObject ao, Object this, Object value) {
* ...
* }
* }
* </pre>
*
* @author Rod Johnson
* @see Joinpoint
*/
public interface Interceptor extends Advice {
}
@@ -1,37 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
/**
* This interface represents an invocation in the program.
*
* <p>An invocation is a joinpoint and can be intercepted by an
* interceptor.
*
* @author Rod Johnson
*/
public interface Invocation extends Joinpoint {
/**
* Get the arguments as an array object.
* It is possible to change element values within this
* array to change the arguments.
* @return the argument of the invocation
*/
Object[] getArguments();
}
@@ -1,65 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
import java.lang.reflect.AccessibleObject;
/**
* This interface represents a generic runtime joinpoint (in the AOP
* terminology).
*
* <p>A runtime joinpoint is an <i>event</i> that occurs on a static
* joinpoint (i.e. a location in a the program). For instance, an
* invocation is the runtime joinpoint on a method (static joinpoint).
* The static part of a given joinpoint can be generically retrieved
* using the {@link #getStaticPart()} method.
*
* <p>In the context of an interception framework, a runtime joinpoint
* is then the reification of an access to an accessible object (a
* method, a constructor, a field), i.e. the static part of the
* joinpoint. It is passed to the interceptors that are installed on
* the static joinpoint.
*
* @author Rod Johnson
* @see Interceptor
*/
public interface Joinpoint {
/**
* Proceed to the next interceptor in the chain.
* <p>The implementation and the semantics of this method depends
* on the actual joinpoint type (see the children interfaces).
* @return see the children interfaces' proceed definition
* @throws Throwable if the joinpoint throws an exception
*/
Object proceed() throws Throwable;
/**
* Return the object that holds the current joinpoint's static part.
* <p>For instance, the target object for an invocation.
* @return the object (can be null if the accessible object is static)
*/
Object getThis();
/**
* Return the static part of this joinpoint.
* <p>The static part is an accessible object on which a chain of
* interceptors are installed.
*/
AccessibleObject getStaticPart();
}
@@ -1,56 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
/**
* Intercepts calls on an interface on its way to the target. These
* are nested "on top" of the target.
*
* <p>The user should implement the {@link #invoke(MethodInvocation)}
* method to modify the original behavior. E.g. the following class
* implements a tracing interceptor (traces all the calls on the
* intercepted method(s)):
*
* <pre class=code>
* class TracingInterceptor implements MethodInterceptor {
* Object invoke(MethodInvocation i) throws Throwable {
* System.out.println("method "+i.getMethod()+" is called on "+
* i.getThis()+" with args "+i.getArguments());
* Object ret=i.proceed();
* System.out.println("method "+i.getMethod()+" returns "+ret);
* return ret;
* }
* }
* </pre>
*
* @author Rod Johnson
*/
public interface MethodInterceptor extends Interceptor {
/**
* Implement this method to perform extra treatments before and
* after the invocation. Polite implementations would certainly
* like to invoke {@link Joinpoint#proceed()}.
* @param invocation the method invocation joinpoint
* @return the result of the call to {@link Joinpoint#proceed()};
* might be intercepted by the interceptor
* @throws Throwable if the interceptors or the target object
* throws an exception
*/
Object invoke(MethodInvocation invocation) throws Throwable;
}
@@ -1,41 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aopalliance.intercept;
import java.lang.reflect.Method;
/**
* Description of an invocation to a method, given to an interceptor
* upon method-call.
*
* <p>A method invocation is a joinpoint and can be intercepted by a
* method interceptor.
*
* @author Rod Johnson
* @see MethodInterceptor
*/
public interface MethodInvocation extends Invocation {
/**
* Get the method being called.
* <p>This method is a frienly implementation of the
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the method being called
*/
Method getMethod();
}
@@ -1,5 +1,5 @@
/*<
* Copyright 2002-2017 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.
@@ -34,8 +34,9 @@ public interface TargetSource extends TargetClassAware {
/**
* Return the type of targets returned by this {@link TargetSource}.
* <p>Can return {@code null}, although certain usages of a {@code TargetSource}
* might just work with a predetermined target class.
* <p>Can return {@code null}, although certain usages of a
* {@code TargetSource} might just work with a predetermined
* target class.
* @return the type of targets returned by this {@link TargetSource}
*/
@Override
@@ -43,8 +44,9 @@ public interface TargetSource extends TargetClassAware {
/**
* Will all calls to {@link #getTarget()} return the same object?
* <p>In that case, there will be no need to invoke {@link #releaseTarget(Object)},
* and the AOP framework can cache the return value of {@link #getTarget()}.
* <p>In that case, there will be no need to invoke
* {@link #releaseTarget(Object)}, and the AOP framework can cache
* the return value of {@link #getTarget()}.
* @return {@code true} if the target is immutable
* @see #getTarget
*/
@@ -53,15 +55,14 @@ public interface TargetSource extends TargetClassAware {
/**
* Return a target instance. Invoked immediately before the
* AOP framework calls the "target" of an AOP method invocation.
* @return the target object which contains the joinpoint,
* or {@code null} if there is no actual target instance
* @return the target object, which contains the joinpoint
* @throws Exception if the target object can't be resolved
*/
Object getTarget() throws Exception;
/**
* Release the given target object obtained from the
* {@link #getTarget()} method, if any.
* {@link #getTarget()} method.
* @param target object obtained from a call to {@link #getTarget()}
* @throws Exception if the object can't be released
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -58,8 +55,7 @@ import org.springframework.util.StringUtils;
* @author Ramnivas Laddad
* @since 2.0
*/
@SuppressWarnings("serial")
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation {
/**
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
@@ -90,21 +86,18 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
private final Class<?> declaringClass;
protected final Method aspectJAdviceMethod;
private final String methodName;
private final Class<?>[] parameterTypes;
protected transient Method aspectJAdviceMethod;
/** The total number of arguments we have to populate on advice dispatch */
private final int adviceInvocationArgumentCount;
private final AspectJExpressionPointcut pointcut;
private final AspectInstanceFactory aspectInstanceFactory;
/**
* The name of the aspect (ref bean) in which this advice was defined
* (used when determining advice precedence so that we can determine
* The name of the aspect (ref bean) in which this advice was defined (used
* when determining advice precedence so that we can determine
* whether two pieces of advice come from the same aspect).
*/
private String aspectName;
@@ -118,13 +111,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* This will be non-null if the creator of this advice object knows the argument names
* and sets them explicitly
*/
private String[] argumentNames;
private String[] argumentNames = null;
/** Non-null if after throwing advice binds the thrown value */
private String throwingName;
private String throwingName = null;
/** Non-null if after returning advice binds the return value */
private String returningName;
private String returningName = null;
private Class<?> discoveredReturningType = Object.class;
@@ -161,10 +154,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) {
Assert.notNull(aspectJAdviceMethod, "Advice method must not be null");
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.adviceInvocationArgumentCount = this.aspectJAdviceMethod.getParameterTypes().length;
this.pointcut = pointcut;
this.aspectInstanceFactory = aspectInstanceFactory;
}
@@ -227,7 +218,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
/**
* Set the declaration order of this advice within the aspect.
* Sets the <b>declaration order</b> of this advice within the aspect
*/
public void setDeclarationOrder(int order) {
this.declarationOrder = order;
@@ -295,8 +286,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
@@ -329,8 +320,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Throwing name '" + name +
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
@@ -366,16 +357,18 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public final synchronized void calculateArgumentBindings() {
public synchronized final void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
if (this.argumentsIntrospected || this.adviceInvocationArgumentCount == 0) {
return;
}
int numUnboundArgs = this.parameterTypes.length;
int numUnboundArgs = this.adviceInvocationArgumentCount;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0]) ||
maybeBindJoinPointStaticPart(parameterTypes[0])) {
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
@@ -469,7 +462,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
// So we match in number...
int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;
int argumentIndexOffset = this.adviceInvocationArgumentCount - numArgumentsLeftToBind;
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
this.argumentBindings.put(this.argumentNames[i], i);
}
@@ -550,7 +543,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
calculateArgumentBindings();
// AMC start
Object[] adviceInvocationArgs = new Object[this.parameterTypes.length];
Object[] adviceInvocationArgs = new Object[this.adviceInvocationArgumentCount];
int numBound = 0;
if (this.joinPointArgumentIndex != -1) {
@@ -587,8 +580,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
}
if (numBound != this.parameterTypes.length) {
throw new IllegalStateException("Required to bind " + this.parameterTypes.length +
if (numBound != this.adviceInvocationArgumentCount) {
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount +
" arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
}
@@ -671,16 +664,6 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
"aspect name '" + this.aspectName + "'";
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
try {
this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("Failed to find advice method on deserialization", ex);
}
}
/**
* MethodMatcher that excludes the specified advice method.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -113,7 +113,6 @@ import org.springframework.util.StringUtils;
* returning {@code null} in the case that the parameter names cannot be discovered.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscoverer {
@@ -155,17 +154,23 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
/** The pointcut expression associated with the advice, as a simple String */
private String pointcutExpression;
private boolean raiseExceptions;
/** If the advice is afterReturning, and binds the return value, this is the parameter name used */
/**
* If the advice is afterReturning, and binds the return value, this is the parameter name used.
*/
private String returningName;
/** If the advice is afterThrowing, and binds the thrown value, this is the parameter name used */
/**
* If the advice is afterThrowing, and binds the thrown value, this is the parameter name used.
*/
private String throwingName;
/**
* The pointcut expression associated with the advice, as a simple String.
*/
private String pointcutExpression;
private Class<?>[] argumentTypes;
private String[] parameterNameBindings;
@@ -181,7 +186,6 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.pointcutExpression = pointcutExpression;
}
/**
* Indicate whether {@link IllegalArgumentException} and {@link AmbiguousBindingException}
* must be thrown as appropriate in the case of failing to deduce advice parameter names.
@@ -209,7 +213,6 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.throwingName = throwingName;
}
/**
* Deduce the parameter names for an advice method.
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class level javadoc}
@@ -415,7 +418,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
int firstParenIndex = toMatch.indexOf('(');
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -471,7 +474,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
* If the token starts meets Java identifier conventions, it's in.
*/
private String maybeExtractVariableName(String candidateToken) {
if (!StringUtils.hasLength(candidateToken)) {
if (candidateToken == null || candidateToken.equals("")) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
@@ -575,7 +578,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
if (toMatch.startsWith("!")) {
toMatch = toMatch.substring(1);
}
int firstParenIndex = toMatch.indexOf('(');
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -30,9 +29,7 @@ import org.springframework.aop.AfterAdvice;
* @author Rod Johnson
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
public AspectJAfterAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -33,9 +32,7 @@ import org.springframework.util.TypeUtils;
* @author Ramnivas Laddad
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
implements AfterReturningAdvice, AfterAdvice, Serializable {
public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice {
public AspectJAfterReturningAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
@@ -101,7 +98,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
else if (Object.class == type && void.class == method.getReturnType()) {
return true;
}
else {
else{
return ClassUtils.isAssignable(type, method.getReturnType());
}
}
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -30,9 +29,7 @@ import org.springframework.aop.AfterAdvice;
* @author Rod Johnson
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -34,8 +33,7 @@ import org.springframework.aop.ProxyMethodInvocation;
* @author Juergen Hoeller
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor {
public AspectJAroundAdvice(
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.intercept.MethodInvocation;
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.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
@@ -186,24 +187,13 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
}
/**
* Determine the ClassLoader to use for pointcut evaluation.
*/
private ClassLoader determinePointcutClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
if (this.pointcutDeclarationScope != null) {
return this.pointcutDeclarationScope.getClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
/**
* Build the underlying AspectJ pointcut expression.
*/
@@ -268,7 +258,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
}
}
catch (Throwable ex) {
catch (BCException ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
@@ -336,6 +326,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
catch (IllegalStateException ex) {
// No current invocation...
// TODO: Should we really proceed here?
if (logger.isDebugEnabled()) {
logger.debug("Could not access current invocation - matching with limited context: " + ex);
}
@@ -422,46 +413,39 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex2) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
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);
}
}
catch (ReflectionWorldException ex2) {
catch (ReflectionWorldException ex4) {
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);
}
}
catch (ReflectionWorldException ex4) {
fallbackExpression = null;
}
}
}
}
catch (Throwable ex) {
// Possibly AspectJ 1.8.10 encountering an invalid signature
logger.debug("PointcutExpression matching rejected target method", ex);
fallbackExpression = null;
}
if (shadowMatch == null) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 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 org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractGenericPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* Spring AOP Advisor that can be used for any AspectJ pointcut expression.
@@ -28,11 +26,16 @@ import org.springframework.beans.factory.BeanFactoryAware;
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor implements BeanFactoryAware {
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor {
private final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
public void setExpression(String expression) {
this.pointcut.setExpression(expression);
}
@@ -49,22 +52,12 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
return this.pointcut.getLocation();
}
public void setParameterTypes(Class<?>[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String... names) {
this.pointcut.setParameterNames(names);
}
public void setParameterTypes(Class<?>... types) {
this.pointcut.setParameterTypes(types);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.pointcut.setBeanFactory(beanFactory);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
@@ -28,8 +27,7 @@ import org.springframework.aop.MethodBeforeAdvice;
* @author Adrian Colyer
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice {
public AspectJMethodBeforeAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -22,6 +22,7 @@ import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice}
@@ -50,11 +51,11 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
this.pointcut = advice.buildSafePointcut();
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean isPerInstance() {
return true;
@@ -90,12 +91,12 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return this.advice.equals(otherAdvisor.advice);
return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice));
}
@Override
public int hashCode() {
return AspectJPointcutAdvisor.class.hashCode() * 29 + this.advice.hashCode();
return AspectJPointcutAdvisor.class.hashCode();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInterceptor;
import org.springframework.aop.support.ClassFilters;
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
@@ -35,12 +34,12 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
*/
public class DeclareParentsAdvisor implements IntroductionAdvisor {
private final Advice advice;
private final Class<?> introducedInterface;
private final ClassFilter typePatternClassFilter;
private final Advice advice;
/**
* Create a new advisor for this DeclareParents field.
@@ -49,8 +48,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param defaultImpl the default implementation class
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
this(interfaceType, typePattern,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
this(interfaceType, typePattern, defaultImpl,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
}
/**
@@ -60,29 +59,32 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param delegateRef the delegate implementation object
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
this(interfaceType, typePattern, new DelegatingIntroductionInterceptor(delegateRef));
this(interfaceType, typePattern, delegateRef.getClass(),
new DelegatingIntroductionInterceptor(delegateRef));
}
/**
* Private constructor to share common code between impl-based delegate and reference-based delegate
* (cannot use method such as init() to share common code, due the use of final fields)
* (cannot use method such as init() to share common code, due the the use of final fields)
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param interceptor the delegation advice as {@link IntroductionInterceptor}
* @param implementationClass implementation class
* @param advice delegation advice
*/
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, IntroductionInterceptor interceptor) {
this.advice = interceptor;
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
this.introducedInterface = interfaceType;
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
// Excludes methods implemented.
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
ClassFilter exclusion = new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
return !introducedInterface.isAssignableFrom(clazz);
return !(introducedInterface.isAssignableFrom(clazz));
}
};
this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);
this.advice = advice;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,15 +32,17 @@ import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.util.Assert;
/**
* An implementation of the AspectJ {@link ProceedingJoinPoint} interface
* wrapping an AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}.
* Implementation of AspectJ ProceedingJoinPoint interface
* wrapping an AOP Alliance MethodInvocation.
*
* <p><b>Note</b>: The {@code getThis()} method returns the current Spring AOP proxy.
* <p><b>Note</b>: the {@code getThis()} method returns the current Spring AOP proxy.
* The {@code getTarget()} method returns the current Spring AOP target (which may be
* {@code null} if there is no target instance) as a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use {@code getThis()}.</b>
* A common example is casting the object to an introduced interface in the implementation of
* an introduction. There is no such distinction between target and proxy in AspectJ itself.
* {@code null} if there is no target), and is a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use
* {@code getThis()}.</b> A common example is casting the object to an
* introduced interface in the implementation of an introduction.
*
* <p>Of course there is no such distinction between target and proxy in AspectJ.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -54,7 +56,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
private final ProxyMethodInvocation methodInvocation;
private Object[] args;
private Object[] defensiveCopyOfArgs;
/** Lazily initialized signature object */
private Signature signature;
@@ -73,7 +75,6 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
this.methodInvocation = methodInvocation;
}
@Override
public void set$AroundClosure(AroundClosure aroundClosure) {
throw new UnsupportedOperationException();
@@ -114,10 +115,12 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
@Override
public Object[] getArgs() {
if (this.args == null) {
this.args = this.methodInvocation.getArguments().clone();
if (this.defensiveCopyOfArgs == null) {
Object[] argsSource = this.methodInvocation.getArguments();
this.defensiveCopyOfArgs = new Object[argsSource.length];
System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
}
return this.args;
return this.defensiveCopyOfArgs;
}
@Override
@@ -125,7 +128,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
if (this.signature == null) {
this.signature = new MethodSignatureImpl();
}
return this.signature;
return signature;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,6 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
this.aspectClass = aspectClass;
}
/**
* Return the specified aspect class (never {@code null}).
*/
@@ -49,18 +48,17 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
return this.aspectClass;
}
@Override
public final Object getAspectInstance() {
try {
return this.aspectClass.newInstance();
}
catch (InstantiationException ex) {
throw new AopConfigException(
"Unable to instantiate aspect class: " + this.aspectClass.getName(), ex);
throw new AopConfigException("Unable to instantiate aspect class [" + this.aspectClass.getName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException(
"Could not access aspect constructor: " + this.aspectClass.getName(), ex);
throw new AopConfigException("Cannot access element class [" + this.aspectClass.getName() + "]", ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 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.
@@ -16,8 +16,6 @@
package org.springframework.aop.aspectj;
import java.io.Serializable;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
@@ -31,8 +29,7 @@ import org.springframework.util.Assert;
* @since 2.0
* @see SimpleAspectInstanceFactory
*/
@SuppressWarnings("serial")
public class SingletonAspectInstanceFactory implements AspectInstanceFactory, Serializable {
public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
private final Object aspectInstance;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -27,7 +27,6 @@ import org.springframework.util.StringUtils;
* Spring AOP {@link ClassFilter} implementation using AspectJ type matching.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
@@ -77,21 +76,17 @@ public class TypePatternClassFilter implements ClassFilter {
* or is recognized as invalid
*/
public void setTypePattern(String typePattern) {
Assert.notNull(typePattern, "Type pattern must not be null");
Assert.notNull(typePattern);
this.typePattern = typePattern;
this.aspectJTypePatternMatcher =
PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution().
parseTypePattern(replaceBooleanOperators(typePattern));
}
/**
* Return the AspectJ type pattern to match.
*/
public String getTypePattern() {
return this.typePattern;
return typePattern;
}
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz candidate target class
@@ -100,7 +95,9 @@ public class TypePatternClassFilter implements ClassFilter {
*/
@Override
public boolean matches(Class<?> clazz) {
Assert.state(this.aspectJTypePatternMatcher != null, "No type pattern has been set");
if (this.aspectJTypePatternMatcher == null) {
throw new IllegalStateException("No 'typePattern' has been set via ctor/setter.");
}
return this.aspectJTypePatternMatcher.matches(clazz);
}
@@ -111,8 +108,9 @@ public class TypePatternClassFilter implements ClassFilter {
* <p>This method converts back to {@code &&} for the AspectJ pointcut parser.
*/
private String replaceBooleanOperators(String pcExpr) {
String result = StringUtils.replace(pcExpr," and "," && ");
result = StringUtils.replace(result, " or ", " || ");
return StringUtils.replace(result, " not ", " ! ");
pcExpr = StringUtils.replace(pcExpr," and "," && ");
pcExpr = StringUtils.replace(pcExpr, " or ", " || ");
pcExpr = StringUtils.replace(pcExpr, " not ", " ! ");
return pcExpr;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ 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.annotation.AnnotationUtils;
@@ -120,6 +121,49 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
}
/**
* The pointcut and advice annotations both have an "argNames" member which contains a
* comma-separated list of the argument names. We use this (if non-empty) to build the
* formal parameters for the pointcut.
*/
protected AspectJExpressionPointcut createPointcutExpression(
Method annotatedMethod, Class<?> declarationScope, String[] pointcutParameterNames) {
Class<?> [] pointcutParameterTypes = new Class<?>[0];
if (pointcutParameterNames != null) {
pointcutParameterTypes = extractPointcutParameterTypes(pointcutParameterNames,annotatedMethod);
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(declarationScope,pointcutParameterNames,pointcutParameterTypes);
ajexp.setLocation(annotatedMethod.toString());
return ajexp;
}
/**
* Create the pointcut parameters needed by aspectj based on the given argument names
* and the argument types that are available from the adviceMethod. Needs to take into
* account (ignore) any JoinPoint based arguments as these are not pointcut context but
* rather part of the advice execution context (thisJoinPoint, thisJoinPointStaticPart)
*/
private Class<?>[] extractPointcutParameterTypes(String[] argNames, Method adviceMethod) {
Class<?>[] ret = new Class<?>[argNames.length];
Class<?>[] paramTypes = adviceMethod.getParameterTypes();
if (argNames.length > paramTypes.length) {
throw new IllegalStateException("Expecting at least " + argNames.length +
" arguments in the advice declaration, but only found " + paramTypes.length);
}
// Make the simplifying assumption for now that all of the JoinPoint based arguments
// come first in the advice declaration.
int typeOffset = paramTypes.length - argNames.length;
for (int i = 0; i < ret.length; i++) {
ret[i] = paramTypes[i + typeOffset];
}
return ret;
}
/**
* Find and return the first AspectJ annotation on the given method
* (there <i>should</i> only be one anyway...)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -50,7 +50,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
private List<Pattern> includePatterns;
private AspectJAdvisorFactory aspectJAdvisorFactory;
private AspectJAdvisorFactory aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory();
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@@ -74,9 +74,6 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@@ -133,7 +130,6 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
package org.springframework.aop.aspectj.annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
@@ -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 ConcurrentHashMap<Class<?>, Object>();
private static final Map<Class<?>, Object> aspectCache = new HashMap<Class<?>, Object>();
private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory();
@@ -144,7 +144,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
AspectMetadata am, Class<?> aspectClass, String aspectName) {
MetadataAwareAspectInstanceFactory instanceFactory;
MetadataAwareAspectInstanceFactory instanceFactory = null;
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// Create a shared aspect instance.
Object instance = getSingletonAspectInstance(aspectClass);
@@ -162,29 +162,23 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
* is created if one cannot be found in the instance cache.
*/
private Object getSingletonAspectInstance(Class<?> aspectClass) {
// Quick check without a lock...
Object instance = aspectCache.get(aspectClass);
if (instance == null) {
synchronized (aspectCache) {
// To be safe, check within full lock now...
instance = aspectCache.get(aspectClass);
if (instance == null) {
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
}
catch (InstantiationException ex) {
throw new AopConfigException(
"Unable to instantiate aspect class: " + aspectClass.getName(), ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException(
"Could not access aspect constructor: " + aspectClass.getName(), ex);
}
}
synchronized (aspectCache) {
Object instance = aspectCache.get(aspectClass);
if (instance != null) {
return instance;
}
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
return instance;
}
catch (InstantiationException ex) {
throw new AopConfigException("Unable to instantiate aspect class [" + aspectClass.getName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException("Cannot access aspect class [" + aspectClass.getName() + "]", ex);
}
}
return instance;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
@@ -35,16 +31,16 @@ import org.springframework.aop.support.ComposablePointcut;
* Metadata for an AspectJ aspect class, with an additional Spring AOP pointcut
* for the per clause.
*
* <p>Uses AspectJ 5 AJType reflection API, enabling us to work with different
* AspectJ instantiation models such as "singleton", "pertarget" and "perthis".
* <p>Uses AspectJ 5 AJType reflection API, so is only supported on Java 5.
* Enables us to work with different AspectJ instantiation models such as
* "singleton", "pertarget" and "perthis".
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.aop.aspectj.AspectJExpressionPointcut
*/
@SuppressWarnings("serial")
public class AspectMetadata implements Serializable {
public class AspectMetadata {
/**
* The name of this aspect as defined to Spring (the bean name) -
@@ -53,17 +49,10 @@ public class AspectMetadata implements Serializable {
*/
private final String aspectName;
/**
* The aspect class, stored separately for re-resolution of the
* corresponding AjType on deserialization.
*/
private final Class<?> aspectClass;
/**
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
* Re-resolved on deserialization since it isn't serializable itself.
*/
private transient AjType<?> ajType;
private final AjType<?> ajType;
/**
* Spring AOP pointcut corresponding to the per clause of the
@@ -97,26 +86,23 @@ public class AspectMetadata implements Serializable {
if (ajType.getDeclarePrecedence().length > 0) {
throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
}
this.aspectClass = ajType.getJavaClass();
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON:
case SINGLETON :
this.perClausePointcut = Pointcut.TRUE;
return;
case PERTARGET:
case PERTHIS:
case PERTARGET : case PERTHIS :
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation(aspectClass.getName());
ajexp.setLocation("@Aspect annotation on " + aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
ajexp.setPointcutDeclarationScope(aspectClass);
this.perClausePointcut = ajexp;
return;
case PERTYPEWITHIN:
case PERTYPEWITHIN :
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
return;
default:
default :
throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
@@ -126,8 +112,10 @@ public class AspectMetadata implements Serializable {
* Extract contents from String of form {@code pertarget(contents)}.
*/
private String findPerClause(Class<?> aspectClass) {
// TODO when AspectJ provides this, we can remove this hack. Hence we don't
// bother to make it elegant. Or efficient. Or robust :-)
String str = aspectClass.getAnnotation(Aspect.class).value();
str = str.substring(str.indexOf('(') + 1);
str = str.substring(str.indexOf("(") + 1);
str = str.substring(0, str.length() - 1);
return str;
}
@@ -144,11 +132,11 @@ public class AspectMetadata implements Serializable {
* Return the aspect class.
*/
public Class<?> getAspectClass() {
return this.aspectClass;
return this.ajType.getJavaClass();
}
/**
* Return the aspect name.
* Return the aspect class.
*/
public String getAspectName() {
return this.aspectName;
@@ -185,10 +173,4 @@ public class AspectMetadata implements Serializable {
return (isPerThisOrPerTarget() || isPerTypeWithin());
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
this.ajType = AjTypeSystem.getAjType(this.aspectClass);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,10 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.OrderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
@@ -40,8 +37,7 @@ import org.springframework.util.ClassUtils;
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
@SuppressWarnings("serial")
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory, Serializable {
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
private final BeanFactory beanFactory;
@@ -70,8 +66,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
* @param type the type that should be introspected by AspectJ
*/
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
Assert.notNull(beanFactory, "BeanFactory must not be null");
Assert.notNull(name, "Bean name must not be null");
this.beanFactory = beanFactory;
this.name = name;
this.aspectMetadata = new AspectMetadata(type, name);
@@ -85,9 +79,12 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
@Override
public ClassLoader getAspectClassLoader() {
return (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
else {
return ClassUtils.getDefaultClassLoader();
}
}
@Override
@@ -95,23 +92,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
return this.aspectMetadata;
}
@Override
public Object getAspectCreationMutex() {
if (this.beanFactory != null) {
if (this.beanFactory.isSingleton(name)) {
// Rely on singleton semantics provided by the factory -> no local lock.
return null;
}
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
}
}
return this;
}
/**
* Determine the order for this factory's target aspect, either
* an instance-specific order expressed through implementing the
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -17,10 +17,10 @@
package org.springframework.aop.aspectj.annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
@@ -43,12 +43,12 @@ public class BeanFactoryAspectJAdvisorsBuilder {
private final AspectJAdvisorFactory advisorFactory;
private volatile List<String> aspectBeanNames;
private List<String> aspectBeanNames;
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<String, List<Advisor>>();
private final Map<String, List<Advisor>> advisorsCache = new HashMap<String, List<Advisor>>();
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache =
new ConcurrentHashMap<String, MetadataAwareAspectInstanceFactory>();
new HashMap<String, MetadataAwareAspectInstanceFactory>();
/**
@@ -56,7 +56,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @param beanFactory the ListableBeanFactory to scan
*/
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory));
this(beanFactory, new ReflectiveAspectJAdvisorFactory());
}
/**
@@ -80,57 +80,56 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
List<String> aspectNames = null;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 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);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 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);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
@@ -16,9 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
@@ -40,19 +37,12 @@ import org.springframework.aop.support.Pointcuts;
* @author Juergen Hoeller
* @since 2.0
*/
@SuppressWarnings("serial")
class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation {
private final AspectJExpressionPointcut declaredPointcut;
private final Class<?> declaringClass;
private final String methodName;
private final Class<?>[] parameterTypes;
private transient Method aspectJAdviceMethod;
private final Method aspectJAdviceMethod;
private final AspectJAdvisorFactory aspectJAdvisorFactory;
@@ -78,9 +68,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
@@ -240,16 +227,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
try {
this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("Failed to find advice method on deserialization", ex);
}
}
/**
* Pointcut implementation that changes its behaviour when the advice is instantiated.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -16,8 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import org.springframework.util.Assert;
/**
@@ -27,8 +25,7 @@ import org.springframework.util.Assert;
* @author Juergen Hoeller
* @since 2.0
*/
@SuppressWarnings("serial")
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory, Serializable {
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory {
private final MetadataAwareAspectInstanceFactory maaif;
@@ -46,17 +43,11 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
@Override
public Object getAspectInstance() {
public synchronized Object getAspectInstance() {
if (this.materialized == null) {
Object mutex = this.maaif.getAspectCreationMutex();
if (mutex == null) {
this.materialized = this.maaif.getAspectInstance();
}
else {
synchronized (mutex) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
synchronized (this) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
}
}
@@ -77,11 +68,6 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
return this.maaif.getAspectMetadata();
}
@Override
public Object getAspectCreationMutex() {
return this.maaif.getAspectCreationMutex();
}
@Override
public int getOrder() {
return this.maaif.getOrder();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -39,11 +39,4 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
*/
AspectMetadata getAspectMetadata();
/**
* Return the best possible creation mutex for this factory.
* @return the mutex object (may be {@code null} for no mutex to use)
* @since 4.3
*/
Object getAspectCreationMutex();
}
@@ -16,8 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import org.springframework.beans.factory.BeanFactory;
/**
@@ -34,8 +32,7 @@ import org.springframework.beans.factory.BeanFactory;
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
@SuppressWarnings("serial")
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory implements Serializable {
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory {
/**
* Create a PrototypeAspectInstanceFactory. AspectJ will be called to
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -46,7 +45,6 @@ import org.springframework.aop.aspectj.AspectJMethodBeforeAdvice;
import org.springframework.aop.aspectj.DeclareParentsAdvisor;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator;
@@ -67,8 +65,7 @@ import org.springframework.util.comparator.InstanceComparator;
* @author Phillip Webb
* @since 2.0
*/
@SuppressWarnings("serial")
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory {
private static final Comparator<Method> METHOD_COMPARATOR;
@@ -96,30 +93,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private final BeanFactory beanFactory;
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}.
*/
public ReflectiveAspectJAdvisorFactory() {
this(null);
}
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}, propagating the given
* {@link BeanFactory} to the created {@link AspectJExpressionPointcut} instances,
* for bean pointcut handling as well as consistent {@link ClassLoader} resolution.
* @param beanFactory the BeanFactory to propagate (may be {@code null}}
* @since 4.3.6
* @see AspectJExpressionPointcut#setBeanFactory
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader()
*/
public ReflectiveAspectJAdvisorFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
@@ -186,7 +159,9 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
if (DeclareParents.class == declareParents.defaultImpl()) {
throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
// This is what comes back if it wasn't set. This seems bizarre...
// TODO this restriction possibly should be relaxed
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
@@ -220,7 +195,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 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,11 +50,6 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
return this.metadata;
}
@Override
public Object getAspectCreationMutex() {
return this;
}
@Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.OrderUtils;
@@ -32,9 +30,8 @@ import org.springframework.core.annotation.OrderUtils;
* @since 2.0
* @see SimpleMetadataAwareAspectInstanceFactory
*/
@SuppressWarnings("serial")
public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspectInstanceFactory
implements MetadataAwareAspectInstanceFactory, Serializable {
implements MetadataAwareAspectInstanceFactory {
private final AspectMetadata metadata;
@@ -55,11 +52,6 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
return this.metadata;
}
@Override
public Object getAspectCreationMutex() {
return this;
}
@Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -71,7 +71,7 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
// generate name and register the interceptor
String interceptorName = existingBeanName + '.' + getInterceptorNameSuffix(interceptorDefinition);
String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
BeanDefinitionReaderUtils.registerBeanDefinition(
new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -97,7 +97,7 @@ public abstract class AopConfigUtils {
}
}
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -81,11 +81,11 @@ public abstract class AopNamespaceUtils {
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -21,8 +21,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Implementation of {@link AspectInstanceFactory} that locates the aspect from the
@@ -50,7 +50,9 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
Assert.notNull(this.aspectBeanName, "'aspectBeanName' is required");
if (!StringUtils.hasText(this.aspectBeanName)) {
throw new IllegalArgumentException("'aspectBeanName' is required");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -234,7 +234,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
@Override
public Class<?>[] getProxiedInterfaces() {
return ClassUtils.toClassArray(this.interfaces);
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
}
@Override
@@ -586,7 +586,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* Simple wrapper class around a Method. Used as the key when
* caching methods, for efficient equals and hashCode comparisons.
*/
private static final class MethodCacheKey implements Comparable<MethodCacheKey> {
private static class MethodCacheKey {
private final Method method;
@@ -599,28 +599,17 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof MethodCacheKey &&
this.method == ((MethodCacheKey) other).method));
if (other == this) {
return true;
}
MethodCacheKey otherKey = (MethodCacheKey) other;
return (this.method == otherKey.method);
}
@Override
public int hashCode() {
return this.hashCode;
}
@Override
public String toString() {
return this.method.toString();
}
@Override
public int compareTo(MethodCacheKey other) {
int result = this.method.getName().compareTo(other.method.getName());
if (result == 0) {
result = this.method.toString().compareTo(other.method.toString());
}
return result;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@ import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.core.DecoratingProxy;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -43,25 +42,6 @@ import org.springframework.util.ObjectUtils;
*/
public abstract class AopProxyUtils {
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
* @return the singleton target object managed in a {@link SingletonTargetSource},
* or {@code null} in any other case (not a proxy, not an existing singleton target)
* @since 4.3.8
* @see Advised#getTargetSource()
* @see SingletonTargetSource#getTarget()
*/
public static Object getSingletonTarget(Object candidate) {
if (candidate instanceof Advised) {
TargetSource targetSource = ((Advised) candidate).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
return ((SingletonTargetSource) targetSource).getTarget();
}
}
return null;
}
/**
* Determine the ultimate target class of the given bean instance, traversing
* not only a top-level proxy but any number of nested proxies as well &mdash;
@@ -78,7 +58,14 @@ public abstract class AopProxyUtils {
Class<?> result = null;
while (current instanceof TargetClassAware) {
result = ((TargetClassAware) current).getTargetClass();
current = getSingletonTarget(current);
Object nested = null;
if (current instanceof Advised) {
TargetSource targetSource = ((Advised) current).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
nested = ((SingletonTargetSource) targetSource).getTarget();
}
}
current = nested;
}
if (result == null) {
result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
@@ -91,29 +78,11 @@ public abstract class AopProxyUtils {
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
* {@link org.springframework.aop.SpringProxy} marker interface.
* @param advised the proxy config
* @return the complete set of interfaces to proxy
* @see SpringProxy
* @see Advised
* @see org.springframework.aop.SpringProxy
*/
public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
return completeProxiedInterfaces(advised, false);
}
/**
* Determine the complete set of interfaces to proxy for the given AOP configuration.
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
* {@link org.springframework.aop.SpringProxy} marker interface.
* @param advised the proxy config
* @param decoratingProxy whether to expose the {@link DecoratingProxy} interface
* @return the complete set of interfaces to proxy
* @since 4.3
* @see SpringProxy
* @see Advised
* @see DecoratingProxy
*/
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
@@ -130,7 +99,6 @@ public abstract class AopProxyUtils {
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
@@ -138,22 +106,13 @@ public abstract class AopProxyUtils {
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class;
}
return proxiedInterfaces;
}
@@ -175,9 +134,6 @@ public abstract class AopProxyUtils {
if (proxy instanceof Advised) {
nonUserIfcCount++;
}
if (proxy instanceof DecoratingProxy) {
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");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.aopalliance.aop.Advice;
@@ -57,6 +56,9 @@ import org.springframework.util.ObjectUtils;
/**
* CGLIB-based {@link AopProxy} implementation for the Spring AOP framework.
*
* <p>Formerly named {@code Cglib2AopProxy}, as of Spring 3.2, this class depends on
* Spring's own internally repackaged version of CGLIB 3.</i>.
*
* <p>Objects of this type should be obtained through proxy factories,
* configured by an {@link AdvisedSupport} object. This class is internal
* to Spring's AOP framework and need not be used directly by client code.
@@ -201,16 +203,18 @@ class CglibAopProxy implements AopProxy, Serializable {
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
catch (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
@@ -237,11 +241,10 @@ class CglibAopProxy implements AopProxy, Serializable {
* validates it if not.
*/
private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (logger.isWarnEnabled()) {
if (logger.isInfoEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader,
ClassUtils.getAllInterfacesForClassAsSet(proxySuperClass));
doValidateClass(proxySuperClass, proxyClassLoader);
validatedClasses.put(proxySuperClass, Boolean.TRUE);
}
}
@@ -252,35 +255,30 @@ class CglibAopProxy implements AopProxy, Serializable {
* Checks for final methods on the given {@code Class}, as well as package-visible
* methods across ClassLoaders, and writes warnings to the log for each one found.
*/
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader, Set<Class<?>> ifcs) {
if (proxySuperClass != Object.class) {
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (Object.class != proxySuperClass) {
Method[] methods = proxySuperClass.getDeclaredMethods();
for (Method method : methods) {
int mod = method.getModifiers();
if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) {
if (!Modifier.isStatic(mod)) {
if (Modifier.isFinal(mod)) {
if (implementsInterface(method, ifcs)) {
logger.warn("Unable to proxy interface-implementing method [" + method + "] because " +
"it is marked as final: Consider using interface-based JDK proxies instead!");
}
logger.info("Final method [" + method + "] cannot get proxied via CGLIB: " +
"Calls to this method will NOT be routed to the target instance and " +
"might lead to NPEs against uninitialized fields in the proxy instance.");
logger.info("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.");
}
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) &&
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
logger.info("Method [" + method + "] is package-visible across different ClassLoaders " +
"and cannot get proxied via CGLIB: Declare this method as public or protected " +
"if you need to support invocations through the proxy.");
logger.info("Unable to proxy method [" + method + "] because it is package-visible " +
"across different ClassLoaders: All calls to this method via a proxy will " +
"NOT be routed to the target instance.");
}
}
}
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs);
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader);
}
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
// Parameters used for optimisation choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
@@ -319,14 +317,14 @@ class CglibAopProxy implements AopProxy, Serializable {
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// then we can make some optimisations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimization 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(
@@ -347,39 +345,13 @@ class CglibAopProxy implements AopProxy, Serializable {
return callbacks;
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof CglibAopProxy &&
AopProxyUtils.equalsInProxy(this.advised, ((CglibAopProxy) other).advised)));
}
@Override
public int hashCode() {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
/**
* Check whether the given method is declared on any of the given interfaces.
*/
private static boolean implementsInterface(Method method, Set<Class<?>> ifcs) {
for (Class<?> ifc : ifcs) {
if (ClassUtils.hasMethod(ifc, method.getName(), method.getParameterTypes())) {
return true;
}
}
return false;
}
/**
* Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
*/
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())) {
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;
@@ -393,6 +365,18 @@ class CglibAopProxy implements AopProxy, Serializable {
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof CglibAopProxy &&
AopProxyUtils.equalsInProxy(this.advised, ((CglibAopProxy) other).advised)));
}
@Override
public int hashCode() {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
/**
* Serializable replacement for CGLIB's NoOp interface.
* Public to allow use elsewhere in the framework.
@@ -838,43 +822,52 @@ class CglibAopProxy implements AopProxy, Serializable {
// Else use the AOP_PROXY.
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
if (logger.isDebugEnabled()) {
logger.debug("Method has advice and optimizations are enabled: " + method);
logger.debug("Method has advice and optimisations are enabled: " + method);
}
// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
// We know that we are optimising so we can use the FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(key);
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Unable to apply any optimizations to advised method: " + method);
logger.debug("Unable to apply any optimisations to advised method: " + method);
}
return AOP_PROXY;
}
}
else {
// See if the return type of the method is outside the class hierarchy 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 we cannot use a dispatcher because the
// target needs to be explicitly released after the invocation.
// See if the return type of the method is outside the class hierarchy
// 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.
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
Class<?> returnType = method.getReturnType();
if (returnType.isAssignableFrom(targetClass)) {
if (targetClass == returnType) {
if (logger.isDebugEnabled()) {
logger.debug("Method return type is assignable from target type and " +
"may therefore return 'this' - using INVOKE_TARGET: " + method);
logger.debug("Method " + method +
"has return type same as target type (may return this) - using INVOKE_TARGET");
}
return INVOKE_TARGET;
}
else {
else if (returnType.isPrimitive() || !returnType.isAssignableFrom(targetClass)) {
if (logger.isDebugEnabled()) {
logger.debug("Method return type ensures 'this' cannot be returned - " +
"using DISPATCH_TARGET: " + method);
logger.debug("Method " + method +
" has return type that ensures this cannot be returned- using DISPATCH_TARGET");
}
return DISPATCH_TARGET;
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Method " + method +
"has return type that is assignable from the target type (may return this) - " +
"using INVOKE_TARGET");
}
return INVOKE_TARGET;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,6 @@ import org.springframework.aop.AopInvocationException;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.DecoratingProxy;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -117,7 +116,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@@ -165,15 +164,11 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
@@ -215,8 +210,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@ import org.springframework.aop.TargetSource;
import org.springframework.util.ClassUtils;
/**
* Factory for AOP proxies for programmatic use, rather than via declarative
* setup in a bean factory. This class provides a simple way of obtaining
* and configuring AOP proxy instances in custom user code.
* Factory for AOP proxies for programmatic use, rather than via a bean
* factory. This class provides a simple way of obtaining and configuring
* AOP proxies in code.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.aop.framework;
import java.io.Closeable;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.DisposableBean;
@@ -50,9 +48,9 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
/**
* Set the ordering which will apply to this processor's implementation
* of {@link Ordered}, used when applying multiple processors.
* <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered.
* Set the ordering which will apply to this class's implementation
* of Ordered, used when applying multiple processors.
* <p>Default value is {@code Integer.MAX_VALUE}, meaning that it's non-ordered.
* @param order the ordering value
*/
public void setOrder(int order) {
@@ -129,7 +127,6 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
*/
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc ||
Closeable.class == ifc || "java.lang.AutoCloseable".equals(ifc.getName()) ||
ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
@@ -142,9 +139,7 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
* @return whether the given interface is an internal language interface
*/
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
return ifc.getName().equals("groovy.lang.GroovyObject");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -26,7 +26,7 @@ import org.springframework.aop.AfterReturningAdvice;
import org.springframework.util.Assert;
/**
* Interceptor to wrap an {@link org.springframework.aop.AfterReturningAdvice}.
* Interceptor to wrap am {@link org.springframework.aop.AfterReturningAdvice}.
* Used internally by the AOP framework; application developers should not need
* to use this class directly.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,8 +54,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.ProxyFactory;
@@ -55,25 +54,26 @@ import org.springframework.util.StringUtils;
* before invoking the bean itself.
*
* <p>This class distinguishes between "common" interceptors: shared for all proxies it
* creates, and "specific" interceptors: unique per bean instance. There need not be any
* common interceptors. If there are, they are set using the interceptorNames property.
* As with {@link org.springframework.aop.framework.ProxyFactoryBean}, interceptors names
* in the current factory are used rather than bean references to allow correct handling
* of prototype advisors and interceptors: for example, to support stateful mixins.
* Any advice type is supported for {@link #setInterceptorNames "interceptorNames"} entries.
* creates, and "specific" interceptors: unique per bean instance. There need not
* be any common interceptors. If there are, they are set using the interceptorNames
* property. As with ProxyFactoryBean, interceptors names in the current factory
* are used rather than bean references to allow correct handling of prototype
* advisors and interceptors: for example, to support stateful mixins.
* Any advice type is supported for "interceptorNames" entries.
*
* <p>Such auto-proxying is particularly useful if there's a large number of beans that
* need to be wrapped with similar proxies, i.e. delegating to the same interceptors.
* Instead of x repetitive proxy definitions for x target beans, you can register
* one single such post processor with the bean factory to achieve the same effect.
*
* <p>Subclasses can apply any strategy to decide if a bean is to be proxied, e.g. by type,
* by name, by definition details, etc. They can also return additional interceptors that
* should just be applied to the specific bean instance. A simple concrete implementation is
* {@link BeanNameAutoProxyCreator}, identifying the beans to be proxied via given names.
* <p>Subclasses can apply any strategy to decide if a bean is to be proxied,
* e.g. by type, by name, by definition details, etc. They can also return
* additional interceptors that should just be applied to the specific bean
* instance. The default concrete implementation is BeanNameAutoProxyCreator,
* identifying the beans to be proxied via a list of bean names.
*
* <p>Any number of {@link TargetSourceCreator} implementations can be used to create
* a custom target source: for example, to pool prototype objects. Auto-proxying will
* a custom target source - for example, to pool prototype objects. Auto-proxying will
* occur even if there is no advice, as long as a TargetSourceCreator specifies a custom
* {@link org.springframework.aop.TargetSource}. If there are no TargetSourceCreators set,
* or if none matches, a {@link org.springframework.aop.target.SingletonTargetSource}
@@ -155,8 +155,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Specify the {@link AdvisorAdapterRegistry} to use.
* <p>Default is the global {@link AdvisorAdapterRegistry}.
* Specify the AdvisorAdapterRegistry to use.
* Default is the global AdvisorAdapterRegistry.
* @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
*/
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
@@ -164,18 +164,18 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Set custom {@code TargetSourceCreators} to be applied in this order.
* If the list is empty, or they all return null, a {@link SingletonTargetSource}
* Set custom TargetSourceCreators to be applied in this order.
* If the list is empty, or they all return null, a SingletonTargetSource
* will be created for each bean.
* <p>Note that TargetSourceCreators will kick in even for target beans
* where no advices or advisors have been found. If a {@code TargetSourceCreator}
* returns a {@link TargetSource} for a specific bean, that bean will be proxied
* where no advices or advisors have been found. If a TargetSourceCreator
* returns a TargetSource for a specific bean, that bean will be proxied
* in any case.
* <p>{@code TargetSourceCreators} can only be invoked if this post processor is used
* in a {@link BeanFactory} and its {@link BeanFactoryAware} callback is triggered.
* @param targetSourceCreators the list of {@code TargetSourceCreators}.
* Ordering is significant: The {@code TargetSource} returned from the first matching
* {@code TargetSourceCreator} (that is, the first that returns non-null) will be used.
* <p>TargetSourceCreators can only be invoked if this post processor is used
* in a BeanFactory, and its BeanFactoryAware callback is used.
* @param targetSourceCreators list of TargetSourceCreator.
* 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) {
this.customTargetSourceCreators = targetSourceCreators;
@@ -206,8 +206,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Return the owning {@link BeanFactory}.
* May be {@code null}, as this post-processor doesn't need to belong to a bean factory.
* Return the owning BeanFactory.
* May be {@code null}, as this object doesn't need to belong to a bean factory.
*/
protected BeanFactory getBeanFactory() {
return this.beanFactory;
@@ -370,7 +370,6 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
*/
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
@@ -454,7 +453,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
@@ -35,7 +35,7 @@ public abstract class AutoProxyUtils {
* to be proxied with its target class (in case of it getting proxied in the first
* place). The value is {@code Boolean.TRUE} or {@code Boolean.FALSE}.
* <p>Proxy factories can set this attribute if they built a target class proxy
* for a specific bean, and want to enforce that bean can always be cast
* for a specific bean, and want to enforce that that bean can always be cast
* to its target class (even if AOP advices get applied through auto-proxying).
* @see #shouldProxyTargetClass
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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,16 +19,15 @@ package org.springframework.aop.framework.autoproxy;
import org.springframework.beans.factory.BeanNameAware;
/**
* {@code BeanPostProcessor} implementation that creates AOP proxies based on all
* candidate {@code Advisor}s in the current {@code BeanFactory}. This class is
* completely generic; it contains no special code to handle any particular aspects,
* such as pooling aspects.
* BeanPostProcessor implementation that creates AOP proxies based on all candidate
* Advisors in the current BeanFactory. This class is completely generic; it contains
* no special code to handle any particular aspects, such as pooling aspects.
*
* <p>It's possible to filter out advisors - for example, to use multiple post processors
* of this type in the same factory - by setting the {@code usePrefix} property to true,
* in which case only advisors beginning with the DefaultAdvisorAutoProxyCreator's bean
* name followed by a dot (like "aapc.") will be used. This default prefix can be changed
* from the bean name by setting the {@code advisorBeanNamePrefix} property.
* of this type in the same factory - by setting the {@code usePrefix} property
* to true, in which case only advisors beginning with the DefaultAdvisorAutoProxyCreator's
* bean name followed by a dot (like "aapc.") will be used. This default prefix can be
* changed from the bean name by setting the {@code advisorBeanNamePrefix} property.
* The separator (.) will also be used in this case.
*
* @author Rod Johnson
@@ -41,22 +40,22 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
public final static String SEPARATOR = ".";
private boolean usePrefix = false;
private boolean usePrefix;
private String advisorBeanNamePrefix;
/**
* Set whether to only include advisors with a certain prefix in the bean name.
* <p>Default is {@code false}, including all beans of type {@code Advisor}.
* @see #setAdvisorBeanNamePrefix
* Set whether to exclude advisors with a certain prefix
* in the bean name.
*/
public void setUsePrefix(boolean usePrefix) {
this.usePrefix = usePrefix;
}
/**
* Return whether to only include advisors with a certain prefix in the bean name.
* Return whether to exclude advisors with a certain prefix
* in the bean name.
*/
public boolean isUsePrefix() {
return this.usePrefix;
@@ -90,7 +89,7 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
/**
* Consider {@code Advisor} beans with the specified prefix as eligible, if activated.
* Consider Advisor beans with the specified prefix as eligible, if activated.
* @see #setUsePrefix
* @see #setAdvisorBeanNamePrefix
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -22,12 +22,12 @@ import org.aopalliance.intercept.MethodInvocation;
/**
* Base class for monitoring interceptors, such as performance monitors.
* Provides configurable "prefix and "suffix" properties that help to
* classify/group performance monitoring results.
* Provides {@code prefix} and {@code suffix} properties
* that help to classify/group performance monitoring results.
*
* <p>In their {@link #invokeUnderTrace} implementation, subclasses should call the
* {@link #createInvocationTraceName} method to create a name for the given trace,
* including information about the method invocation along with a prefix/suffix.
* <p>Subclasses should call the {@code createInvocationTraceName(MethodInvocation)}
* method to create a name for the given trace that includes information about the
* method invocation under trace along with the prefix and suffix added as appropriate.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -58,12 +58,6 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
*/
private boolean hideProxyClassNames = false;
/**
* Indicates whether to pass an exception to the logger.
* @see #writeToLog(Log, String, Throwable)
*/
private boolean logExceptionStackTrace = true;
/**
* Set whether to use a dynamic logger or a static logger.
@@ -104,17 +98,6 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
this.hideProxyClassNames = hideProxyClassNames;
}
/**
* Set whether to pass an exception to the logger, suggesting inclusion
* of its stack trace into the log. Default is "true"; set this to "false"
* in order to reduce the log output to just the trace message (which may
* include the exception class name and exception message, if applicable).
* @since 4.3.10
*/
public void setLogExceptionStackTrace(boolean logExceptionStackTrace) {
this.logExceptionStackTrace = logExceptionStackTrace;
}
/**
* Determines whether or not logging is enabled for the particular {@code MethodInvocation}.
@@ -188,40 +171,6 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
return logger.isTraceEnabled();
}
/**
* Write the supplied trace message to the supplied {@code Log} instance.
* <p>To be called by {@link #invokeUnderTrace} for enter/exit messages.
* <p>Delegates to {@link #writeToLog(Log, String, Throwable)} as the
* ultimate delegate that controls the underlying logger invocation.
* @since 4.3.10
* @see #writeToLog(Log, String, Throwable)
*/
protected void writeToLog(Log logger, String message) {
writeToLog(logger, message, null);
}
/**
* Write the supplied trace message and {@link Throwable} to the
* supplied {@code Log} instance.
* <p>To be called by {@link #invokeUnderTrace} for enter/exit outcomes,
* potentially including an exception. Note that an exception's stack trace
* won't get logged when {@link #setLogExceptionStackTrace} is "false".
* <p>By default messages are written at {@code TRACE} level. Subclasses
* can override this method to control which level the message is written
* at, typically also overriding {@link #isLogEnabled} accordingly.
* @since 4.3.10
* @see #setLogExceptionStackTrace
* @see #isLogEnabled
*/
protected void writeToLog(Log logger, String message, Throwable ex) {
if (ex != null && this.logExceptionStackTrace) {
logger.trace(message, ex);
}
else {
logger.trace(message);
}
}
/**
* Subclasses must override this method to perform any tracing around the
@@ -231,15 +180,13 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
* <p>By default, the passed-in {@code Log} instance will have log level
* "trace" enabled. Subclasses do not have to check for this again, unless
* they overwrite the {@code isInterceptorEnabled} method to modify
* the default behavior, and may delegate to {@code writeToLog} for actual
* messages to be written.
* the default behavior.
* @param logger the {@code Log} to write trace messages to
* @return the result of the call to {@code MethodInvocation.proceed()}
* @throws Throwable if the call to {@code MethodInvocation.proceed()}
* encountered any errors
* @see #isInterceptorEnabled
* @see #isLogEnabled
* @see #writeToLog(Log, String)
* @see #writeToLog(Log, String, Throwable)
*/
protected abstract Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,12 +31,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.lang.UsesJava8;
import org.springframework.util.ClassUtils;
@@ -61,15 +58,6 @@ import org.springframework.util.concurrent.ListenableFuture;
*/
public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
/**
* The default name of the {@link TaskExecutor} bean to pick up: "taskExecutor".
* <p>Note that the initial lookup happens by type; this is just the fallback
* in case of multiple executor beans found in the context.
* @since 4.2.6
*/
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor";
// Java 8's CompletableFuture type present?
private static final boolean completableFuturePresent = ClassUtils.isPresent(
"java.util.concurrent.CompletableFuture", AsyncExecutionInterceptor.class.getClassLoader());
@@ -79,7 +67,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap<Method, AsyncTaskExecutor>(16);
private volatile Executor defaultExecutor;
private Executor defaultExecutor;
private AsyncUncaughtExceptionHandler exceptionHandler;
@@ -87,22 +75,10 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
/**
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
* executor has been requested via a qualifier on the async method, in which case the
* executor will be looked up at invocation time against the enclosing bean factory
*/
public AsyncExecutionAspectSupport(Executor defaultExecutor) {
this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler());
}
/**
* Create a new {@link AsyncExecutionAspectSupport} with the given exception handler.
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
* executor has been requested via a qualifier on the async method, in which case the
* executor will be looked up at invocation time against the enclosing bean factory
* Create a new {@link AsyncExecutionAspectSupport}, using the provided default
* executor unless individual async methods indicate via qualifier that a more
* specific executor should be used.
* @param defaultExecutor the executor to use when executing asynchronous methods
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use
*/
public AsyncExecutionAspectSupport(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
@@ -110,16 +86,23 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
this.exceptionHandler = exceptionHandler;
}
/**
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
*/
public AsyncExecutionAspectSupport(Executor defaultExecutor) {
this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler());
}
/**
* Supply the executor to be used when executing async methods.
* @param defaultExecutor the {@code Executor} (typically a Spring {@code AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to, unless a more specific
* executor has been requested via a qualifier on the async method, in which case the
* executor will be looked up at invocation time against the enclosing bean factory
* @see #getExecutorQualifier(Method)
* @param defaultExecutor the {@code Executor} (typically a Spring {@code
* AsyncTaskExecutor} or {@link java.util.concurrent.ExecutorService}) to delegate to
* unless a more specific executor has been requested via a qualifier on the async
* method, in which case the executor will be looked up at invocation time against the
* enclosing bean factory.
* @see #getExecutorQualifier
* @see #setBeanFactory(BeanFactory)
* @see #getDefaultExecutor(BeanFactory)
*/
public void setExecutor(Executor defaultExecutor) {
this.defaultExecutor = defaultExecutor;
@@ -134,10 +117,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
}
/**
* Set the {@link BeanFactory} to be used when looking up executors by qualifier
* or when relying on the default executor lookup algorithm.
* @see #findQualifiedExecutor(BeanFactory, String)
* @see #getDefaultExecutor(BeanFactory)
* Set the {@link BeanFactory} to be used when looking up executors by qualifier.
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
@@ -148,32 +128,26 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
/**
* Determine the specific executor to use when executing the given method.
* Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
* @return the executor to use (or {@code null}, but just if no default executor is available)
* @return the executor to use (or {@code null}, but just if no default executor has been set)
*/
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) {
Executor targetExecutor;
Executor executorToUse = this.defaultExecutor;
String qualifier = getExecutorQualifier(method);
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
}
else {
targetExecutor = this.defaultExecutor;
if (targetExecutor == null) {
synchronized (this.executors) {
if (this.defaultExecutor == null) {
this.defaultExecutor = getDefaultExecutor(this.beanFactory);
}
targetExecutor = this.defaultExecutor;
}
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
" to access qualified executor '" + qualifier + "'");
}
executorToUse = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
this.beanFactory, Executor.class, qualifier);
}
if (targetExecutor == null) {
else if (executorToUse == null) {
return null;
}
executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
executor = (executorToUse instanceof AsyncListenableTaskExecutor ?
(AsyncListenableTaskExecutor) executorToUse : new TaskExecutorAdapter(executorToUse));
this.executors.put(method, executor);
}
return executor;
@@ -186,76 +160,11 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* been specified and that the {@linkplain #setExecutor(Executor) default executor}
* should be used.
* @param method the method to inspect for executor qualifier metadata
* @return the qualifier if specified, otherwise empty String or {@code null}
* @return the qualifier if specified, otherwise empty string or {@code null}
* @see #determineAsyncExecutor(Method)
* @see #findQualifiedExecutor(BeanFactory, String)
*/
protected abstract String getExecutorQualifier(Method method);
/**
* Retrieve a target executor for the given qualifier.
* @param qualifier the qualifier to resolve
* @return the target executor, or {@code null} if none available
* @since 4.2.6
* @see #getExecutorQualifier(Method)
*/
protected Executor findQualifiedExecutor(BeanFactory beanFactory, String qualifier) {
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
" to access qualified executor '" + qualifier + "'");
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier);
}
/**
* Retrieve or build a default executor for this advice instance.
* An executor returned from here will be cached for further use.
* <p>The default implementation searches for a unique {@link TaskExecutor} bean
* in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
* If neither of the two is resolvable, this implementation will return {@code null}.
* @param beanFactory the BeanFactory to use for a default executor lookup
* @return the default executor, or {@code null} if none available
* @since 4.2.6
* @see #findQualifiedExecutor(BeanFactory, String)
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
*/
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
if (beanFactory != null) {
try {
// Search for TaskExecutor bean... not plain Executor since that would
// match with ScheduledExecutorService as well, which is unusable for
// our purposes here. TaskExecutor is more clearly designed for it.
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
if (logger.isInfoEnabled()) {
logger.info("More than one TaskExecutor bean found within the context, and none is named " +
"'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly " +
"as an alias) in order to use it for async processing: " + ex.getBeanNamesFound());
}
}
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.info("No task executor bean found for async processing: " +
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
}
// Giving up -> either using local default executor or none at all...
}
}
return null;
}
/**
* Delegate for actually executing the given task with the chosen executor.
* @param task the task to execute
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,11 +26,9 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.Ordered;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.util.ClassUtils;
/**
@@ -67,27 +65,22 @@ import org.springframework.util.ClassUtils;
*/
public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
/**
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to;
* as of 4.2.6, a local executor for this interceptor will be built otherwise
*/
public AsyncExecutionInterceptor(Executor defaultExecutor) {
super(defaultExecutor);
}
/**
* Create a new {@code AsyncExecutionInterceptor}.
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to;
* as of 4.2.6, a local executor for this interceptor will be built otherwise
* or {@link java.util.concurrent.ExecutorService}) to delegate to
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use
*/
public AsyncExecutionInterceptor(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
super(defaultExecutor, exceptionHandler);
}
/**
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
*/
public AsyncExecutionInterceptor(Executor defaultExecutor) {
super(defaultExecutor);
}
/**
* Intercept the given method invocation, submit the actual calling of the method to
@@ -143,20 +136,6 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport imple
return null;
}
/**
* This implementation searches for a unique {@link org.springframework.core.task.TaskExecutor}
* bean in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
* If neither of the two is resolvable (e.g. if no {@code BeanFactory} was configured at all),
* this implementation falls back to a newly created {@link SimpleAsyncTaskExecutor} instance
* for local use if no default could be found.
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
*/
@Override
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -128,20 +128,20 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
/**
* The default message used for writing method entry messages.
*/
private static final String DEFAULT_ENTER_MESSAGE = "Entering method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_ENTER_MESSAGE =
"Entering method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The default message used for writing method exit messages.
*/
private static final String DEFAULT_EXIT_MESSAGE = "Exiting method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_EXIT_MESSAGE =
"Exiting method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The default message used for writing exception messages.
*/
private static final String DEFAULT_EXCEPTION_MESSAGE = "Exception thrown in method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_EXCEPTION_MESSAGE =
"Exception thrown in method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The {@code Pattern} used to match placeholders.
@@ -182,14 +182,14 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setEnterMessage(String enterMessage) throws IllegalArgumentException {
Assert.hasText(enterMessage, "enterMessage must not be empty");
Assert.hasText(enterMessage, "'enterMessage' must not be empty");
checkForInvalidPlaceholders(enterMessage);
Assert.doesNotContain(enterMessage, PLACEHOLDER_RETURN_VALUE,
"enterMessage cannot contain placeholder " + PLACEHOLDER_RETURN_VALUE);
"enterMessage cannot contain placeholder [" + PLACEHOLDER_RETURN_VALUE + "]");
Assert.doesNotContain(enterMessage, PLACEHOLDER_EXCEPTION,
"enterMessage cannot contain placeholder " + PLACEHOLDER_EXCEPTION);
"enterMessage cannot contain placeholder [" + PLACEHOLDER_EXCEPTION + "]");
Assert.doesNotContain(enterMessage, PLACEHOLDER_INVOCATION_TIME,
"enterMessage cannot contain placeholder " + PLACEHOLDER_INVOCATION_TIME);
"enterMessage cannot contain placeholder [" + PLACEHOLDER_INVOCATION_TIME + "]");
this.enterMessage = enterMessage;
}
@@ -206,10 +206,10 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setExitMessage(String exitMessage) {
Assert.hasText(exitMessage, "exitMessage must not be empty");
Assert.hasText(exitMessage, "'exitMessage' must not be empty");
checkForInvalidPlaceholders(exitMessage);
Assert.doesNotContain(exitMessage, PLACEHOLDER_EXCEPTION,
"exitMessage cannot contain placeholder" + PLACEHOLDER_EXCEPTION);
"exitMessage cannot contain placeholder [" + PLACEHOLDER_EXCEPTION + "]");
this.exitMessage = exitMessage;
}
@@ -225,10 +225,12 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setExceptionMessage(String exceptionMessage) {
Assert.hasText(exceptionMessage, "exceptionMessage must not be empty");
Assert.hasText(exceptionMessage, "'exceptionMessage' must not be empty");
checkForInvalidPlaceholders(exceptionMessage);
Assert.doesNotContain(exceptionMessage, PLACEHOLDER_RETURN_VALUE,
"exceptionMessage cannot contain placeholder " + PLACEHOLDER_RETURN_VALUE);
"exceptionMessage cannot contain placeholder [" + PLACEHOLDER_RETURN_VALUE + "]");
Assert.doesNotContain(exceptionMessage, PLACEHOLDER_INVOCATION_TIME,
"exceptionMessage cannot contain placeholder [" + PLACEHOLDER_INVOCATION_TIME + "]");
this.exceptionMessage = exceptionMessage;
}
@@ -244,7 +246,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
*/
@Override
protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
String name = ClassUtils.getQualifiedMethodName(invocation.getMethod());
String name = invocation.getMethod().getDeclaringClass().getName() + "." + invocation.getMethod().getName();
StopWatch stopWatch = new StopWatch(name);
Object returnValue = null;
boolean exitThroughException = false;
@@ -260,8 +262,8 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
stopWatch.stop();
}
exitThroughException = true;
writeToLog(logger, replacePlaceholders(
this.exceptionMessage, invocation, null, ex, stopWatch.getTotalTimeMillis()), ex);
writeToLog(logger,
replacePlaceholders(this.exceptionMessage, invocation, null, ex, stopWatch.getTotalTimeMillis()), ex);
throw ex;
}
finally {
@@ -269,12 +271,35 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
writeToLog(logger, replacePlaceholders(
this.exitMessage, invocation, returnValue, null, stopWatch.getTotalTimeMillis()));
writeToLog(logger,
replacePlaceholders(this.exitMessage, invocation, returnValue, null, stopWatch.getTotalTimeMillis()));
}
}
}
/**
* Writes the supplied message to the supplied {@code Log} instance.
* @see #writeToLog(org.apache.commons.logging.Log, String, Throwable)
*/
protected void writeToLog(Log logger, String message) {
writeToLog(logger, message, null);
}
/**
* Writes the supplied message and {@link Throwable} to the
* supplied {@code Log} instance. By default messages are written
* at {@code TRACE} level. Sub-classes can override this method
* to control which level the message is written at.
*/
protected void writeToLog(Log logger, String message, Throwable ex) {
if (ex != null) {
logger.trace(message, ex);
}
else {
logger.trace(message);
}
}
/**
* Replace the placeholders in the given message with the supplied values,
* or values derived from those supplied.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@ public class JamonPerformanceMonitorInterceptor extends AbstractMonitoringInterc
finally {
monitor.stop();
if (!this.trackAllInvocations || isLogEnabled(logger)) {
writeToLog(logger, "JAMon performance statistics for method [" + name + "]:\n" + monitor);
logger.trace("JAMon performance statistics for method [" + name + "]:\n" + monitor);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -63,7 +63,7 @@ public class PerformanceMonitorInterceptor extends AbstractMonitoringInterceptor
}
finally {
stopWatch.stop();
writeToLog(logger, stopWatch.shortSummary());
logger.trace(stopWatch.shortSummary());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -55,14 +55,14 @@ public class SimpleTraceInterceptor extends AbstractTraceInterceptor {
@Override
protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
String invocationDescription = getInvocationDescription(invocation);
writeToLog(logger, "Entering " + invocationDescription);
logger.trace("Entering " + invocationDescription);
try {
Object rval = invocation.proceed();
writeToLog(logger, "Exiting " + invocationDescription);
logger.trace("Exiting " + invocationDescription);
return rval;
}
catch (Throwable ex) {
writeToLog(logger, "Exception thrown in " + invocationDescription, ex);
logger.trace("Exception thrown in " + invocationDescription, ex);
throw ex;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2014 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.
@@ -89,7 +89,7 @@ public abstract class ScopedProxyUtils {
}
/**
* Generate the bean name that is used within the scoped proxy to reference the target bean.
* Generates the bean name that is used within the scoped proxy to reference the target bean.
* @param originalBeanName the original name of bean
* @return the generated bean to be used to reference the target bean
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -23,7 +23,6 @@ import org.aopalliance.aop.Advice;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.Assert;
/**
@@ -46,7 +45,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
private BeanFactory beanFactory;
private transient volatile Advice advice;
private transient Advice advice;
private transient volatile Object adviceMonitor = new Object();
@@ -73,23 +72,8 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
resetAdviceMonitor();
}
private void resetAdviceMonitor() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
this.adviceMonitor = ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
}
else {
this.adviceMonitor = new Object();
}
}
/**
* Specify a particular instance of the target advice directly,
* avoiding lazy resolution in {@link #getAdvice()}.
* @since 3.1
*/
public void setAdvice(Advice advice) {
synchronized (this.adviceMonitor) {
this.advice = advice;
@@ -98,42 +82,18 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
@Override
public Advice getAdvice() {
Advice advice = this.advice;
if (advice != null || this.adviceBeanName == null) {
return advice;
}
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
// Rely on singleton semantics provided by the factory.
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
synchronized (this.adviceMonitor) {
if (this.advice == null) {
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
}
return this.advice;
synchronized (this.adviceMonitor) {
if (this.advice == null && this.adviceBeanName != null) {
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
}
return this.advice;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append(": advice ");
if (this.adviceBeanName != null) {
sb.append("bean '").append(this.adviceBeanName).append("'");
}
else {
sb.append(this.advice);
}
return sb.toString();
return getClass().getName() + ": advice bean '" + getAdviceBeanName() + "'";
}
@@ -146,7 +106,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
ois.defaultReadObject();
// Initialize transient fields.
resetAdviceMonitor();
this.adviceMonitor = new Object();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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,7 +21,6 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -130,8 +129,8 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
return ((targetClass != null && matchesPattern(ClassUtils.getQualifiedMethodName(method, targetClass))) ||
matchesPattern(ClassUtils.getQualifiedMethodName(method)));
return ((targetClass != null && matchesPattern(targetClass.getName() + "." + method.getName())) ||
matchesPattern(method.getDeclaringClass().getName() + "." + method.getName()));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.aop.support;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.LinkedHashSet;
import java.util.LinkedList;
@@ -35,7 +34,6 @@ import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodIntrospector;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -114,30 +112,6 @@ public abstract class AopUtils {
return result;
}
/**
* Select an invocable method on the target type: either the given method itself
* if actually exposed on the target type, or otherwise a corresponding method
* on one of the target type's interfaces or on the target type itself.
* @param method the method to check
* @param targetType the target type to search methods on (typically an AOP proxy)
* @return a corresponding invocable method on the target type
* @throws IllegalStateException if the given method is not invocable on the given
* target type (typically due to a proxy mismatch)
* @since 4.3
* @see MethodIntrospector#selectInvocableMethod(Method, Class)
*/
public static Method selectInvocableMethod(Method method, Class<?> targetType) {
Method methodToUse = MethodIntrospector.selectInvocableMethod(method, targetType);
if (Modifier.isPrivate(methodToUse.getModifiers()) && !Modifier.isStatic(methodToUse.getModifiers()) &&
SpringProxy.class.isAssignableFrom(targetType)) {
throw new IllegalStateException(String.format(
"Need to invoke method '%s' found on proxy for target class '%s' but cannot " +
"be delegated to target bean. Switch its visibility to package or protected.",
method.getName(), method.getDeclaringClass().getSimpleName()));
}
return methodToUse;
}
/**
* Determine whether the given method is an "equals" method.
* @see java.lang.Object#equals
@@ -222,11 +196,6 @@ public abstract class AopUtils {
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
@@ -235,7 +204,7 @@ public abstract class AopUtils {
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -22,6 +22,7 @@ import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Convenient class for building up pointcuts. All methods return
@@ -187,14 +188,21 @@ public class ComposablePointcut implements Pointcut, Serializable {
if (!(other instanceof ComposablePointcut)) {
return false;
}
ComposablePointcut otherPointcut = (ComposablePointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
ComposablePointcut that = (ComposablePointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
}
@Override
public int hashCode() {
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
int code = 17;
if (this.classFilter != null) {
code = 37 * code + this.classFilter.hashCode();
}
if (this.methodMatcher != null) {
code = 37 * code + this.methodMatcher.hashCode();
}
return code;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@ import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.core.ControlFlow;
import org.springframework.core.ControlFlowFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -32,7 +34,7 @@ import org.springframework.util.ObjectUtils;
*
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @see org.springframework.core.ControlFlow
*/
@SuppressWarnings("serial")
public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable {
@@ -41,7 +43,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
private String methodName;
private volatile int evaluations;
private int evaluations;
/**
@@ -53,11 +55,11 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
}
/**
* Construct a new pointcut that matches all calls below the given method
* in the given class. If no method name is given, matches all control flows
* below the given class.
* Construct a new pointcut that matches all calls below the
* given method in the given class. If the method name is null,
* matches all control flows below that class.
* @param clazz the clazz
* @param methodName the name of the method (may be {@code null})
* @param methodName the name of the method
*/
public ControlFlowPointcut(Class<?> clazz, String methodName) {
Assert.notNull(clazz, "Class must not be null");
@@ -91,14 +93,8 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
this.evaluations++;
for (StackTraceElement element : new Throwable().getStackTrace()) {
if (element.getClassName().equals(this.clazz.getName()) &&
(this.methodName == null || element.getMethodName().equals(this.methodName))) {
return true;
}
}
return false;
ControlFlow cflow = ControlFlowFactory.createControlFlow();
return (this.methodName != null ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz));
}
/**
@@ -134,7 +130,8 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public int hashCode() {
int code = this.clazz.hashCode();
int code = 17;
code = 37 * code + this.clazz.hashCode();
if (this.methodName != null) {
code = 37 * code + this.methodName.hashCode();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2014 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.
@@ -45,7 +45,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
private final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
private int order = Ordered.LOWEST_PRECEDENCE;
private int order = Integer.MAX_VALUE;
/**
@@ -104,7 +104,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
@Override
public Class<?>[] getInterfaces() {
return ClassUtils.toClassArray(this.interfaces);
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
}
@Override
@@ -118,6 +118,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
}
}
public void setOrder(int order) {
this.order = order;
}
@@ -127,6 +128,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
return this.order;
}
@Override
public Advice getAdvice() {
return this.advice;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,15 +53,15 @@ public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
* due to the delegate implementing it. Call this method to exclude
* internal interfaces from being visible at the proxy level.
* <p>Does nothing if the interface is not implemented by the delegate.
* @param ifc the interface to suppress
* @param intf the interface to suppress
*/
public void suppressInterface(Class<?> ifc) {
this.publishedInterfaces.remove(ifc);
public void suppressInterface(Class<?> intf) {
this.publishedInterfaces.remove(intf);
}
@Override
public Class<?>[] getInterfaces() {
return ClassUtils.toClassArray(this.publishedInterfaces);
return this.publishedInterfaces.toArray(new Class<?>[this.publishedInterfaces.size()]);
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import org.springframework.util.PatternMatchUtils;
/**
* Pointcut bean for simple method name matches, as alternative to regexp patterns.
* Does not handle overloaded methods: all methods with a given name will be eligible.
* Does not handle overloaded methods: all methods *with a given name will be eligible.
*
* @author Juergen Hoeller
* @author Rod Johnson
@@ -94,7 +94,7 @@ public abstract class Pointcuts {
@SuppressWarnings("serial")
private static class SetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
public static final SetterPointcut INSTANCE = new SetterPointcut();
public static SetterPointcut INSTANCE = new SetterPointcut();
@Override
public boolean matches(Method method, Class<?> targetClass) {
@@ -115,7 +115,7 @@ public abstract class Pointcuts {
@SuppressWarnings("serial")
private static class GetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
public static final GetterPointcut INSTANCE = new GetterPointcut();
public static GetterPointcut INSTANCE = new GetterPointcut();
@Override
public boolean matches(Method method, Class<?> targetClass) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,10 +36,10 @@ import org.springframework.util.Assert;
public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMatcherPointcut
implements PointcutAdvisor, Ordered, Serializable {
private Advice advice;
private int order = Integer.MAX_VALUE;
private Advice advice;
/**
* Create a new StaticMethodMatcherPointcutAdvisor,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -22,6 +22,7 @@ import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Simple Pointcut that looks for a specific Java 5 annotation
@@ -45,15 +46,16 @@ public class AnnotationMatchingPointcut implements Pointcut {
* @param classAnnotationType the annotation type to look for at the class level
*/
public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType) {
this(classAnnotationType, false);
this.classFilter = new AnnotationClassFilter(classAnnotationType);
this.methodMatcher = MethodMatcher.TRUE;
}
/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* @param classAnnotationType the annotation type to look for at the class level
* @param checkInherited whether to also check the superclasses and interfaces
* as well as meta-annotations for the annotation type
* @see AnnotationClassFilter#AnnotationClassFilter(Class, boolean)
* @param checkInherited whether to explicitly check the superclasses and
* interfaces for the annotation type as well (even if the annotation type
* is not marked as inherited itself)
*/
public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType, boolean checkInherited) {
this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited);
@@ -107,14 +109,21 @@ public class AnnotationMatchingPointcut implements Pointcut {
if (!(other instanceof AnnotationMatchingPointcut)) {
return false;
}
AnnotationMatchingPointcut otherPointcut = (AnnotationMatchingPointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
AnnotationMatchingPointcut that = (AnnotationMatchingPointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
}
@Override
public int hashCode() {
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
int code = 17;
if (this.classFilter != null) {
code = 37 * code + this.classFilter.hashCode();
}
if (this.methodMatcher != null) {
code = 37 * code + this.methodMatcher.hashCode();
}
return code;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
private String targetBeanName;
/** Class of the target */
private volatile Class<?> targetClass;
private Class<?> targetClass;
/**
* BeanFactory that owns this TargetSource. We need to hold onto this
@@ -120,28 +120,21 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public Class<?> getTargetClass() {
Class<?> targetClass = this.targetClass;
if (targetClass != null) {
return targetClass;
}
synchronized (this) {
// Full check within synchronization, entering the BeanFactory interaction algorithm only once...
targetClass = this.targetClass;
if (targetClass == null && this.beanFactory != null) {
// Determine type of the target bean.
targetClass = this.beanFactory.getType(this.targetBeanName);
if (targetClass == null) {
if (logger.isTraceEnabled()) {
logger.trace("Getting bean with name '" + this.targetBeanName + "' for type determination");
}
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
targetClass = beanInstance.getClass();
public synchronized Class<?> getTargetClass() {
if (this.targetClass == null && this.beanFactory != null) {
// Determine type of the target bean.
this.targetClass = this.beanFactory.getType(this.targetBeanName);
if (this.targetClass == null) {
if (logger.isTraceEnabled()) {
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
}
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
if (beanInstance != null) {
this.targetClass = beanInstance.getClass();
}
this.targetClass = targetClass;
}
return targetClass;
}
return this.targetClass;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -39,7 +39,7 @@ import org.springframework.aop.TargetSource;
public abstract class AbstractRefreshableTargetSource implements TargetSource, Refreshable {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
protected Log logger = LogFactory.getLog(getClass());
protected Object targetObject;
@@ -6,5 +6,4 @@ http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframewor
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.2.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.3.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
@@ -1,409 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/aop"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/aop"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's AOP support.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="config">
<xsd:annotation>
<xsd:documentation><![CDATA[
A section (compartmentalization) of AOP-specific configuration (including
aspects, pointcuts, etc).
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="pointcut" type="pointcutType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.Advisor"><![CDATA[
A named advisor definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="aspect" type="aspectType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named aspect definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="aspectj-autoproxy">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
Enables the use of the @AspectJ style of Spring AOP.
See org.springframework.context.annotation.EnableAspectJAutoProxy Javadoc
for information on code-based alternatives to this XML element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates that only @AspectJ beans with names matched by the (regex)
pattern will be considered as defining aspects to use for Spring autoproxying.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scoped-proxy">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.scope.ScopedProxyFactoryBean"><![CDATA[
Marks a bean definition as being a scoped proxy.
A bean marked as such will be exposed via a proxy, with the 'real'
bean instance being retrieved from some other source (such as a
HttpSession) as and when required.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? This is the default; in order to
switch to standard Java interface-based proxies, turn this flag to "false".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="aspectType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="pointcut" type="pointcutType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="declare-parents" type="declareParentsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Allows this aspect to introduce additional interfaces that the advised
object will transparently implement.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="before" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A before advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after-returning" type="afterReturningAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after-returning advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after-throwing" type="afterThrowingAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after-throwing advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="around" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An around advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for an aspect.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the (backing) bean that encapsulates the aspect.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:token">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this aspect when multiple
advice executes at a specific joinpoint.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="includeType">
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.util.regex.Pattern"><![CDATA[
The regular expression defining which beans are to be included in the
list of @AspectJ beans; beans with names matched by the pattern will
be included.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="pointcutType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a pointcut.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expression" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The pointcut expression.
For example : 'execution(* com.xyz.myapp.service.*.*(..))'
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="declareParentsType">
<xsd:attribute name="types-matching" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.TypePatternClassFilter"><![CDATA[
The AspectJ type expression that defines what types (classes) the
introduction is restricted to.
An example would be 'org.springframework.beans.ITestBean+'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="implement-interface" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The fully qualified name of the interface that will be introduced.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-impl" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The fully qualified name of the class that will be instantiated to serve
as the default implementation of the introduced interface.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="delegate-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to the bean that will serve
as the default implementation of the introduced interface.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="basicAdviceType">
<xsd:attribute name="pointcut" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The associated pointcut expression.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of an associated pointcut definition.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="method" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method that defines the logic of the advice.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="arg-names" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma-delimited list of advice method argument (parameter) names
that will be matched from pointcut parameters.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="afterReturningAdviceType">
<xsd:complexContent>
<xsd:extension base="basicAdviceType">
<xsd:attribute name="returning" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method parameter to which the return value must
be passed.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="afterThrowingAdviceType">
<xsd:complexContent>
<xsd:extension base="basicAdviceType">
<xsd:attribute name="throwing" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method parameter to which the thrown exception must
be passed.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="advisorType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.aop.Advisor"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="advice-ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to an advice bean.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.aopalliance.aop.Advice"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
A pointcut expression.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to a pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:token">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this advice when multiple
advice executes at a specific joinpoint.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="pointcutRefType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
</xsd:schema>
@@ -307,8 +307,7 @@ public class AspectJAdviceParameterNameDiscovererTests {
try {
discoverer.getParameterNames(m);
fail("Expecting " + exceptionType.getName() + " with message '" + message + "'");
}
catch (RuntimeException expected) {
} catch (RuntimeException expected) {
assertEquals("Expecting exception of type " + exceptionType.getName(),
exceptionType, expected.getClass());
assertEquals("Exception message does not match expected", message, expected.getMessage());
@@ -215,8 +215,7 @@ public final class MethodInvocationProceedingJoinPointTests {
itb.setSpouse(new TestBean());
try {
itb.unreliableFileOperation();
}
catch (IOException ex) {
} catch (IOException ex) {
// we don't realy care...
}
}
@@ -1,19 +1,3 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aspectj;
import java.lang.annotation.Documented;
@@ -113,14 +97,12 @@ public class TrickyAspectJPointcutExpressionTests {
try {
bean.sayHello();
fail("Expected exception");
}
catch (TestException ex) {
assertEquals(message, ex.getMessage());
} catch (TestException e) {
assertEquals(message, e.getMessage());
}
assertEquals(1, logAdvice.getCountThrows());
}
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
/**
@@ -133,15 +115,14 @@ public class TrickyAspectJPointcutExpressionTests {
}
@SuppressWarnings("serial")
public static class TestException extends RuntimeException {
public TestException(String string) {
super(string);
}
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@@ -150,23 +131,18 @@ public class TrickyAspectJPointcutExpressionTests {
public static @interface Log {
}
public static interface TestService {
public String sayHello();
}
@Log
public static class TestServiceImpl implements TestService {
@Override
public String sayHello() {
throw new TestException("TestServiceImpl");
}
}
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
private int countBefore = 0;
@@ -178,9 +154,9 @@ public class TrickyAspectJPointcutExpressionTests {
countBefore++;
}
public void afterThrowing(Exception ex) throws Throwable {
public void afterThrowing(Exception e) throws Throwable {
countThrows++;
throw ex;
throw e;
}
public int getCountBefore() {
@@ -195,6 +171,7 @@ public class TrickyAspectJPointcutExpressionTests {
countThrows = 0;
countBefore = 0;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -693,11 +693,6 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
return new AspectMetadata(PerTypeWithinAspect.class, "perTypeWithin");
}
@Override
public Object getAspectCreationMutex() {
return this;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -37,26 +37,26 @@ import static org.junit.Assert.*;
* @author Juergen Hoeller
* @author Chris Beams
*/
public class ArgumentBindingTests {
public final class ArgumentBindingTests {
@Test(expected = IllegalArgumentException.class)
@Test(expected=IllegalArgumentException.class)
public void testBindingInPointcutUsedByAdvice() {
TestBean tb = new TestBean();
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
proxyFactory.addAspect(NamedPointcutWithArgs.class);
ITestBean proxiedTestBean = proxyFactory.getProxy();
proxiedTestBean.setName("Supercalifragalisticexpialidocious");
ITestBean proxiedTestBean = (ITestBean) proxyFactory.getProxy();
proxiedTestBean.setName("Supercalifragalisticexpialidocious"); // should throw
}
@Test(expected = IllegalStateException.class)
@Test(expected=IllegalStateException.class)
public void testAnnotationArgumentNameBinding() {
TransactionalBean tb = new TransactionalBean();
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
proxiedTestBean.doInTransaction();
ITransactionalBean proxiedTestBean = (ITransactionalBean) proxyFactory.getProxy();
proxiedTestBean.doInTransaction(); // should throw
}
@Test
@@ -71,7 +71,6 @@ public class ArgumentBindingTests {
assertEquals("formal", pnames[0]);
}
public void methodWithOneParam(String aParam) {
}
@@ -101,6 +100,9 @@ public class ArgumentBindingTests {
}
/**
* @author Juergen Hoeller
*/
@Aspect
class PointcutWithAnnotationArgument {
@@ -113,6 +115,9 @@ class PointcutWithAnnotationArgument {
}
/**
* @author Adrian Colyer
*/
@Aspect
class NamedPointcutWithArgs {
@@ -16,13 +16,13 @@
package org.springframework.aop.aspectj.annotation;
import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Ignore;
import org.junit.Test;
import test.aop.PerThisAspect;
@@ -80,18 +80,7 @@ public class AspectProxyFactoryTests {
}
@Test
@SuppressWarnings("unchecked")
public void testSerializable() throws Exception {
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
proxyFactory.addAspect(LoggingAspectOnVarargs.class);
ITestBean proxy = proxyFactory.getProxy();
assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C));
ITestBean tb = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
assertTrue(tb.doWithVarargs(MyEnum.A, MyOtherEnum.C));
}
@Test
@SuppressWarnings("unchecked")
@Ignore // InstantiationModelAwarePointcutAdvisorImpl not serializable yet
public void testWithInstance() throws Exception {
MultiplyReturnValue aspect = new MultiplyReturnValue();
int multiple = 3;
@@ -144,8 +133,7 @@ public class AspectProxyFactoryTests {
}
@SuppressWarnings("serial")
public static class TestBean implements ITestBean, Serializable {
public static class TestBean implements ITestBean {
private int age;
@@ -183,8 +171,7 @@ public class AspectProxyFactoryTests {
@Aspect
@SuppressWarnings("serial")
public static class LoggingAspectOnVarargs implements Serializable {
public static class LoggingAspectOnVarargs {
@Around("execution(* doWithVarargs(*))")
public Object doLog(ProceedingJoinPoint pjp) throws Throwable {
@@ -206,9 +193,11 @@ public class AspectProxyFactoryTests {
}
/**
* @author Rod Johnson
*/
@Aspect
@SuppressWarnings("serial")
class MultiplyReturnValue implements Serializable {
class MultiplyReturnValue {
private int multiple = 2;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -16,6 +16,8 @@
package org.springframework.aop.framework;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
@@ -32,7 +34,7 @@ import static org.junit.Assert.*;
* @author Rod Johnson
* @author Chris Beams
*/
public class AopProxyUtilsTests {
public final class AopProxyUtilsTests {
@Test
public void testCompleteProxiedInterfacesWorksWithNull() {
@@ -123,10 +125,15 @@ public class AopProxyUtilsTests {
assertEquals(Comparable.class, userInterfaces[1]);
}
@Test(expected = IllegalArgumentException.class)
@Test(expected=IllegalArgumentException.class)
public void testProxiedUserInterfacesWithNoInterface() {
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[0],
(proxy1, method, args) -> null);
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
AopProxyUtils.proxiedUserInterfaces(proxy);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 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.
@@ -16,8 +16,6 @@
package org.springframework.aop.framework;
import java.util.ArrayList;
import java.util.List;
import javax.accessibility.Accessible;
import javax.swing.JFrame;
import javax.swing.RootPaneContainer;
@@ -33,8 +31,6 @@ import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.Order;
import org.springframework.tests.TimeStamped;
import org.springframework.tests.aop.advice.CountingBeforeAdvice;
import org.springframework.tests.aop.interceptor.NopInterceptor;
@@ -53,7 +49,7 @@ import static org.junit.Assert.*;
* @author Chris Beams
* @since 14.05.2003
*/
public class ProxyFactoryTests {
public final class ProxyFactoryTests {
@Test
public void testIndexOfMethods() {
@@ -341,34 +337,6 @@ public class ProxyFactoryTests {
assertTrue(proxy instanceof Accessible);
}
@Test
public void testInterfaceProxiesCanBeOrderedThroughAnnotations() {
Object proxy1 = new ProxyFactory(new A()).getProxy();
Object proxy2 = new ProxyFactory(new B()).getProxy();
List<Object> list = new ArrayList<Object>(2);
list.add(proxy1);
list.add(proxy2);
AnnotationAwareOrderComparator.sort(list);
assertSame(proxy2, list.get(0));
assertSame(proxy1, list.get(1));
}
@Test
public void testTargetClassProxiesCanBeOrderedThroughAnnotations() {
ProxyFactory pf1 = new ProxyFactory(new A());
pf1.setProxyTargetClass(true);
ProxyFactory pf2 = new ProxyFactory(new B());
pf2.setProxyTargetClass(true);
Object proxy1 = pf1.getProxy();
Object proxy2 = pf2.getProxy();
List<Object> list = new ArrayList<Object>(2);
list.add(proxy1);
list.add(proxy2);
AnnotationAwareOrderComparator.sort(list);
assertSame(proxy2, list.get(0));
assertSame(proxy1, list.get(1));
}
@SuppressWarnings("serial")
private static class TimestampIntroductionInterceptor extends DelegatingIntroductionInterceptor
@@ -393,22 +361,4 @@ public class ProxyFactoryTests {
}
}
@Order(2)
public static class A implements Runnable {
@Override
public void run() {
}
}
@Order(1)
public static class B implements Runnable{
@Override
public void run() {
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public final class ConcurrencyThrottleInterceptorTests {
public void testSerializable() throws Exception {
DerivedTestBean tb = new DerivedTestBean();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(ITestBean.class);
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
proxyFactory.addAdvice(cti);
proxyFactory.setTarget(tb);
@@ -75,7 +75,7 @@ public final class ConcurrencyThrottleInterceptorTests {
private void testMultipleThreads(int concurrencyLimit) {
TestBean tb = new TestBean();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(ITestBean.class);
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
cti.setConcurrencyLimit(concurrencyLimit);
proxyFactory.addAdvice(cti);
@@ -95,7 +95,7 @@ public final class ConcurrencyThrottleInterceptorTests {
ex.printStackTrace();
}
threads[i] = new ConcurrencyThread(proxy,
i % 2 == 0 ? new OutOfMemoryError() : new IllegalStateException());
i % 2 == 0 ? (Throwable) new OutOfMemoryError() : (Throwable) new IllegalStateException());
threads[i].start();
}
for (int i = 0; i < NR_OF_THREADS; i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -83,7 +83,7 @@ public final class CustomizableTraceInterceptorTests {
public void testSunnyDayPathLogsCorrectly() throws Throwable {
MethodInvocation methodInvocation = mock(MethodInvocation.class);
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(methodInvocation.getThis()).willReturn(this);
Log log = mock(Log.class);
@@ -101,7 +101,7 @@ public final class CustomizableTraceInterceptorTests {
MethodInvocation methodInvocation = mock(MethodInvocation.class);
IllegalArgumentException exception = new IllegalArgumentException();
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(methodInvocation.getThis()).willReturn(this);
given(methodInvocation.proceed()).willThrow(exception);
@@ -61,8 +61,7 @@ public final class DebugInterceptorTests {
try {
interceptor.invoke(methodInvocation);
fail("Must have propagated the IllegalArgumentException.");
}
catch (IllegalArgumentException expected) {
} catch (IllegalArgumentException expected) {
}
checkCallCountTotal(interceptor);

Some files were not shown because too many files have changed in this diff Show More