Compare commits

...
Author SHA1 Message Date
Spring Buildmaster 952ebf8ce1 Release version 5.1.10.RELEASE 2019-09-28 11:27:24 +00:00
Sam Brannen 7d126d3288 Improve documentation regarding "annotated classes"
See gh-23638
2019-09-26 10:26:36 +02:00
Rossen Stoyanchev e9dc5160b9 Use correct log level
See gh-23534
2019-09-26 07:00:27 +01:00
Juergen Hoeller 3616e96792 Upgrade to SLF4J 1.7.28, Groovy 2.5.8, RxJava 2.2.12, Joda-Time 2.10.4, Rome 1.12.2, OkHttp 3.14.3, Apache HttpClient 4.5.10, Apache Johnzon 1.1.13 2019-09-25 22:27:41 +02:00
Juergen Hoeller 357beb24bc Polishing 2019-09-25 22:15:07 +02:00
Rossen Stoyanchev 17c423f5af Support for sameSite attribute in WebFlux
Bypass server cookie and write Set-Cookie header directly for Reactor
Netty, and Servlet API which do not provide options.

For Undertow use the sameSite attribute.

Closes gh-23693
2019-09-25 17:16:48 +01:00
Juergen Hoeller b1ed0511f7 Upgrade to Tomcat 9.0.26, Undertow 2.0.26, Hibernate ORM 5.3.12
Includes Netty 4.1.39 (aligned with Reactor) and Checkstyle 8.24.
2019-09-25 12:15:02 +02:00
Juergen Hoeller bb6f9bb6d4 Polishing 2019-09-25 12:14:48 +02:00
Juergen Hoeller 0519a2ff3c Exclude jdk package in ShadowingClassLoader (JDK 11 compatibility)
Closes gh-23641
2019-09-25 12:11:33 +02:00
Juergen Hoeller 6a08bfdff7 Avoid unnecessary synchronization for non-existent missing caches
Closes gh-23635
2019-09-25 12:10:23 +02:00
Juergen Hoeller da44a247cb Efficient concurrency in MethodOverrides through CopyOnWriteArraySet
Also restores immediate MethodOverrides instance in AbstractBeanDefinition, avoiding potential lazy-init race condition.

Closes gh-23448
2019-09-25 12:09:16 +02:00
Juergen Hoeller 20fc7e178a Consistent equality check for parent name and indexed arguments
Closes gh-23593
2019-09-25 12:07:29 +02:00
Stephane Nicoll 31c881468c Upgrade to Reactor Californium-SR12
Closes gh-23694
2019-09-25 08:46:15 +02:00
Rossen Stoyanchev 955000699a Add getRawStatusCode() to ExchangeResult
Closes gh-23630
2019-09-24 12:58:52 +01:00
Rossen Stoyanchev 99d9dacc4f Log sendBufferSizeLimit exceeded at warn
Closes gh-23534
2019-09-24 12:09:41 +01:00
Rossen Stoyanchev 2794264480 Fix JettyRequestUpgradeStrategy initialization bug
Closes gh-23313
2019-09-24 11:34:46 +01:00
Rossen Stoyanchev 4edc7196fb Refine disconnected client handling in WebFlux
If an error looks like a "disconnected client" but the response is not
yet committed then it can't be an I/O error from writing to the server
response. It is most likely as a result of a remote call as part of
request handling.

Not setting the response to 500 in this case results in a 200 response
status despite the error. Even if it was an I/O error from the server
response, setting the status won't impact a failed response.

Closes gh-23319
2019-09-24 11:09:42 +01:00
Sam Brannen 8f6846827d Ensure ClassFilter and MethodMatcher implementations are cacheable
While resolving the regression raised in gh-23571, it came to our
attention that not all of our ClassFilter and MethodMatcher
implementations were properly cacheable with CGLIB generated proxies
due to missing (or improper) equals() and hashCode() implementations.

Although such deficiencies may not manifest themselves as bugs in Core
Spring's default arrangements, these might cause issues in custom
arrangements in user applications.

This commit addresses this by ensuring that ClassFilter and
MethodMatcher implementations properly implement equals() and
hashCode(). In addition, missing toString() implementations have been
added to improve diagnostics for logging and debugging.

Closes gh-23659
2019-09-19 15:35:17 +02:00
Sam Brannen b2aad1c3b1 Ensure bean definitions can be removed concurrently
Prior to this commit, concurrent invocations of
DefaultListableBeanFactory.removeBeanDefinition() could result in a
NullPointerException.

This commit fixes this by adding an appropriate not-null check in
resetBeanDefinition().

Closes gh-23542
2019-09-17 13:09:08 +02:00
Brian Clozel ca2b2f5533 Wait for complete disposal of Reactor Netty resources
Fixes gh-23631
2019-09-17 09:49:05 +02:00
Stephane Nicoll b65984a078 Consume getProtocolResolvers() rather than internal list
This commit makes sure that DefaultResourceLoader consistently use
getProtocolResolvers() to access additional protocol resolvers. This
allows subclasses to define how the list is provided.

Closes gh-23564
2019-09-16 14:35:00 +02:00
Sam Brannen b1b25fab00 Fix Checkstyle violation 2019-09-16 13:45:37 +02:00
Phillip Webb e9454b8b11 Update checkstyle import rule
Update the checkstyle rule to enforce the blank line between `java`
and `javax`.

See gh-23539
2019-09-16 13:45:28 +02:00
Phillip WebbandSam Brannen d945ae9191 Add blank line between java and javax imports
See gh-23539

Co-authored-by: Sam Brannen <sbrannen@pivotal.io>
2019-09-16 13:41:59 +02:00
Sam BrannenandSebastien Deleuze d09f537699 Annotate Object#equals parameter with @nullable
See gh-23093

Co-authored-by: Sebastien Deleuze <sdeleuze@pivotal.io>
2019-09-16 12:43:13 +02:00
Juergen Hoeller c8f20815ef Revise LinkedCaseInsensitiveMap's lazy key/value/entry collections
Closes gh-22926
2019-09-16 12:38:46 +02:00
Juergen Hoeller 60976e4116 Add missing nullable declarations
See gh-22821
2019-09-16 12:37:49 +02:00
Sam Brannen bd28bb1f56 Add additional tests for HttpHeaders.keySet() operations
See gh-22821
2019-09-16 12:36:05 +02:00
Phillip Webb aa69703f3b Fix LinkedCaseInsensitiveMap collection methods
Ensure that results returned from keySet, entrySet & values are tracked
to remove case insensitive keys from the source map.

Closes gh-22821
2019-09-16 12:36:05 +02:00
Sam Brannen a871f609ea Introduce failing tests for HttpHeaders
See gh-22821
2019-09-16 12:28:38 +02:00
Rossen Stoyanchev f259fda8eb Fix checkstyle violations 2019-09-12 21:46:42 +01:00
Rossen Stoyanchev 23be5dfb0e Handle invalid MediaType in Jetty/Tomcat adapters
See: gh-23553
2019-09-12 20:58:47 +01:00
Rossen Stoyanchev b7eaab4c5d Handle very early completion notification
On a Servlet container a completion notification may come at any time
even in the UNSUBSCRIBED state, i.e. before the write Publisher has
called onSubscribe.

See: gh-23553
2019-09-12 14:14:11 +01:00
Rossen Stoyanchev 07b0fa132e doFilterNestedErrorDispatch delegates to filter chain
Closes: gh-23596
2019-09-12 13:42:12 +01:00
Rossen Stoyanchev 6eb0e9e44b Unwrap decorated request or response
Closes: gh-23598
2019-09-12 13:42:12 +01:00
GungnirLaevatain 9db4118180 Fix DefaultListableBeanFactory#copyConfigurationFrom
Prior to this commit, the copyConfigurationFrom(ConfigurableBeanFactory)
method in DefaultListableBeanFactory cloned its own AutowireCandidateResolver
type instead of the resolver type from the supplied ConfigurableBeanFactory.

This commit fixes that by cloning the resolver type from the supplied
ConfigurableBeanFactory.

Closes gh-23569
2019-09-12 13:58:24 +02:00
Arjen Poutsma b159ef6019 Make MockClientHttpResponse uses raw status code
This commit make sure that MockClientHttpResponse does not use
HttpStatus, but the raw status code.

Closes gh-23599
2019-09-11 10:41:01 +02:00
Sam Brannen 961010055e Support trailing comment in DTD declaration in XML config
Prior to this commit, Spring failed to determine that an XML config file
was DTD-based if the DTD declaration was followed by a comment.

This commit fixes this by modifying the consumeCommentTokens(String)
algorithm in XmlValidationModeDetector so that both leading and trailing
comments are properly consumed without losing any XML content.

Closes gh-23605
2019-09-09 16:18:21 +02:00
Sam Brannen a7aecbb4dc Ensure spring-test test tasks are UP-TO-DATE
See also: 69214429df and eec183ef28
2019-09-05 15:06:12 +02:00
Sam Brannen d036b5a283 Do not treat void and Void as simple types in BeanUtils
Prior to this commit, the isSimpleProperty() and isSimpleValueType()
methods in BeanUtils treated void and Void as simple types; however,
doing so does not make sense in this context, since void implies the
lack of a property or value.

This commit addresses this by explicitly excluding void and Void in the
logic in isSimpleValueType().

This commit also simplifies the implementation of
ViewResolutionResultHandler.supports(HandlerResult) to take advantage
of this change.

Closes gh-23573
2019-09-04 15:48:40 +02:00
Brian Clozel 3a132f8c3c Revert Artifactory Gradle plugin configuration
This commit reverts all artifactory configuration changes in this
branch. A new build plan has been created for the master branch which is
tailored for the latest Gradle changes made on that branch.
2019-09-04 11:21:41 +02:00
Brian Clozel 1187fea65c Fix Artifactory Gradle plugin configuration
This commit adds a missing dependency from the artifactoryPublish task
to the "install" task as POMs are currently missing from the published
artifacts and they are generated with the "install" task here.
2019-09-04 10:26:22 +02:00
Brian Clozel e26cdfe21e Fix Artifactory Gradle plugin configuration 2019-09-04 10:00:13 +02:00
Sam Brannen f37ec90f2f Consider Void.class a primitive wrapper in ClassUtils
Prior to this commit, ClassUtils.isPrimitiveOrWrapper() and
ClassUtils.isPrimitiveWrapper() did not return true for Void.class.
However, ClassUtils.isPrimitiveOrWrapper() did return true for
void.class. This lacking symmetry is inconsistent and can lead to bugs
in reflective code.

See: https://github.com/spring-projects/spring-data-r2dbc/issues/159

This commit addresses this by adding an entry for Void.class -> void.class
in the internal primitiveWrapperTypeMap in ClassUtils.

Closes gh-23572
2019-09-03 14:02:24 +02:00
Arjen Poutsma f748b1e68d Fix timing bug in DataBufferUtils::readAsynchronousFileChannel
This commit makes sure that reading is enabled after the current
signal has been processed, not while is is being processed. The bug
was only apparent while using the JettyClientHttpConnector, which
requests new elements continuously, even after the end of the
stream has been signalled.
2019-09-02 15:13:22 +02:00
Sam Brannen 9729b460f1 Retain entry set order in read-only HttpHeaders
Prior to this commit, the entry set of read-only HttpHeaders lost the
original headers' ordering.

The changes in commit ce7278aaf4 introduced a regression in the read-only
HttpHeaders support. Specifically, the implementation of entrySet() in
the internal ReadOnlyHttpHeaders class converted the original entry set
to an immutable, non-ordered set of immutable entries.

This commit fixes this issue by converting the original entry set to an
immutable, ordered set of immutable entries.

Closes gh-23551
2019-08-31 13:10:07 +02:00
Sam Brannen a496353770 Delete dead code 2019-08-31 11:44:04 +02:00
Arjen Poutsma d709a69ff1 Remove buffering of encoded parts in MultipartHttpMessageWriter
Closes gh-23518
2019-08-29 16:34:36 +02:00
Arjen Poutsma 2c5958e191 Support back pressure in DataBufferUtils::readAsynchronousFileChannel
This commit adds support for back pressure in the ReadCompletionHandler,
as used by DataBufferUtils::readAsynchronousFileChannel.

See gh-23518
2019-08-29 16:34:36 +02:00
Rossen Stoyanchev 4f4b9f6b1b Fix checkstyle violation 2019-08-29 15:53:05 +03:00
Rossen Stoyanchev 4e4ec266b2 Adjust error response in ResourceUrlEncodingFilter
Failure to find the lookup path now results in 400 instead of 500
reflecting the presence of some issue with the input path.

Closes gh-23508
2019-08-29 14:58:03 +03:00
Rossen Stoyanchev bd8f94ad7b Upgrade to Jetty 9.4.20.v20190813 2019-08-29 11:11:17 +03:00
Rossen Stoyanchev c2d71922d7 Fix for change in Jetty 9.4.20.v20190813
Closes gh-23500
2019-08-29 10:52:16 +03:00
Rossen Stoyanchev 88e9dcef0c Consistently apply onCompletion/onError handling
Follow-up change in addition to dd22b8fd.

See gh-23096
2019-08-29 09:20:50 +03:00
Brian Clozel 4a4edeb97f Apply Artifactory Gradle plugin to build
Since gh-23282, our CI does not apply automatically the Artifactory
Gradle plugin during our build and we're now applying it "manually".
This commit backports this change since the build configuration is
shared between branches.

See gh-23282
2019-08-27 22:26:25 +02:00
Rossen Stoyanchev dd22b8fd39 Fix race condition with onCompletion/onError
Closes gh-23096
2019-08-27 21:43:33 +03:00
Sam Brannen 8189c90741 Allow Set-Cookie header to be overwritten in MockHttpServletResponse
Prior to this commit, there was no way to replace the Set-Cookie header
via MockHttpServletResponse. Specifically, an invocation of setHeader()
for the Set-Cookie header resulted in an additional Set-Cookie header
instead of replacing the existing one, which is in violation of the
contract for javax.servlet.http.HttpServletResponse.setHeader(...).

This commit refactors the internals of MockHttpServletResponse to ensure
that an existing Set-Cookie header is overwritten when set via an
invocation of setHeader(). This commit also verifies the expected
behavior for addHeader() and addCookie() with regard to multiple cookies.

Closes gh-23512
2019-08-27 17:20:38 +02:00
Sam Brannen 9d2a874e3f Introduce getOriginalBeanName(String) in ScopedProxyUtils
This commit introduces a utility method for retrieving the original
bean name for the target of a scoped proxy.

Closes gh-23514
2019-08-27 15:46:34 +02:00
Rossen Stoyanchev a7bb5ca473 Remove unnecessary iteration over headers
The use of LinkedCaseInsensitiveMap, going back to 3.0, makes it
unnecessary to iterate over keys which can cause
ConcurrentModificationException.

Closes gh-23460
2019-08-21 13:34:17 +03:00
Rossen Stoyanchev 6d8bf3466c Suppress decoding error for resource path
Closes gh-23463
2019-08-21 10:02:15 +03:00
Rossen Stoyanchev b86c11cc9b Respect existing content-length for HTTP HEAD
Closes gh-23484
2019-08-21 02:28:19 +03:00
Stephane Nicoll 122e2ca2ac Merge pull request #23437 from wyhasany
* pr/23437:
  Fix typo

Closes gh-23437
2019-08-09 09:37:00 +02:00
Michał Rowicki 806fcb3839 Fix typo
See gh-23437
2019-08-09 09:36:46 +02:00
Sam Brannen 30ebc3b8e2 Remove superfluous AnnotationAttributes#putIfAbsent implementation
Since Java 8, putIfAbsent() is a standard method in java.util.Map. We
therefore no longer need the custom implementation that overrides the
standard implementation in HashMap.
2019-08-06 18:10:13 +02:00
Sam Brannen a092dc055e Check for instanceof Throwable in AnnotationAttributes#assertNotException
Prior to this commit, AnnotationAttributes#assertNotException checked if
the attribute value was an instance of Exception. Although this was
typically sufficient, the scope was not always broad enough -- for
example, if AnnotationReadingVisitorUtils#convertClassValues stored a
Throwable in the map (such as a LinkageError).

This commit fixes this by checking for an instance of Throwable in
AnnotationAttributes#assertNotException.

Closes gh-23424
2019-08-06 18:06:00 +02:00
Rossen Stoyanchev 70be7117f3 Fix link to Spring AMQP and polish
Optimize section headings for dispaly in left hand navigation.
2019-08-02 16:32:01 +01:00
Spring Buildmaster f13a6d4f32 Next Development Version 2019-08-02 09:02:14 +00:00
Juergen Hoeller 7c2e2d40af Polishing 2019-08-02 01:39:02 +02:00
Juergen Hoeller d8e624e97e Consistent suppression of get/clearWarnings without target connection
See gh-23346
2019-08-02 01:19:16 +02:00
Juergen Hoeller 762ea3ea90 Document all remaining public methods on BeanDefinitionParserDelegate
Closes gh-23349
2019-08-01 15:26:11 +02:00
Juergen Hoeller 871bb57e02 TransactionAwareDataSourceProxy locally handles get/clearWarnings call
Closes gh-23346
2019-08-01 15:26:00 +02:00
Juergen Hoeller aebc485eda MethodParameter.equals properly checks overridden containing class
Closes gh-23352
2019-08-01 14:34:39 +02:00
Juergen Hoeller ea4f7d365f Deprecate logger field in HandlerMethodArgumentResolverComposite 2019-07-31 23:48:21 +02:00
Juergen Hoeller 438b40f6d7 Consistent ordering of WebClient.Builder methods 2019-07-31 23:48:14 +02:00
Juergen Hoeller 59064f0780 Upgrade to Undertow 2.0.23 and Apache Johnzon 1.1.12 2019-07-30 22:27:09 +02:00
Juergen Hoeller 960079e5f5 Retain non-null HttpStatus return value in Client(Http)Response
See gh-23366
2019-07-30 22:26:46 +02:00
Arjen Poutsma 29ef985411 Add support for non-standard status codes
Added support for status codes that do not occur in HttpStatus in
DefaultClientResponseBuilder and made ClientResponse::statusCode
ClientHttpResponse::getStatusCode @Nullable.

Closed gh-23366
2019-07-30 17:44:47 +02:00
Juergen Hoeller b2c56590dd Upgrade to Netty 4.1.38 and Checkstyle 8.23 2019-07-30 16:59:23 +02:00
Juergen Hoeller c4622dbebc Polishing 2019-07-30 16:59:01 +02:00
Juergen Hoeller 9a36027ae1 MethodParameter.equals checks nesting level and containing class
Closes gh-23352
2019-07-30 16:58:45 +02:00
Arjen Poutsma 6cb4b8bd43 Add onRawStatus to WebClient
- Add onRawStatus to WebClient.ResponseSpec, allowing users to deal with
  raw status codes that are not in HttpStatus.
- No longer throw an exception status codes not in HttpStatus.

Closes gh-23367
2019-07-30 15:10:33 +02:00
Rossen Stoyanchev 7b697266be PathPatternParser allows '-' in variables
The isJavaIdentifier check is not really required, but also seems
intuitive for variables to be Java identifier-like. This commit relaxes
the constraint a bit by also allowing "-".

Closes gh-23101
2019-07-30 12:04:47 +01:00
Rossen Stoyanchev 1d92755cc7 Remove custom handling of byte[] in DefaultStompSession
Closes gh-23358
2019-07-30 10:52:51 +01:00
Stephane Maldini 50a909908c Remove unnecessary flushOnEach (since reactor-netty 0.9) 2019-07-30 10:54:51 +02:00
Stephane Nicoll da54121ee0 Upgrade to Reactor Californium-SR10 2019-07-30 09:51:32 +02:00
Sam Brannen 5034d1e7b3 Introduce ServerHttpRequest.Builder.header() variant for setting headers
Prior to this commit, the `header(String, String)` method in the
ServerHttpRequest.Builder API actually added a header value instead of
setting or overriding a header value. Since this conflicted with the
stated behavior in the Javadoc as well as the original intention of the
method, we have decided to introduce an overloaded variant
`header(String, String...)` which accepts a var-args list of header
values to set or override.

In addition, this commit deprecates the existing `header(String, String)`
method for removal in Spring Framework 5.2.

In order not to be a breaking change for custom implementations of the
builder API, this commit implements the new `header(String, String...)`
method as an interface `default` method, with the intent to remove the
default implementation in Spring Framework 5.2

closes gh-23333
2019-07-25 13:02:09 +02:00
Stephane Nicoll 0f9c7934bb Merge pull request #23353 from izeye
* pr/23353:
  Add Javadoc since for Jaxb2XmlDecoder(MimeType...)

Closes gh-23353
2019-07-25 08:39:13 +02:00
Johnny Lim 946fc39d42 Add Javadoc since for Jaxb2XmlDecoder(MimeType...)
See gh-23353
2019-07-25 08:38:46 +02:00
Ryan Burke 78802d4277 Fix typo in webflux.adoc 2019-07-22 18:35:53 +02:00
Juergen Hoeller 92890232df Upgrade to OpenPDF 1.2.21, Rome 1.12.1, XStream 1.4.11.1
Includes updated javadoc links for 5.1.x branch.
2019-07-20 18:20:03 +02:00
Juergen Hoeller b1e8ed182e Polishing 2019-07-20 17:53:54 +02:00
Juergen Hoeller 0d37209b78 Document default message handling in MessageSource.getMessage variants 2019-07-20 16:23:31 +02:00
Juergen Hoeller 4a09b323b6 Apply getInterfaceMethodIfPossible without SecurityManager as well
Closes gh-23323
2019-07-20 16:11:17 +02:00
Juergen Hoeller 209c8505e6 Align forRawClassAssignableFromTypeVariable with 5.1 assertion style
See gh-23321
2019-07-20 16:10:49 +02:00
Phillip Webb e5bef10d85 Fix ResolvableType raw class isAssignable checks
Fix `isAssignable` for `ResolvableType.forRawClass` so that it can be
used with types backed by a `TypeVarible`. Prior to this commit the
rawClass value was used, which wouldn't always work.

Closes gh-23321
2019-07-20 13:23:21 +01:00
zheng.ren01@mljr.com f92b60c08f Only invoke getInterfaceMethodIfPossible() when security manager is used
Prior to this commit, AbstractAutowireCapableBeanFactory's
invokeCustomInitMethod() method invoked
ClassUtils.getInterfaceMethodIfPossible() even if the security manager
was not being used.

This commit ensures that getInterfaceMethodIfPossible() is only invoked
if the security manager is used.

Closes gh-23323
2019-07-20 13:30:57 +02:00
Rossen Stoyanchev a244675630 Merge pull request #23305' from AndreasKl/fowarded-prefix-causes-invalid-path into 5.1.x 2019-07-19 10:44:42 +01:00
Rossen Stoyanchev 153ac82380 Polish 2019-07-19 10:44:23 +01:00
Andreas Kluth 4973e110ee An empty X-Forwarded-Prefix with a path containing escape sequences leads to exceptions. 2019-07-19 10:44:23 +01:00
Rossen Stoyanchev 2b94205ba9 Update docs on multipart with RestTemplate
Replace docs on using MultipartBodyBuilder for the RestTemplate with
examples that show MultiValueMap. Originally the idea was to make
MultipartBodyBuilder accessible to the RestTemplate too, but with
support for async parts that's no longer a good fit.

Closes gh-23295
2019-07-19 10:43:50 +01:00
Juergen Hoeller 46e5b6f7af Upgrade to Tomcat 9.0.22, Checkstyle 8.22, Mockito 2.28.2 2019-07-17 23:26:07 +02:00
Juergen Hoeller f5daa657f4 Polishing 2019-07-17 23:25:50 +02:00
Juergen Hoeller 9ffdf05d77 Explicit javadoc note on publishEvent hand-off semantics
See gh-21025
2019-07-17 23:25:21 +02:00
Juergen Hoeller 18bfa6b003 Consider Hibernate Query.list() as query-terminating method
Closes gh-23248
2019-07-17 23:24:52 +02:00
Sam Brannen 74ddf1bee5 Improve documentation for @Autowired constructors
Prior to this commit, there was some ambiguity surrounding semantics
for @Autowired constructors and `required = true`, especially for
multiple @Autowired constructors.

This commit improves the documentation in the Javadoc for @Autowired as
well as in the reference manual.

Closes gh-23263
2019-07-17 18:55:58 +02:00
Rossen Stoyanchev 99c4a9eeba Filtering for nested ERROR dispatch
OncePerRequestFilter now has a doFilter method that allows separate
processing of nested ERROR dispatches. This is useful for filters
that wrap the request and response.

Closes gh-23196
2019-07-15 11:23:12 +01:00
Rossen Stoyanchev 235858e4e5 Exposes supported mime types in Jaxb2Decoder
Closes gh-23278
2019-07-13 11:00:43 +01:00
Stephane Nicoll 5089824245 Merge pull request #23274 from akun2014
* pr/23274:
  Fix typo in UrlPathHelper

Closes gh-23274
2019-07-11 09:54:54 +02:00
桂坤 81eb911c09 Fix typo in UrlPathHelper
See gh-23274
2019-07-11 09:54:03 +02:00
Sam Brannen 99758b56d3 Ensure Javadoc is generated using UTF-8 encoding
Fixes gh-23253
2019-07-09 18:22:11 +02:00
Sam Brannen db8be50161 Support empty target request path in FlashMap
Prior to this commit, if the user configured an empty path for the
targetRequestPath property of a FlashMap, the FlashMapManager threw a
StringIndexOutOfBoundsException when saving the output FlashMap for the
next request.

This commit fixes this by skipping the decoding and normalization of an
empty target request path.

Fixes gh-23240
2019-07-07 18:38:26 +02:00
Sam Brannen efab6eb55d Ignore empty entries when parsing MediaTypes and MimeTypes
Prior to Spring Framework 5.1.3, MimeTypeUtils.parseMimeTypes() and
MediaType.parseMediaTypes() ignored empty entries, but 5.1.3 introduced
a regression in that an empty entry -- for example, due to a trailing
comma in the list of media types in an HTTP Accept header -- would result
in a "406 Not Acceptable" response status.

This commit fixes this by filtering out empty entries before parsing
them into MimeType and MediaType instances. Empty entries are therefore
effectively ignored.

Fixes gh-23241
2019-07-07 12:39:46 +02:00
Juergen Hoeller 7a7d4109ac Polishing 2019-07-05 17:47:36 +02:00
Juergen Hoeller 53ebbb20f9 Upgrade to Netty 4.1.37 2019-07-05 17:08:46 +02:00
Juergen Hoeller 16deb3c50f Defensively register ReactiveReturnValueHandler for messaging methods
Closes gh-23207
2019-07-05 17:08:08 +02:00
Juergen Hoeller a1eae42fd0 Expose implementation method for annotation introspection purposes
Closes gh-23210
2019-07-05 17:07:44 +02:00
Juergen Hoeller 56cc0d02e9 Bean destruction exceptions consistently logged at warn level
Closes gh-23200
2019-07-05 17:07:22 +02:00
Juergen Hoeller aeef95938e SpringValidatorAdapter's ObjectError subclasses are serializable
Closes gh-23181
2019-07-05 17:07:01 +02:00
Rossen Stoyanchev 2aec175ccc Drain body after exception from applying onStatus
Closes gh-23230
2019-07-05 10:50:03 +01:00
Rossen Stoyanchev 2088a3d57b Document async requests with Spring MVC Test
Closes gh-19666
2019-07-05 10:30:02 +01:00
Rossen Stoyanchev 4e6e47b726 Earlier detection of token authentication
Use a callback to detect token authentication (via inteceptor) thus
avoiding a potential race between that detection after the message is
sent on the inbound channel (via Executor) and the processing of the
CONNECTED frame returned from the broker on the outbound channel.

Closes gh-23160
2019-07-03 15:24:27 +01:00
Rossen Stoyanchev 5af9a8edae Ensure WebSocketHttpRequestHandler writes headers
Closes gh-23179
2019-07-03 15:24:27 +01:00
Rossen Stoyanchev 6e79dcdc8e Merge pull request #23070 from L00kian/23060-fix 2019-07-02 09:33:13 +01:00
Rossen Stoyanchev 29b7659094 Polish 2019-07-02 09:32:07 +01:00
Ilya Lukyanovich 27b5d2b288 Optional @RequestPart Mono arg resolves to Mono.empty
Closes gh-23060
2019-07-02 09:32:07 +01:00
Sam Brannen ac29e9de6a Document that CacheManager.getCache() may create a new Cache
Prior to this commit, it was unclear that an invocation of getCache()
might potentially create a new Cache.

This commit updates the Javadoc to point out that concrete CacheManager
implementations may choose to create a new Cache at runtime if the Cache
does not already exist.

Closes gh-23193
2019-06-25 13:12:42 +03:00
Sam Brannen dda4dfb44b Clarify semantics of the PriorityOrdered interface
This commit clarifies the semantics of the PriorityOrdered interface
with respect to sorting sets of objects containing both PriorityOrdered
and plain Ordered objects.

Closes gh-23187
2019-06-25 10:40:55 +03:00
Juergen Hoeller 29dcd19971 Upgrade to AspectJ 1.9.4, RxJava 2.2.10, Jetty 9.4.19, Undertow 2.0.22
Includes Hibernate Validator 6.0.17 and renames "withoutJclOverSlf4j".
2019-06-22 16:49:40 +02:00
Rossen Stoyanchev 594c5806a6 Handle error in apply of writeFunction
Closes gh-23175
2019-06-21 14:15:14 +01:00
Sam Brannen 97bfb75fbc Polish documentation for @ControllerAdvice in reference manual 2019-06-21 12:45:08 +03:00
Sam Brannen ad915f4a26 Document that Ordered is not supported for @ControllerAdvice beans
Closes gh-23172
2019-06-21 12:39:34 +03:00
Sebastien Deleuze bcad276adb Fix Jackson documentation broken links
Closes gh-23153
2019-06-19 13:59:36 +02:00
Sebastien Deleuze bd568ea2f1 Document how to specify Jackson JSON view serialization hints
Closes gh-23150
2019-06-18 16:50:54 +02:00
Sam Brannen d18d4d865e Update Javadoc for HtmlUtils regarding Apache Commons Text
Closes gh-23122
2019-06-14 14:48:24 +03:00
Spring Buildmaster 108ce58025 Next Development Version 2019-06-13 14:04:56 +00:00
1049 changed files with 5192 additions and 1594 deletions
+15 -15
View File
@@ -17,7 +17,7 @@ plugins {
}
ext {
linkHomepage = "https://projects.spring.io/spring-framework"
linkHomepage = "https://spring.io/projects/spring-framework"
linkCi = "https://build.spring.io/browse/SPR"
linkIssue = "https://github.com/spring-projects/spring-framework/issues"
linkScmUrl = "https://github.com/spring-projects/spring-framework"
@@ -28,27 +28,27 @@ ext {
!it.name.equals("spring-build-src") && !it.name.equals("spring-framework-bom")
}
aspectjVersion = "1.9.3"
aspectjVersion = "1.9.4"
freemarkerVersion = "2.3.28"
groovyVersion = "2.5.7"
groovyVersion = "2.5.8"
hsqldbVersion = "2.4.1"
jackson2Version = "2.9.9"
jettyVersion = "9.4.18.v20190429"
jettyVersion = "9.4.20.v20190813"
junit5Version = "5.3.2"
kotlinVersion = "1.2.71"
log4jVersion = "2.11.2"
nettyVersion = "4.1.36.Final"
reactorVersion = "Californium-SR9"
nettyVersion = "4.1.39.Final"
reactorVersion = "Californium-SR12"
rxjavaVersion = "1.3.8"
rxjavaAdapterVersion = "1.2.1"
rxjava2Version = "2.2.9"
slf4jVersion = "1.7.26" // spring-jcl + consistent 3rd party deps
rxjava2Version = "2.2.12"
slf4jVersion = "1.7.28" // spring-jcl + consistent 3rd party deps
tiles3Version = "3.0.8"
tomcatVersion = "9.0.21"
undertowVersion = "2.0.21.Final"
tomcatVersion = "9.0.26"
undertowVersion = "2.0.26.Final"
gradleScriptDir = "${rootProject.projectDir}/gradle"
withoutJclOverSlf4J = {
withoutJclOverSlf4j = {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
}
@@ -139,11 +139,10 @@ configure(allprojects) { project ->
// classes with the "$" pattern; otherwise, using -Dtest.single=MyTests to
// run MyTests by itself will fail if MyTests contains any inner classes.
exclude(["**/Abstract*.class", '**/*$*'])
reports.junitXml.setDestination(file("$buildDir/test-results"))
}
checkstyle {
toolVersion = "8.21"
toolVersion = "8.24"
configDir = rootProject.file("src/checkstyle")
}
@@ -156,7 +155,7 @@ configure(allprojects) { project ->
testCompile("junit:junit:4.12") {
exclude group: "org.hamcrest", module: "hamcrest-core"
}
testCompile("org.mockito:mockito-core:2.27.0") {
testCompile("org.mockito:mockito-core:2.28.2") {
exclude group: "org.hamcrest", module: "hamcrest-core"
}
testCompile("com.nhaarman:mockito-kotlin:1.6.0") {
@@ -178,7 +177,7 @@ configure(allprojects) { project ->
"https://docs.oracle.com/javase/8/docs/api/",
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://glassfish.java.net/nonav/docs/v3/api/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
@@ -217,6 +216,7 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
javadoc {
description = "Generates project-level javadoc for use in -javadoc jar"
options.encoding = "UTF-8"
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
options.author = true
options.header = project.name
+1 -1
View File
@@ -1 +1 @@
version=5.1.8.BUILD-SNAPSHOT
version=5.1.10.RELEASE
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ task api(type: Javadoc) {
it.tasks.getByName("jar")
}
}
options.encoding = "UTF-8"
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
options.author = true
options.header = rootProject.description
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,11 @@ package org.springframework.aop;
* <p>Can be used as part of a {@link Pointcut} or for the entire
* targeting of an {@link IntroductionAdvisor}.
*
* <p>Concrete implementations of this interface typically should provide proper
* implementations of {@link Object#equals(Object)} and {@link Object#hashCode()}
* in order to allow the filter to be used in caching scenarios &mdash; for
* example, in proxies generated by CGLIB.
*
* @author Rod Johnson
* @see Pointcut
* @see MethodMatcher
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +40,11 @@ import java.lang.reflect.Method;
* in an interceptor chain, will have run, so any state changes they have produced in
* parameters or ThreadLocal state will be available at the time of evaluation.
*
* <p>Concrete implementations of this interface typically should provide proper
* implementations of {@link Object#equals(Object)} and {@link Object#hashCode()}
* in order to allow the matcher to be used in caching scenarios &mdash; for
* example, in proxies generated by CGLIB.
*
* @author Rod Johnson
* @since 11.11.2003
* @see Pointcut
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -735,6 +735,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
public int hashCode() {
return this.adviceMethod.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.adviceMethod;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import org.aspectj.weaver.tools.TypePatternMatcher;
import org.springframework.aop.ClassFilter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
@@ -29,6 +30,7 @@ import org.springframework.util.StringUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
@@ -113,4 +115,21 @@ public class TypePatternClassFilter implements ClassFilter {
result = StringUtils.replace(result, " or ", " || ");
return StringUtils.replace(result, " not ", " ! ");
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof TypePatternClassFilter &&
ObjectUtils.nullSafeEquals(this.typePattern, ((TypePatternClassFilter) other).typePattern)));
}
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.typePattern);
}
@Override
public String toString() {
return getClass().getName() + ": " + this.typePattern;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -327,10 +327,11 @@ class CglibAopProxy implements AopProxy, Serializable {
// TODO: small memory optimization 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);
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
this.fixedInterceptorMap.put(methods.toString(), x);
}
// Now copy both the callbacks from mainCallbacks
@@ -633,8 +634,8 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args,
this.targetClass, this.adviceChain, methodProxy);
MethodInvocation invocation = new CglibMethodInvocation(
proxy, this.target, method, args, this.targetClass, this.adviceChain, methodProxy);
// If we get here, we need to create a MethodInvocation.
Object retVal = invocation.proceed();
retVal = processReturnType(proxy, this.target, method, retVal);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
protected final Method method;
protected Object[] arguments = new Object[0];
protected Object[] arguments;
@Nullable
private final Class<?> targetClass;
@@ -158,7 +158,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,20 +23,25 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Utility class for creating a scoped proxy.
* Used by ScopedProxyBeanDefinitionDecorator and ClassPathBeanDefinitionScanner.
*
* <p>Used by ScopedProxyBeanDefinitionDecorator and ClassPathBeanDefinitionScanner.
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @since 2.5
*/
public abstract class ScopedProxyUtils {
private static final String TARGET_NAME_PREFIX = "scopedTarget.";
private static final int TARGET_NAME_PREFIX_LENGTH = TARGET_NAME_PREFIX.length();
/**
* Generate a scoped proxy for the supplied target bean, registering the target
@@ -45,6 +50,8 @@ public abstract class ScopedProxyUtils {
* @param registry the bean definition registry
* @param proxyTargetClass whether to create a target class proxy
* @return the scoped proxy definition
* @see #getTargetBeanName(String)
* @see #getOriginalBeanName(String)
*/
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
BeanDefinitionRegistry registry, boolean proxyTargetClass) {
@@ -93,11 +100,29 @@ public abstract class ScopedProxyUtils {
* Generate 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
* @see #getOriginalBeanName(String)
*/
public static String getTargetBeanName(String originalBeanName) {
return TARGET_NAME_PREFIX + originalBeanName;
}
/**
* Get the original bean name for the provided {@linkplain #getTargetBeanName
* target bean name}.
* @param targetBeanName the target bean name for the scoped proxy
* @return the original bean name
* @throws IllegalArgumentException if the supplied bean name does not refer
* to the target of a scoped proxy
* @since 5.1.10
* @see #getTargetBeanName(String)
* @see #isScopedTarget(String)
*/
public static String getOriginalBeanName(String targetBeanName) {
Assert.isTrue(isScopedTarget(targetBeanName), () -> "bean name '" +
targetBeanName + "' does not refer to the target of a scoped proxy");
return targetBeanName.substring(TARGET_NAME_PREFIX_LENGTH);
}
/**
* Specify if the {@code beanName} is the name of a bean that references the target
* bean within a scoped proxy.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.springframework.aop.support;
import java.io.Serializable;
import java.util.Arrays;
import org.springframework.aop.ClassFilter;
import org.springframework.util.Assert;
@@ -28,6 +29,7 @@ import org.springframework.util.ObjectUtils;
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
* @since 11.11.2003
* @see MethodMatchers
* @see Pointcuts
@@ -89,9 +91,9 @@ public abstract class ClassFilters {
@SuppressWarnings("serial")
private static class UnionClassFilter implements ClassFilter, Serializable {
private ClassFilter[] filters;
private final ClassFilter[] filters;
public UnionClassFilter(ClassFilter[] filters) {
UnionClassFilter(ClassFilter[] filters) {
this.filters = filters;
}
@@ -115,6 +117,12 @@ public abstract class ClassFilters {
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.filters);
}
@Override
public String toString() {
return getClass().getName() + ": " + Arrays.toString(this.filters);
}
}
@@ -124,9 +132,9 @@ public abstract class ClassFilters {
@SuppressWarnings("serial")
private static class IntersectionClassFilter implements ClassFilter, Serializable {
private ClassFilter[] filters;
private final ClassFilter[] filters;
public IntersectionClassFilter(ClassFilter[] filters) {
IntersectionClassFilter(ClassFilter[] filters) {
this.filters = filters;
}
@@ -150,6 +158,12 @@ public abstract class ClassFilters {
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.filters);
}
@Override
public String toString() {
return getClass().getName() + ": " + Arrays.toString(this.filters);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,12 +24,15 @@ import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
/**
* Convenient class for building up pointcuts. All methods return
* ComposablePointcut, so we can use a concise idiom like:
* Convenient class for building up pointcuts.
*
* {@code
* Pointcut pc = new ComposablePointcut().union(classFilter).intersection(methodMatcher).intersection(pointcut);
* }
* <p>All methods return {@code ComposablePointcut}, so we can use concise idioms
* like in the following example.
*
* <pre class="code">Pointcut pc = new ComposablePointcut()
* .union(classFilter)
* .intersection(methodMatcher)
* .intersection(pointcut);</pre>
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -199,7 +202,7 @@ public class ComposablePointcut implements Pointcut, Serializable {
@Override
public String toString() {
return "ComposablePointcut: " + this.classFilter + ", " +this.methodMatcher;
return getClass().getName() + ": " + this.classFilter + ", " + this.methodMatcher;
}
}
@@ -34,14 +34,15 @@ import org.springframework.util.ObjectUtils;
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
*/
@SuppressWarnings("serial")
public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable {
private Class<?> clazz;
private final Class<?> clazz;
@Nullable
private String methodName;
private final String methodName;
private volatile int evaluations;
@@ -142,4 +143,9 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
return code;
}
@Override
public String toString() {
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ import org.springframework.util.ClassUtils;
* @author Juergen Hoeller
* @since 11.11.2003
*/
@SuppressWarnings({"serial" })
@SuppressWarnings("serial")
public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFilter, Ordered, Serializable {
private final Advice advice;
@@ -82,25 +82,25 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
/**
* Create a DefaultIntroductionAdvisor for the given advice.
* @param advice the Advice to apply
* @param intf the interface to introduce
* @param ifc the interface to introduce
*/
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) {
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
addInterface(intf);
addInterface(ifc);
}
/**
* Add the specified interface to the list of interfaces to introduce.
* @param intf the interface to introduce
* @param ifc the interface to introduce
*/
public void addInterface(Class<?> intf) {
Assert.notNull(intf, "Interface must not be null");
if (!intf.isInterface()) {
throw new IllegalArgumentException("Specified class [" + intf.getName() + "] must be an interface");
public void addInterface(Class<?> ifc) {
Assert.notNull(ifc, "Interface must not be null");
if (!ifc.isInterface()) {
throw new IllegalArgumentException("Specified class [" + ifc.getName() + "] must be an interface");
}
this.interfaces.add(intf);
this.interfaces.add(ifc);
}
@Override
@@ -113,8 +113,8 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
for (Class<?> ifc : this.interfaces) {
if (this.advice instanceof DynamicIntroductionAdvice &&
!((DynamicIntroductionAdvice) this.advice).implementsInterface(ifc)) {
throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
"does not implement interface [" + ifc.getName() + "] specified for introduction");
throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
"does not implement interface [" + ifc.getName() + "] specified for introduction");
}
}
}
@@ -168,7 +168,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
@Override
public String toString() {
return ClassUtils.getShortName(getClass()) + ": advice [" + this.advice + "]; interfaces " +
return getClass().getName() + ": advice [" + this.advice + "]; interfaces " +
ClassUtils.classNamesToString(this.interfaces);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @author Sam Brannen
* @since 11.11.2003
* @see ClassFilters
* @see Pointcuts
@@ -155,6 +156,11 @@ public abstract class MethodMatchers {
public int hashCode() {
return 37 * this.mm1.hashCode() + this.mm2.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.mm1 + ", " + this.mm2;
}
}
@@ -229,6 +235,11 @@ public abstract class MethodMatchers {
// Allow for matching with regular UnionMethodMatcher by providing same hash...
return super.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.cf1 + ", " + this.mm1 + ", " + this.cf2 + ", " + this.mm2;
}
}
@@ -311,6 +322,11 @@ public abstract class MethodMatchers {
public int hashCode() {
return 37 * this.mm1.hashCode() + this.mm2.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.mm1 + ", " + this.mm2;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,9 @@ import java.util.List;
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.
* Pointcut bean for simple method name matches, as an alternative to regexp patterns.
*
* <p>Does not handle overloaded methods: all methods with a given name will be eligible.
*
* @author Juergen Hoeller
* @author Rod Johnson
@@ -108,4 +109,9 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
return this.mappedNames.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.mappedNames;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@ import org.springframework.util.Assert;
/**
* Pointcut constants for matching getters and setters,
* and static methods useful for manipulating and evaluating pointcuts.
* These methods are particularly useful for composing pointcuts
*
* <p>These methods are particularly useful for composing pointcuts
* using the union and intersection methods.
*
* @author Rod Johnson
@@ -106,6 +107,11 @@ public abstract class Pointcuts {
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "Pointcuts.SETTERS";
}
}
@@ -126,6 +132,11 @@ public abstract class Pointcuts {
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "Pointcuts.GETTERS";
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,22 @@ package org.springframework.aop.support;
import java.io.Serializable;
import org.springframework.aop.ClassFilter;
import org.springframework.util.Assert;
/**
* Simple ClassFilter implementation that passes classes (and optionally subclasses).
*
* @author Rod Johnson
* @author Sam Brannen
*/
@SuppressWarnings("serial")
public class RootClassFilter implements ClassFilter, Serializable {
private Class<?> clazz;
private final Class<?> clazz;
public RootClassFilter(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
this.clazz = clazz;
}
@@ -41,4 +44,20 @@ public class RootClassFilter implements ClassFilter, Serializable {
return this.clazz.isAssignableFrom(candidate);
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof RootClassFilter &&
this.clazz.equals(((RootClassFilter) other).clazz)));
}
@Override
public int hashCode() {
return this.clazz.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.clazz.getName();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
}
/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* Create a new AnnotationMatchingPointcut for the given annotation types.
* @param classAnnotationType the annotation type to look for at the class level
* (can be {@code null})
* @param methodAnnotationType the annotation type to look for at the method level
@@ -75,7 +75,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
}
/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* Create a new AnnotationMatchingPointcut for the given annotation types.
* @param classAnnotationType the annotation type to look for at the class level
* (can be {@code null})
* @param methodAnnotationType the annotation type to look for at the method level
@@ -138,7 +138,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
@Override
public String toString() {
return "AnnotationMatchingPointcut: " + this.classFilter + ", " +this.methodMatcher;
return "AnnotationMatchingPointcut: " + this.classFilter + ", " + this.methodMatcher;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
* interface, if any, and the corresponding method on the target class).
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 2.0
* @see AnnotationMatchingPointcut
*/
@@ -94,7 +95,7 @@ public class AnnotationMethodMatcher extends StaticMethodMatcher {
return false;
}
AnnotationMethodMatcher otherMm = (AnnotationMethodMatcher) other;
return this.annotationType.equals(otherMm.annotationType);
return (this.annotationType.equals(otherMm.annotationType) && this.checkInherited == otherMm.checkInherited);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import static org.junit.Assert.*;
* @author Rod Johnson
* @author Rick Evans
* @author Chris Beams
* @author Sam Brannen
*/
public class TypePatternClassFilterTests {
@@ -88,4 +89,34 @@ public class TypePatternClassFilterTests {
new TypePatternClassFilter().matches(String.class);
}
@Test
public void testEquals() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter3 = new TypePatternClassFilter("org.springframework.tests.*");
assertEquals(filter1, filter2);
assertNotEquals(filter1, filter3);
}
@Test
public void testHashCode() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter3 = new TypePatternClassFilter("org.springframework.tests.*");
assertEquals(filter1.hashCode(), filter2.hashCode());
assertNotEquals(filter1.hashCode(), filter3.hashCode());
}
@Test
public void testToString() {
TypePatternClassFilter filter1 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
TypePatternClassFilter filter2 = new TypePatternClassFilter("org.springframework.tests.sample.beans.*");
assertEquals("org.springframework.aop.aspectj.TypePatternClassFilter: org.springframework.tests.sample.beans.*",
filter1.toString());
assertEquals(filter1.toString(), filter2.toString());
}
}
@@ -18,6 +18,7 @@ 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;
@@ -0,0 +1,74 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.scope;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.*;
/**
* Unit tests for {@link ScopedProxyUtils}.
*
* @author Sam Brannen
* @since 5.1.10
*/
public class ScopedProxyUtilsTests {
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void getTargetBeanNameAndIsScopedTarget() {
String originalBeanName = "myBean";
String targetBeanName = ScopedProxyUtils.getTargetBeanName(originalBeanName);
assertNotEquals(originalBeanName, targetBeanName);
assertTrue(targetBeanName.endsWith(originalBeanName));
assertTrue(ScopedProxyUtils.isScopedTarget(targetBeanName));
assertFalse(ScopedProxyUtils.isScopedTarget(originalBeanName));
}
@Test
public void getOriginalBeanNameAndIsScopedTarget() {
String originalBeanName = "myBean";
String targetBeanName = ScopedProxyUtils.getTargetBeanName(originalBeanName);
String parsedOriginalBeanName = ScopedProxyUtils.getOriginalBeanName(targetBeanName);
assertNotEquals(targetBeanName, parsedOriginalBeanName);
assertEquals(originalBeanName, parsedOriginalBeanName);
assertTrue(ScopedProxyUtils.isScopedTarget(targetBeanName));
assertFalse(ScopedProxyUtils.isScopedTarget(parsedOriginalBeanName));
}
@Test
public void getOriginalBeanNameForNullTargetBean() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("bean name 'null' does not refer to the target of a scoped proxy");
ScopedProxyUtils.getOriginalBeanName(null);
}
@Test
public void getOriginalBeanNameForNonScopedTarget() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("bean name 'myBean' does not refer to the target of a scoped proxy");
ScopedProxyUtils.getOriginalBeanName("myBean");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,39 +23,46 @@ import org.springframework.core.NestedRuntimeException;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Unit tests for {@link ClassFilters}.
*
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
*/
public class ClassFiltersTests {
private ClassFilter exceptionFilter = new RootClassFilter(Exception.class);
private final ClassFilter exceptionFilter = new RootClassFilter(Exception.class);
private ClassFilter itbFilter = new RootClassFilter(ITestBean.class);
private final ClassFilter interfaceFilter = new RootClassFilter(ITestBean.class);
private final ClassFilter hasRootCauseFilter = new RootClassFilter(NestedRuntimeException.class);
private ClassFilter hasRootCauseFilter = new RootClassFilter(NestedRuntimeException.class);
@Test
public void testUnion() {
public void union() {
assertTrue(exceptionFilter.matches(RuntimeException.class));
assertFalse(exceptionFilter.matches(TestBean.class));
assertFalse(itbFilter.matches(Exception.class));
assertTrue(itbFilter.matches(TestBean.class));
ClassFilter union = ClassFilters.union(exceptionFilter, itbFilter);
assertFalse(interfaceFilter.matches(Exception.class));
assertTrue(interfaceFilter.matches(TestBean.class));
ClassFilter union = ClassFilters.union(exceptionFilter, interfaceFilter);
assertTrue(union.matches(RuntimeException.class));
assertTrue(union.matches(TestBean.class));
assertTrue(union.toString().matches("^.+UnionClassFilter: \\[.+RootClassFilter: .+Exception, .+RootClassFilter: .+TestBean\\]$"));
}
@Test
public void testIntersection() {
public void intersection() {
assertTrue(exceptionFilter.matches(RuntimeException.class));
assertTrue(hasRootCauseFilter.matches(NestedRuntimeException.class));
ClassFilter intersection = ClassFilters.intersection(exceptionFilter, hasRootCauseFilter);
assertFalse(intersection.matches(RuntimeException.class));
assertFalse(intersection.matches(TestBean.class));
assertTrue(intersection.matches(NestedRuntimeException.class));
assertTrue(intersection.toString().matches("^.+IntersectionClassFilter: \\[.+RootClassFilter: .+Exception, .+RootClassFilter: .+NestedRuntimeException\\]$"));
}
}
@@ -100,6 +100,14 @@ public class ControlFlowPointcutTests {
assertFalse(new ControlFlowPointcut(One.class, "getAge").hashCode() == new ControlFlowPointcut(One.class).hashCode());
}
@Test
public void testToString() {
assertEquals(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = null",
new ControlFlowPointcut(One.class).toString());
assertEquals(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = getAge",
new ControlFlowPointcut(One.class, "getAge").toString());
}
public class One {
int getAge(ITestBean proxied) {
return proxied.getAge();
@@ -0,0 +1,66 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.support;
import org.junit.Test;
import org.springframework.aop.ClassFilter;
import org.springframework.tests.sample.beans.ITestBean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
/**
* Unit tests for {@link RootClassFilter}.
*
* @author Sam Brannen
* @since 5.1.10
*/
public class RootClassFilterTests {
private final ClassFilter filter1 = new RootClassFilter(Exception.class);
private final ClassFilter filter2 = new RootClassFilter(Exception.class);
private final ClassFilter filter3 = new RootClassFilter(ITestBean.class);
@Test
public void matches() {
assertTrue(filter1.matches(Exception.class));
assertTrue(filter1.matches(RuntimeException.class));
assertFalse(filter1.matches(Error.class));
}
@Test
public void testEquals() {
assertEquals(filter1, filter2);
assertNotEquals(filter1, filter3);
}
@Test
public void testHashCode() {
assertEquals(filter1.hashCode(), filter2.hashCode());
assertNotEquals(filter1.hashCode(), filter3.hashCode());
}
@Test
public void testToString() {
assertEquals("org.springframework.aop.support.RootClassFilter: java.lang.Exception", filter1.toString());
assertEquals(filter1.toString(), filter2.toString());
}
}
@@ -0,0 +1,108 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.support.annotation;
import org.junit.Test;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.beans.factory.annotation.Qualifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
/**
* Unit tests for {@link AnnotationMatchingPointcut}.
*
* @author Sam Brannen
* @since 5.1.10
*/
public class AnnotationMatchingPointcutTests {
@Test
public void classLevelPointcuts() {
Pointcut pointcut1 = new AnnotationMatchingPointcut(Qualifier.class, true);
Pointcut pointcut2 = new AnnotationMatchingPointcut(Qualifier.class, true);
Pointcut pointcut3 = new AnnotationMatchingPointcut(Qualifier.class);
assertEquals(AnnotationClassFilter.class, pointcut1.getClassFilter().getClass());
assertEquals(AnnotationClassFilter.class, pointcut2.getClassFilter().getClass());
assertEquals(AnnotationClassFilter.class, pointcut3.getClassFilter().getClass());
assertTrue(pointcut1.getClassFilter().toString().contains(Qualifier.class.getName()));
assertEquals(MethodMatcher.TRUE, pointcut1.getMethodMatcher());
assertEquals(MethodMatcher.TRUE, pointcut2.getMethodMatcher());
assertEquals(MethodMatcher.TRUE, pointcut3.getMethodMatcher());
assertEquals(pointcut1, pointcut2);
assertNotEquals(pointcut1, pointcut3);
assertEquals(pointcut1.hashCode(), pointcut2.hashCode());
// #1 and #3 have equivalent hash codes even though equals() returns false.
assertEquals(pointcut1.hashCode(), pointcut3.hashCode());
assertEquals(pointcut1.toString(), pointcut2.toString());
}
@Test
public void methodLevelPointcuts() {
Pointcut pointcut1 = new AnnotationMatchingPointcut(null, Qualifier.class, true);
Pointcut pointcut2 = new AnnotationMatchingPointcut(null, Qualifier.class, true);
Pointcut pointcut3 = new AnnotationMatchingPointcut(null, Qualifier.class);
assertEquals(ClassFilter.TRUE, pointcut1.getClassFilter());
assertEquals(ClassFilter.TRUE, pointcut2.getClassFilter());
assertEquals(ClassFilter.TRUE, pointcut3.getClassFilter());
assertEquals("ClassFilter.TRUE", pointcut1.getClassFilter().toString());
assertEquals(AnnotationMethodMatcher.class, pointcut1.getMethodMatcher().getClass());
assertEquals(AnnotationMethodMatcher.class, pointcut2.getMethodMatcher().getClass());
assertEquals(AnnotationMethodMatcher.class, pointcut3.getMethodMatcher().getClass());
assertEquals(pointcut1, pointcut2);
assertNotEquals(pointcut1, pointcut3);
assertEquals(pointcut1.hashCode(), pointcut2.hashCode());
// #1 and #3 have equivalent hash codes even though equals() returns false.
assertEquals(pointcut1.hashCode(), pointcut3.hashCode());
assertEquals(pointcut1.toString(), pointcut2.toString());
}
@Test
public void classLevelAndMethodLevelPointcuts() {
Pointcut pointcut1 = new AnnotationMatchingPointcut(Qualifier.class, Qualifier.class, true);
Pointcut pointcut2 = new AnnotationMatchingPointcut(Qualifier.class, Qualifier.class, true);
Pointcut pointcut3 = new AnnotationMatchingPointcut(Qualifier.class, Qualifier.class);
assertEquals(AnnotationClassFilter.class, pointcut1.getClassFilter().getClass());
assertEquals(AnnotationClassFilter.class, pointcut2.getClassFilter().getClass());
assertEquals(AnnotationClassFilter.class, pointcut3.getClassFilter().getClass());
assertTrue(pointcut1.getClassFilter().toString().contains(Qualifier.class.getName()));
assertEquals(AnnotationMethodMatcher.class, pointcut1.getMethodMatcher().getClass());
assertEquals(AnnotationMethodMatcher.class, pointcut2.getMethodMatcher().getClass());
assertEquals(AnnotationMethodMatcher.class, pointcut3.getMethodMatcher().getClass());
assertTrue(pointcut1.getMethodMatcher().toString().contains(Qualifier.class.getName()));
assertEquals(pointcut1, pointcut2);
assertNotEquals(pointcut1, pointcut3);
assertEquals(pointcut1.hashCode(), pointcut2.hashCode());
// #1 and #3 have equivalent hash codes even though equals() returns false.
assertEquals(pointcut1.hashCode(), pointcut3.hashCode());
assertEquals(pointcut1.toString(), pointcut2.toString());
}
}
+1 -1
View File
@@ -89,7 +89,7 @@ dependencies {
optional(project(":spring-context-support")) // for JavaMail and JSR-107 support
optional(project(":spring-orm")) // for JPA exception translation support
optional(project(":spring-tx")) // for JPA, @Transactional support
optional("javax.cache:cache-api:1.1.0") // for JCache aspect
optional("javax.cache:cache-api:1.1.0") // for JCache aspect
optional("javax.transaction:javax.transaction-api:1.3") // for @javax.transaction.Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
testCompile(project(":spring-test"))
@@ -19,6 +19,7 @@ package org.springframework.cache.config;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CachePut;
@@ -17,6 +17,7 @@
package org.springframework.transaction.aspectj;
import java.io.IOException;
import javax.transaction.Transactional;
import org.junit.Before;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -554,35 +554,42 @@ public abstract class BeanUtils {
}
/**
* Check if the given type represents a "simple" property:
* a primitive, a String or other CharSequence, a Number, a Date,
* a URI, a URL, a Locale, a Class, or a corresponding array.
* Check if the given type represents a "simple" property: a simple value
* type or an array of simple value types.
* <p>See {@link #isSimpleValueType(Class)} for the definition of <em>simple
* value type</em>.
* <p>Used to determine properties to check for a "simple" dependency-check.
* @param clazz the type to check
* @param type the type to check
* @return whether the given type represents a "simple" property
* @see org.springframework.beans.factory.support.RootBeanDefinition#DEPENDENCY_CHECK_SIMPLE
* @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#checkDependencies
* @see #isSimpleValueType(Class)
*/
public static boolean isSimpleProperty(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return isSimpleValueType(clazz) || (clazz.isArray() && isSimpleValueType(clazz.getComponentType()));
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}
/**
* Check if the given type represents a "simple" value type:
* a primitive, an enum, a String or other CharSequence, a Number, a Date,
* a URI, a URL, a Locale or a Class.
* @param clazz the type to check
* Check if the given type represents a "simple" value type: a primitive or
* primitive wrapper, an enum, a String or other CharSequence, a Number, a
* Date, a URI, a URL, a Locale, or a Class.
* <p>{@code Void} and {@code void} are not considered simple value types.
* @param type the type to check
* @return whether the given type represents a "simple" value type
* @see #isSimpleProperty(Class)
*/
public static boolean isSimpleValueType(Class<?> clazz) {
return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
Enum.class.isAssignableFrom(clazz) ||
CharSequence.class.isAssignableFrom(clazz) ||
Number.class.isAssignableFrom(clazz) ||
Date.class.isAssignableFrom(clazz) ||
URI.class == clazz || URL.class == clazz ||
Locale.class == clazz || Class.class == clazz);
public static boolean isSimpleValueType(Class<?> type) {
return (type != void.class && type != Void.class &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,19 +23,21 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a constructor, field, setter method or config method as to be autowired by
* Marks a constructor, field, setter method, or config method as to be autowired by
* Spring's dependency injection facilities. This is an alternative to the JSR-330
* {@link javax.inject.Inject} annotation, adding required-vs-optional semantics.
*
* <p>Only one constructor (at max) of any given bean class may declare this annotation
* with the 'required' parameter set to {@code true}, indicating <i>the</i> constructor
* to autowire when used as a Spring bean. If multiple <i>non-required</i> constructors
* declare the annotation, they will be considered as candidates for autowiring.
* The constructor with the greatest number of dependencies that can be satisfied by
* matching beans in the Spring container will be chosen. If none of the candidates
* can be satisfied, then a primary/default constructor (if present) will be used.
* If a class only declares a single constructor to begin with, it will always be used,
* even if not annotated. An annotated constructor does not have to be public.
* <p>Only one constructor of any given bean class may declare this annotation with
* the 'required' attribute set to {@code true}, indicating <i>the</i> constructor
* to autowire when used as a Spring bean. Furthermore, if the 'required' attribute
* is set to {@code true}, only a single constructor may be annotated with
* {@code @Autowired}. If multiple <i>non-required</i> constructors declare the
* annotation, they will be considered as candidates for autowiring. The constructor
* with the greatest number of dependencies that can be satisfied by matching beans
* in the Spring container will be chosen. If none of the candidates can be satisfied,
* then a primary/default constructor (if present) will be used. If a class only
* declares a single constructor to begin with, it will always be used, even if not
* annotated. An annotated constructor does not have to be public.
*
* <p>Fields are injected right after construction of a bean, before any config methods
* are invoked. Such a config field does not have to be public.
@@ -45,7 +47,7 @@ import java.lang.annotation.Target;
* Bean property setter methods are effectively just a special case of such a general
* config method. Such config methods do not have to be public.
*
* <p>In the case of a multi-arg constructor or method, the 'required' parameter is
* <p>In the case of a multi-arg constructor or method, the 'required' attribute is
* applicable to all arguments. Individual parameters may be declared as Java-8-style
* {@link java.util.Optional} or, as of Spring Framework 5.0, also as {@code @Nullable}
* or a not-null parameter type in Kotlin, overriding the base required semantics.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -139,9 +139,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
/**
* Create a new AutowiredAnnotationBeanPostProcessor
* for Spring's standard {@link Autowired} annotation.
* <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
* standard {@link Autowired @Autowired} annotation.
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available.
*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
@@ -242,7 +243,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here..
// Let's check for lookup methods here...
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, method -> {
@@ -251,7 +252,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -408,7 +408,7 @@ public class ConstructorArgumentValues {
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
ValueHolder vh1 = entry.getValue();
ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey());
if (!vh1.contentEquals(vh2)) {
if (vh2 == null || !vh1.contentEquals(vh2)) {
return false;
}
}
@@ -430,7 +430,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
@Override
public int hashCode() {
return 31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.containingClass);
return (31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.containingClass));
}
@@ -17,6 +17,7 @@
package org.springframework.beans.factory.config;
import java.io.Serializable;
import javax.inject.Provider;
import org.springframework.beans.BeansException;
@@ -1900,8 +1900,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
@@ -179,8 +179,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
@Nullable
private MutablePropertyValues propertyValues;
@Nullable
private MethodOverrides methodOverrides;
private MethodOverrides methodOverrides = new MethodOverrides();
@Nullable
private String initMethodName;
@@ -869,9 +868,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* <p>Never returns {@code null}.
*/
public MethodOverrides getMethodOverrides() {
if (this.methodOverrides == null) {
this.methodOverrides = new MethodOverrides();
}
return this.methodOverrides;
}
@@ -880,7 +876,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* @since 5.0.2
*/
public boolean hasMethodOverrides() {
return (this.methodOverrides != null && !this.methodOverrides.isEmpty());
return !this.methodOverrides.isEmpty();
}
/**
@@ -1064,10 +1060,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
public void validate() throws BeanDefinitionValidationException {
if (hasMethodOverrides() && getFactoryMethodName() != null) {
throw new BeanDefinitionValidationException(
"Cannot combine static factory method with method overrides: " +
"the static factory method must create the instance");
"Cannot combine factory method with container-generated method overrides: " +
"the factory method must create the concrete bean instance.");
}
if (hasBeanClass()) {
prepareMethodOverrides();
}
@@ -1079,14 +1074,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* @throws BeanDefinitionValidationException in case of validation failure
*/
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
synchronized (overrides) {
for (MethodOverride mo : overrides) {
prepareMethodOverride(mo);
}
}
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
@@ -249,7 +249,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
public int accept(Method method) {
MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method);
if (logger.isTraceEnabled()) {
logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]");
logger.trace("MethodOverride for " + method + ": " + methodOverride);
}
if (methodOverride == null) {
return PASSTHROUGH;
@@ -43,6 +43,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.inject.Provider;
import org.springframework.beans.BeanUtils;
@@ -321,7 +322,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
this.dependencyComparator = otherListableFactory.dependencyComparator;
// A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware...
setAutowireCandidateResolver(BeanUtils.instantiateClass(getAutowireCandidateResolver().getClass()));
setAutowireCandidateResolver(
BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass()));
// Make resolvable dependencies (e.g. ResourceLoader) available here as well...
this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
}
@@ -1002,7 +1004,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
if (beanName.equals(bd.getParentName())) {
// Ensure bd is non-null due to potential concurrent modification
// of the beanDefinitionMap.
if (bd != null && beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -571,8 +571,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
bean.destroy();
}
catch (Throwable ex) {
if (logger.isInfoEnabled()) {
logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
@@ -261,10 +261,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.info(msg, ex);
logger.warn(msg, ex);
}
else {
logger.info(msg + ": " + ex);
logger.warn(msg + ": " + ex);
}
}
}
@@ -343,14 +343,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
this.beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.info(msg, ex.getTargetException());
logger.warn(msg, ex.getTargetException());
}
else {
logger.info(msg + ": " + ex.getTargetException());
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.info("Failed to invoke destroy method '" + this.destroyMethodName +
logger.warn("Failed to invoke destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'", ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.beans.factory.support;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
@@ -84,7 +85,14 @@ public class GenericBeanDefinition extends AbstractBeanDefinition {
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof GenericBeanDefinition && super.equals(other)));
if (this == other) {
return true;
}
if (!(other instanceof GenericBeanDefinition)) {
return false;
}
GenericBeanDefinition that = (GenericBeanDefinition) other;
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,8 @@
package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import org.springframework.lang.Nullable;
@@ -37,9 +36,7 @@ import org.springframework.lang.Nullable;
*/
public class MethodOverrides {
private final Set<MethodOverride> overrides = Collections.synchronizedSet(new LinkedHashSet<>(2));
private volatile boolean modified = false;
private final Set<MethodOverride> overrides = new CopyOnWriteArraySet<>();
/**
@@ -61,7 +58,6 @@ public class MethodOverrides {
*/
public void addOverrides(@Nullable MethodOverrides other) {
if (other != null) {
this.modified = true;
this.overrides.addAll(other.overrides);
}
}
@@ -70,7 +66,6 @@ public class MethodOverrides {
* Add the given method override.
*/
public void addOverride(MethodOverride override) {
this.modified = true;
this.overrides.add(override);
}
@@ -80,7 +75,6 @@ public class MethodOverrides {
* @see MethodOverride
*/
public Set<MethodOverride> getOverrides() {
this.modified = true;
return this.overrides;
}
@@ -88,7 +82,7 @@ public class MethodOverrides {
* Return whether the set of method overrides is empty.
*/
public boolean isEmpty() {
return (!this.modified || this.overrides.isEmpty());
return this.overrides.isEmpty();
}
/**
@@ -98,18 +92,13 @@ public class MethodOverrides {
*/
@Nullable
public MethodOverride getOverride(Method method) {
if (!this.modified) {
return null;
}
synchronized (this.overrides) {
MethodOverride match = null;
for (MethodOverride candidate : this.overrides) {
if (candidate.matches(method)) {
match = candidate;
}
MethodOverride match = null;
for (MethodOverride candidate : this.overrides) {
if (candidate.matches(method)) {
match = candidate;
}
return match;
}
return match;
}
@@ -123,7 +112,6 @@ public class MethodOverrides {
}
MethodOverrides that = (MethodOverrides) other;
return this.overrides.equals(that.overrides);
}
@Override
@@ -643,6 +643,9 @@ public class BeanDefinitionParserDelegate {
parentName, className, this.readerContext.getBeanClassLoader());
}
/**
* Parse the meta elements underneath the given element, if any.
*/
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
@@ -658,23 +661,27 @@ public class BeanDefinitionParserDelegate {
}
}
/**
* Parse the given autowire attribute value into
* {@link AbstractBeanDefinition} autowire constants.
*/
@SuppressWarnings("deprecation")
public int getAutowireMode(String attValue) {
String att = attValue;
if (isDefaultValue(att)) {
att = this.defaults.getAutowire();
public int getAutowireMode(String attrValue) {
String attr = attrValue;
if (isDefaultValue(attr)) {
attr = this.defaults.getAutowire();
}
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
if (AUTOWIRE_BY_NAME_VALUE.equals(att)) {
if (AUTOWIRE_BY_NAME_VALUE.equals(attr)) {
autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME;
}
else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) {
else if (AUTOWIRE_BY_TYPE_VALUE.equals(attr)) {
autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
}
else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) {
else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(attr)) {
autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR;
}
else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) {
else if (AUTOWIRE_AUTODETECT_VALUE.equals(attr)) {
autowire = AbstractBeanDefinition.AUTOWIRE_AUTODETECT;
}
// Else leave default value.
@@ -953,6 +960,12 @@ public class BeanDefinitionParserDelegate {
}
}
/**
* Parse a value, ref or collection sub-element of a property or
* constructor-arg element.
* @param ele subelement of property element; we don't know which yet
* @param bd the current bean definition (if any)
*/
@Nullable
public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd) {
return parsePropertySubElement(ele, bd, null);
@@ -962,6 +975,7 @@ public class BeanDefinitionParserDelegate {
* Parse a value, ref or collection sub-element of a property or
* constructor-arg element.
* @param ele subelement of property element; we don't know which yet
* @param bd the current bean definition (if any)
* @param defaultValueType the default type (class name) for any
* {@code <value>} tag that might be created
*/
@@ -1347,11 +1361,22 @@ public class BeanDefinitionParserDelegate {
return TRUE_VALUE.equals(value);
}
/**
* Parse a custom element (outside of the default namespace).
* @param ele the element to parse
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
/**
* Parse a custom element (outside of the default namespace).
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
@@ -1366,14 +1391,27 @@ public class BeanDefinitionParserDelegate {
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
/**
* Decorate the given bean definition through a namespace handler, if applicable.
* @param ele the current element
* @param originalDef the current bean definition
* @return the decorated bean definition
*/
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) {
return decorateBeanDefinitionIfRequired(ele, originalDef, null);
}
/**
* Decorate the given bean definition through a namespace handler, if applicable.
* @param ele the current element
* @param originalDef the current bean definition
* @param containingBd the containing bean definition (if any)
* @return the decorated bean definition
*/
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
Element ele, BeanDefinitionHolder definitionHolder, @Nullable BeanDefinition containingBd) {
Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = definitionHolder;
BeanDefinitionHolder finalDefinition = originalDef;
// Decorate based on custom attributes first.
NamedNodeMap attributes = ele.getAttributes();
@@ -1393,6 +1431,14 @@ public class BeanDefinitionParserDelegate {
return finalDefinition;
}
/**
* Decorate the given bean definition through a namespace handler,
* if applicable.
* @param node the current child node
* @param originalDef the current bean definition
* @param containingBd the containing bean definition (if any)
* @return the decorated bean definition
*/
public BeanDefinitionHolder decorateIfRequired(
Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
@@ -1473,10 +1519,16 @@ public class BeanDefinitionParserDelegate {
return desiredName.equals(node.getNodeName()) || desiredName.equals(getLocalName(node));
}
/**
* Determine whether the given URI indicates the default namespace.
*/
public boolean isDefaultNamespace(@Nullable String namespaceUri) {
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
}
/**
* Determine whether the given node indicates the default namespace.
*/
public boolean isDefaultNamespace(Node node) {
return isDefaultNamespace(getNamespaceURI(node));
}
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,8 +19,14 @@ package org.springframework.beans;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.Test;
@@ -32,7 +38,12 @@ import org.springframework.tests.sample.beans.DerivedTestBean;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Unit tests for {@link BeanUtils}.
@@ -40,6 +51,7 @@ import static org.junit.Assert.*;
* @author Juergen Hoeller
* @author Rob Harrop
* @author Chris Beams
* @author Sam Brannen
* @since 19.05.2003
*/
public class BeanUtilsTests {
@@ -275,6 +287,60 @@ public class BeanUtilsTests {
}
}
@Test
public void isSimpleValueType() {
Stream.of(
boolean.class, char.class, byte.class, short.class, int.class,
long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class,
Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, Date.class, URI.class, URL.class, Locale.class, Class.class
).forEach(this::assertIsSimpleValueType);
Stream.of(int[].class, Object.class, List.class, void.class, Void.class)
.forEach(this::assertIsNotSimpleValueType);
}
@Test
public void isSimpleProperty() {
Stream.of(
boolean.class, char.class, byte.class, short.class, int.class,
long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class,
Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, Date.class, URI.class, URL.class, Locale.class, Class.class,
boolean[].class, Boolean[].class, Date[].class
).forEach(this::assertIsSimpleProperty);
Stream.of(Object.class, List.class, void.class, Void.class)
.forEach(this::assertIsNotSimpleProperty);
}
private void assertIsSimpleValueType(Class<?> type) {
assertTrue("Type [" + type.getName() + "] should be a simple value type", BeanUtils.isSimpleValueType(type));
}
private void assertIsNotSimpleValueType(Class<?> type) {
assertFalse("Type [" + type.getName() + "] should not be a simple value type", BeanUtils.isSimpleValueType(type));
}
private void assertIsSimpleProperty(Class<?> type) {
assertTrue("Type [" + type.getName() + "] should be a simple property", BeanUtils.isSimpleProperty(type));
}
private void assertIsNotSimpleProperty(Class<?> type) {
assertFalse("Type [" + type.getName() + "] should not be a simple property", BeanUtils.isSimpleProperty(type));
}
private void assertSignatureEquals(Method desiredMethod, String signature) {
assertEquals(desiredMethod, BeanUtils.resolveSignature(signature, MethodSignatureBean.class));
}
@@ -445,6 +511,7 @@ public class BeanUtilsTests {
}
}
@SuppressWarnings("unused")
private static class BeanWithSingleNonDefaultConstructor {
private final String name;
@@ -38,6 +38,8 @@ import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Priority;
import javax.security.auth.Subject;
@@ -792,6 +794,18 @@ public class DefaultListableBeanFactoryTests {
lbf.registerAlias("test", "test3");
}
@Test
public void testAliasChaining() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerAlias("testAlias", "testAlias2");
lbf.registerAlias("testAlias2", "testAlias3");
Object bean = lbf.getBean("test");
assertSame(bean, lbf.getBean("testAlias"));
assertSame(bean, lbf.getBean("testAlias2"));
assertSame(bean, lbf.getBean("testAlias3"));
}
@Test
public void testBeanDefinitionOverriding() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
@@ -802,20 +816,6 @@ public class DefaultListableBeanFactoryTests {
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
}
@Test
public void testBeanDefinitionRemoval() {
lbf.setAllowBeanDefinitionOverriding(false);
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
lbf.registerAlias("test", "test2");
lbf.preInstantiateSingletons();
lbf.removeBeanDefinition("test");
lbf.removeAlias("test2");
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "test2");
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
}
@Test
public void testBeanDefinitionOverridingNotAllowed() {
lbf.setAllowBeanDefinitionOverriding(false);
@@ -844,15 +844,55 @@ public class DefaultListableBeanFactoryTests {
}
@Test
public void testAliasChaining() {
public void beanDefinitionOverridingWithConstructorArgumentMismatch() {
RootBeanDefinition bd1 = new RootBeanDefinition(NestedTestBean.class);
bd1.getConstructorArgumentValues().addIndexedArgumentValue(1, "value1");
lbf.registerBeanDefinition("test", bd1);
RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
bd2.getConstructorArgumentValues().addIndexedArgumentValue(0, "value0");
lbf.registerBeanDefinition("test", bd2);
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
assertEquals("value0", lbf.getBean("test", NestedTestBean.class).getCompany());
}
@Test
public void testBeanDefinitionRemoval() {
lbf.setAllowBeanDefinitionOverriding(false);
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
lbf.registerAlias("test", "test2");
lbf.preInstantiateSingletons();
lbf.removeBeanDefinition("test");
lbf.removeAlias("test2");
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerAlias("testAlias", "testAlias2");
lbf.registerAlias("testAlias2", "testAlias3");
Object bean = lbf.getBean("test");
assertSame(bean, lbf.getBean("testAlias"));
assertSame(bean, lbf.getBean("testAlias2"));
assertSame(bean, lbf.getBean("testAlias3"));
lbf.registerAlias("test", "test2");
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
}
@Test // gh-23542
public void concurrentBeanDefinitionRemoval() {
final int MAX = 200;
lbf.setAllowBeanDefinitionOverriding(false);
// Register the bean definitions before invoking preInstantiateSingletons()
// to simulate realistic usage of an ApplicationContext; otherwise, the bean
// factory thinks it's an "empty" factory which causes this test to fail in
// an unrealistic manner.
IntStream.range(0, MAX).forEach(this::registerTestBean);
lbf.preInstantiateSingletons();
// This test is considered successful if the following does not result in an exception.
IntStream.range(0, MAX).parallel().forEach(this::removeTestBean);
}
private void registerTestBean(int i) {
String name = "test" + i;
lbf.registerBeanDefinition(name, new RootBeanDefinition(TestBean.class));
}
private void removeTestBean(int i) {
String name = "test" + i;
lbf.removeBeanDefinition(name);
}
@Test
@@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
@@ -17,6 +17,7 @@
package org.springframework.beans.factory.config;
import java.util.Date;
import javax.inject.Provider;
import org.junit.After;
@@ -18,6 +18,7 @@ package org.springframework.beans.factory.serviceloader;
import java.util.List;
import java.util.ServiceLoader;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -100,6 +100,27 @@ public class BeanDefinitionTests {
assertTrue(bd.hashCode() == otherBd.hashCode());
}
@Test
public void genericBeanDefinitionEquality() {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName("parent");
bd.setScope("request");
bd.setAbstract(true);
bd.setLazyInit(true);
GenericBeanDefinition otherBd = new GenericBeanDefinition();
otherBd.setScope("request");
otherBd.setAbstract(true);
otherBd.setLazyInit(true);
boolean condition1 = !bd.equals(otherBd);
assertTrue(condition1);
boolean condition = !otherBd.equals(bd);
assertTrue(condition);
otherBd.setParentName("parent");
assertTrue(bd.equals(otherBd));
assertTrue(otherBd.equals(bd));
assertTrue(bd.hashCode() == otherBd.hashCode());
}
@Test
public void beanDefinitionHolderEquality() {
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
@@ -28,6 +28,7 @@ import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.PropertyPermission;
import java.util.Set;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
@@ -23,6 +23,7 @@ import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.Completion;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
@@ -19,6 +19,7 @@ package org.springframework.context.index.processor;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
@@ -19,6 +19,7 @@ package org.springframework.context.index.processor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.processing.ProcessingEnvironment;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
@@ -18,6 +18,7 @@ package org.springframework.context.index.processor;
import java.util.HashSet;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -18,6 +18,7 @@ package org.springframework.context.index.processor;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -17,6 +17,7 @@
package org.springframework.context.index.processor;
import java.util.Set;
import javax.lang.model.element.Element;
/**
@@ -19,6 +19,7 @@ package org.springframework.context.index.processor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
@@ -19,6 +19,7 @@ package org.springframework.context.index.processor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.annotation.ManagedBean;
import javax.inject.Named;
import javax.persistence.Converter;
@@ -37,6 +38,7 @@ import org.springframework.context.index.sample.AbstractController;
import org.springframework.context.index.sample.MetaControllerIndexed;
import org.springframework.context.index.sample.SampleComponent;
import org.springframework.context.index.sample.SampleController;
import org.springframework.context.index.sample.SampleEmbedded;
import org.springframework.context.index.sample.SampleMetaController;
import org.springframework.context.index.sample.SampleMetaIndexedController;
import org.springframework.context.index.sample.SampleNonStaticEmbedded;
@@ -48,7 +50,6 @@ import org.springframework.context.index.sample.cdi.SampleNamed;
import org.springframework.context.index.sample.cdi.SampleTransactional;
import org.springframework.context.index.sample.jpa.SampleConverter;
import org.springframework.context.index.sample.jpa.SampleEmbeddable;
import org.springframework.context.index.sample.SampleEmbedded;
import org.springframework.context.index.sample.jpa.SampleEntity;
import org.springframework.context.index.sample.jpa.SampleMappedSuperClass;
import org.springframework.context.index.sample.type.Repo;
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.processing.Processor;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
@@ -16,7 +16,7 @@ dependencies {
optional("org.freemarker:freemarker:${freemarkerVersion}")
testCompile(project(":spring-context"))
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.hibernate:hibernate-validator:6.0.16.Final")
testCompile("org.hibernate:hibernate-validator:6.0.17.Final")
testCompile("javax.annotation:javax.annotation-api:1.3.2")
testRuntime("org.ehcache:jcache:1.0.1")
testRuntime("org.ehcache:ehcache:3.4.0")
@@ -17,6 +17,7 @@
package org.springframework.cache.jcache;
import java.util.concurrent.Callable;
import javax.cache.Cache;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache;
import java.util.Collection;
import java.util.LinkedHashSet;
import javax.cache.CacheManager;
import javax.cache.Caching;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache;
import java.net.URI;
import java.util.Properties;
import javax.cache.CacheManager;
import javax.cache.Caching;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@ abstract class AbstractCacheInterceptor<O extends AbstractJCacheOperation<A>, A
/**
* Resolve the cache to use.
* @param context the invocation context
* @return the cache to use (never null)
* @return the cache to use (never {@code null})
*/
protected Cache resolveCache(CacheOperationInvocationContext<O> context) {
Collection<? extends Cache> caches = context.getOperation().getCacheResolver().resolveCaches(context);
@@ -73,7 +73,7 @@ abstract class AbstractCacheInterceptor<O extends AbstractJCacheOperation<A>, A
/**
* Convert the collection of caches in a single expected element.
* <p>Throw an {@link IllegalStateException} if the collection holds more than one element
* @return the single element or {@code null} if the collection is empty
* @return the single element, or {@code null} if the collection is empty
*/
@Nullable
static Cache extractFrom(Collection<? extends Cache> caches) {
@@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheMethodDetails;
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CacheMethodDetails;
@@ -17,6 +17,7 @@
package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import javax.cache.annotation.CacheKeyInvocationContext;
import org.springframework.cache.interceptor.CacheErrorHandler;
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyGenerator;
import javax.cache.annotation.CacheMethodDetails;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache.interceptor;
import java.lang.reflect.Method;
import java.util.List;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheMethodDetails;
import javax.cache.annotation.CachePut;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,6 @@ class CacheRemoveAllInterceptor extends AbstractCacheInterceptor<CacheRemoveAllO
CacheOperationInvocationContext<CacheRemoveAllOperation> context, CacheOperationInvoker invoker) {
CacheRemoveAllOperation operation = context.getOperation();
boolean earlyRemove = operation.isEarlyRemove();
if (earlyRemove) {
removeAll(context);
@@ -67,8 +66,8 @@ class CacheRemoveAllInterceptor extends AbstractCacheInterceptor<CacheRemoveAllO
protected void removeAll(CacheOperationInvocationContext<CacheRemoveAllOperation> context) {
Cache cache = resolveCache(context);
if (logger.isTraceEnabled()) {
logger.trace("Invalidating entire cache '" + cache.getName() + "' for operation "
+ context.getOperation());
logger.trace("Invalidating entire cache '" + cache.getName() + "' for operation " +
context.getOperation());
}
doClear(cache);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,6 @@ class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemov
CacheOperationInvocationContext<CacheRemoveOperation> context, CacheOperationInvoker invoker) {
CacheRemoveOperation operation = context.getOperation();
boolean earlyRemove = operation.isEarlyRemove();
if (earlyRemove) {
removeValue(context);
@@ -68,8 +67,8 @@ class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemov
Object key = generateKey(context);
Cache cache = resolveCache(context);
if (logger.isTraceEnabled()) {
logger.trace("Invalidating key [" + key + "] on cache '" + cache.getName()
+ "' for operation " + context.getOperation());
logger.trace("Invalidating key [" + key + "] on cache '" + cache.getName() +
"' for operation " + context.getOperation());
}
doEvict(cache, key);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,8 +50,8 @@ class CacheRemoveOperation extends AbstractJCacheKeyOperation<CacheRemove> {
}
/**
* Specify if the cache entry should be remove before invoking the method. By default, the
* cache entry is removed after the method invocation.
* Specify if the cache entry should be removed before invoking the method.
* <p>By default, the cache entry is removed after the method invocation.
* @see javax.cache.annotation.CacheRemove#afterInvocation()
*/
public boolean isEarlyRemove() {
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache.interceptor;
import java.util.Collection;
import java.util.Collections;
import javax.cache.annotation.CacheInvocationContext;
import org.springframework.cache.Cache;
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;
import javax.cache.annotation.CacheInvocationContext;
import javax.cache.annotation.CacheInvocationParameter;
@@ -17,6 +17,7 @@
package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheKeyInvocationContext;
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.cache.annotation.CacheMethodDetails;
/**
@@ -17,6 +17,7 @@
package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheMethodDetails;
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheKeyGenerator;
import javax.cache.annotation.CacheKeyInvocationContext;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,14 +25,16 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.util.Assert;
/**
* Cache decorator which synchronizes its {@link #put}, {@link #evict} and {@link #clear}
* operations with Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager},
* performing the actual cache put/evict/clear operation only in the after-commit phase of a
* successful transaction. If no transaction is active, {@link #put}, {@link #evict} and
* Cache decorator which synchronizes its {@link #put}, {@link #evict} and
* {@link #clear} operations with Spring-managed transactions (through Spring's
* {@link TransactionSynchronizationManager}, performing the actual cache
* put/evict/clear operation only in the after-commit phase of a successful
* transaction. If no transaction is active, {@link #put}, {@link #evict} and
* {@link #clear} operations will be performed immediately, as usual.
*
* <p>Use of more aggressive operations such as {@link #putIfAbsent} cannot be deferred
* to the after-commit phase of a running transaction. Use these with care.
* <p><b>Note:</b> Use of immediate operations such as {@link #putIfAbsent}
* cannot be deferred to the after-commit phase of a running transaction.
* Use these with care in a transactional environment.
*
* @author Juergen Hoeller
* @author Stephane Nicoll
@@ -54,6 +56,7 @@ public class TransactionAwareCacheDecorator implements Cache {
this.targetCache = targetCache;
}
/**
* Return the target Cache that this Cache should delegate to.
*/
@@ -19,6 +19,7 @@ package org.springframework.mail.javamail;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
@@ -17,6 +17,7 @@
package org.springframework.mail.javamail;
import java.beans.PropertyEditorSupport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
@@ -17,6 +17,7 @@
package org.springframework.mail.javamail;
import java.io.InputStream;
import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
@@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.activation.FileTypeMap;
import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
@@ -17,6 +17,7 @@
package org.springframework.mail.javamail;
import java.util.Date;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
@@ -18,6 +18,7 @@ package org.springframework.scheduling.commonj;
import java.util.LinkedList;
import java.util.List;
import javax.naming.NamingException;
import commonj.timers.Timer;
@@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import javax.naming.NamingException;
import commonj.work.Work;
@@ -18,6 +18,7 @@ package org.springframework.scheduling.quartz;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.quartz.SchedulerConfigException;
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
import org.quartz.Scheduler;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache;
import java.util.ArrayList;
import java.util.List;
import javax.cache.Cache;
import javax.cache.CacheManager;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheMethodDetails;
@@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CachePut;
@@ -18,6 +18,7 @@ package org.springframework.cache.jcache.interceptor;
import java.lang.reflect.Method;
import java.util.Comparator;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyGenerator;
import javax.cache.annotation.CacheRemove;
@@ -17,6 +17,7 @@
package org.springframework.cache.jcache.interceptor;
import java.io.IOException;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheMethodDetails;
import javax.cache.annotation.CachePut;
@@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import javax.cache.annotation.CacheInvocationContext;
import javax.cache.annotation.CacheMethodDetails;
import javax.cache.annotation.CacheResolver;
@@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Set;
import javax.cache.annotation.CacheInvocationParameter;
import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CacheMethodDetails;

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