Compare commits

...

307 Commits

Author SHA1 Message Date
Spring Buildmaster 45eb23bd21 Release version 5.1.5.RELEASE 2019-02-13 05:51:16 +00:00
Stephane Nicoll d703ca95d7 Upgrade to Reactor Californium SR5 2019-02-12 21:29:25 +01:00
Juergen Hoeller 106a757098 Polishing 2019-02-12 09:07:58 +01:00
Juergen Hoeller 8637540678 Expose empty annotation array as empty AnnotationAttributes array
Closes gh-22405
2019-02-12 09:07:51 +01:00
Sebastien Deleuze 5bb1c3e1e3 Deprecate SqlXmlObjectMappingHandler
This class is only known to be used in spring-data-jdbc-ext project
which was never upgraded to Spring Framework 5.x and is no longer
actively developed.

Closes gh-11647
2019-02-11 13:18:28 +01:00
Sebastien Deleuze 2a0a002bd3 Improve Kotlin documentation
Closes gh-22400
2019-02-11 13:08:04 +01:00
dzou 514f7e3328 Add link to Kotlin sample for Spring Cloud GCP
Closes gh-2070
2019-02-11 13:08:04 +01:00
Juergen Hoeller cdd0456aa4 Upgrade to Tomcat 9.0.16 and Log4J 2.11.2 2019-02-11 11:51:41 +01:00
Juergen Hoeller 9f03d158ce Upgrade to Checkstyle 8.17 and Mockito 2.24 2019-02-08 18:03:07 +01:00
Juergen Hoeller ba0c48b933 Polishing 2019-02-08 18:02:28 +01:00
Mansur Mustaquim 82dbde13b6 Fix for ScriptUtils failure when '--' occurs inside a multi-line comment on the same line as '*/' (#22392)
* Test for multi-line comment block where the comment end delimiter occurs on a line starting with the single-line comment prefix
* ScriptUtils successfully parses a SQL script containing a multi-line comment block where the comment-end delimiter occurs on a line starting with the single-line comment prefix.
2019-02-08 16:20:51 +01:00
Stephane Nicoll a698adf125 Merge pull request #22382 from artembilan
* pr/22382:
  Polish contribution
  Polish warning message
2019-02-08 08:49:34 +01:00
Stephane Nicoll 50e4308779 Polish contribution
Closes gh-22382
2019-02-08 08:48:58 +01:00
Artem Bilan 07bac70c09 Polish warning message
See gh-22382
2019-02-08 08:48:18 +01:00
Juergen Hoeller cc740dfd93 Upgrade to Groovy 2.5.6 and Hibernate ORM 5.1.17 2019-02-07 23:02:59 +01:00
Juergen Hoeller 15af0d9787 Polishing 2019-02-07 23:02:35 +01:00
Rossen Stoyanchev 2b974da395 Use snapshot instead of libs-snapshot repository
The latter has stale Reactor snapshots
2019-02-07 14:34:59 -05:00
Rossen Stoyanchev e7c038f2d2 Switch to Reactor Californium snapshots 2019-02-07 11:59:54 -05:00
Juergen Hoeller b8e663c531 AbstractAutoProxyCreator ignores unused early proxy references
Closes gh-22370
2019-02-07 15:57:44 +01:00
Juergen Hoeller 0f73a69033 AbstractApplicationContext resets local listeners to pre-refresh state
Closes gh-22325
2019-02-07 15:56:46 +01:00
Juergen Hoeller e9626779ee @Resource provides dependency descriptor for resolving beans by name
Closes gh-22359
2019-02-07 15:56:00 +01:00
Juergen Hoeller 5f4c461d4f Documentation revision for @PostConstruct/PreDestroy and @Required
Closes gh-22348
2019-02-07 15:53:55 +01:00
Brian Clozel ef8652615c Log exception at ERROR level in CompositeLog
Fixes gh-22364
2019-02-06 19:58:41 +01:00
Sebastien Deleuze d1e5a3af9f Fix truncated Value#value javadoc
Closes gh-22331
2019-02-06 19:28:31 +01:00
Juergen Hoeller 9895e44d73 Polishing 2019-02-05 16:03:24 +01:00
Juergen Hoeller 643a68f81b Detect existing jar URLs from URLClassLoader.getURLs()
Closes gh-22346
2019-02-05 16:02:50 +01:00
Juergen Hoeller ac4525ddf8 Detect MariaDB as MySQL (for mariadb-java-client 2.4+ compatibility)
Closes gh-22344
2019-02-05 16:02:17 +01:00
Yoann Rodière 17caac8f1f Add tests for SpringBeanContainer (Hibernate ORM integration) and fix the behavior when requesting named beans (#22260)
* Add integration tests for SpringBeanContainer (Hibernate ORM integration)
* Autowire bean properties of beans retrieved by name in SpringBeanContainer
* Add integration tests for fallback cases in SpringBeanContainer (Hibernate ORM integration)
* Fix SpringBeanContainer incorrectly losing the bean name when calling the fallback producer

(cherry picked from commit 00855c4f5f)
2019-02-05 16:01:40 +01:00
Juergen Hoeller 165d2511b9 Upgrade to Apache HttpClient 4.5.7 and Commons FileUpload 1.4
Includes RxJava 2.2.6, Netty 4.1.33, Undertow 2.0.17.
2019-02-05 00:46:07 +01:00
Juergen Hoeller d27bae245a Polishing 2019-02-05 00:45:28 +01:00
Juergen Hoeller 0ebc020b21 Load-time weaving support for WildFly 13+ (JBoss Modules 1.8+)
Fixes gh-22297
2019-02-05 00:44:52 +01:00
Juergen Hoeller 59a9c8e004 MethodReference.MethodValueRef.setValue throws SpelEvaluationException
Closes gh-22336
2019-02-05 00:43:56 +01:00
Juergen Hoeller ca7634dfe8 Avoid duplicate class introspection during findAnnotationOnBean
Closes gh-22318
2019-02-05 00:42:24 +01:00
Juergen Hoeller 5eca512c46 Ref doc mentions SimpleTransactionScope next to SimpleThreadScope
Closes gh-22180
2019-02-05 00:41:53 +01:00
Stephane Nicoll 99da6e9723 Merge pull request #22337 from mhewedy
* pr/22337:
  Polish "Fix use CompletableFuture in DeferredResultReturnValueHandlerTest"
  Fix use CompletableFuture in DeferredResultReturnValueHandlerTest
2019-02-04 10:33:58 +01:00
Stephane Nicoll 1241c3b2d1 Merge pull request #22339 from vpavic
* pr/22339:
  Polish "Improve spring-context-indexer documentation"
  Improve spring-context-indexer documentation
2019-02-04 10:33:54 +01:00
Stephane Nicoll 7c62d7cfe2 Polish "Fix use CompletableFuture in DeferredResultReturnValueHandlerTest"
Closes gh-22337
2019-02-04 10:31:31 +01:00
Muhammad Hewedy 6507b09c7f Fix use CompletableFuture in DeferredResultReturnValueHandlerTest
See gh-22337
2019-02-04 10:24:52 +01:00
Stephane Nicoll 229f354df1 Polish "Improve spring-context-indexer documentation"
Closes gh-22339
2019-02-04 10:22:43 +01:00
Vedran Pavic 43ea25e413 Improve spring-context-indexer documentation
See gh-22339
2019-02-04 10:17:34 +01:00
Rossen Stoyanchev 4560dc2818 Improve empty body check
Fixes gh-22265
2019-01-25 15:48:04 -05:00
Juergen Hoeller d0033f12d0 ApplicationListenerMethodAdapter uses target method for order lookup
Fixes #22307
2019-01-25 15:44:43 +01:00
Juergen Hoeller 85ec9b9df2 Avoid Class.getPackage() in favor of plain Class.getName() checks
Fixes #22306
2019-01-25 15:35:49 +01:00
Arjen Poutsma 4732f83d70 Fix Java 9 Build
Fix Java 9 build by replacing deprecated method.
2019-01-24 15:44:58 +01:00
Juergen Hoeller 7cc700435b HandlerMethod skips interface parameter introspection for return value
Fixes #22303
2019-01-24 15:18:55 +01:00
Juergen Hoeller 493e9c1ff0 Consistent upgrade to Rome 1.12 and WebJars Locator 0.36 2019-01-24 15:18:43 +01:00
Sam Brannen edadb9efb6 Remove obsolete PetClinic Example section of Testing chapter
Issue: #22288
2019-01-23 16:40:21 +01:00
Rossen Stoyanchev 810b615471 Correct issus in Spring MVC section
Fixes #22282
2019-01-22 09:06:18 -05:00
Rossen Stoyanchev 51f9e0aaca Typo in webmvc.adoc 2019-01-22 09:06:18 -05:00
Brian Clozel d6aa589c50 Wrap DecodingException in DefaultServerRequest
Prior to this commit, Spring WebFlux function would let
`DecodingException` thrown by codecs bubble up to the web handler level.
Since this exception is not handled by default there, the response would
be turned into a HTTP 500 status.

In the annotation model, `ArgumentResolver` implementations wrap this
exception with a `ServerWebInputException`, which itself extends
`ResponseStatusException`. The latter is supported by the error handling
infrastructure as a HTTP 400 response.

This commit ensures that `DecodingException` instances are properly
wrapped in `ServerWebInputException` at the `ServerRequest` level
directly, thus supporting all setup modes ("standalone" and through the
`DispatcherHandler`).

Fixes #22290
2019-01-22 14:54:44 +01:00
Sebastien Deleuze fc6cff53bb Clarify documentation about JSON Views
This commit intends to clarify the documentation by avoiding confusion
between @JsonView and Spring MVC JSON views.

Fixes #22280
2019-01-22 10:51:25 +01:00
Rossen Stoyanchev 20f4022e7b Correctly truncate logging of response body
Fixes #22287
2019-01-21 09:57:52 -05:00
Rossen Stoyanchev 020c537c03 Add note to CorsFilter section
Fixes #19841
2019-01-21 09:47:30 -05:00
Rossen Stoyanchev e373b46660 Jackson2JsonDecoder tolerates null literal
Fixes #22042
2019-01-18 18:27:40 -05:00
Rossen Stoyanchev 5dcde9e7d7 Trim decoded SSE data
Fixes #22043
2019-01-18 18:13:58 -05:00
Rossen Stoyanchev ef72ef54fa Avoid NPE when setting warnLogCategory
Fixes #22159
2019-01-18 18:08:48 -05:00
Rossen Stoyanchev a77eee899a Document synchronous use of the WebClient
Fixes #22173
2019-01-18 17:46:16 -05:00
Rossen Stoyanchev 9837ec5904 Fix Javadoc typos
Closes #22261
2019-01-17 18:01:08 -05:00
Rossen Stoyanchev bdac937a43 Replace more references to issue tracker
Fixes #22254
2019-01-17 17:08:39 -05:00
Sanghyuk Jung 6ca3884759 Update links to issue tracker 2019-01-17 16:44:41 -05:00
Rossen Stoyanchev 189e1afc6e Use try-with-resources in documentation samples
Fixes #22269
2019-01-17 12:53:59 -05:00
Rossen Stoyanchev d1862a26dd Typo in web documentation
Fixes #22270
2019-01-17 12:27:00 -05:00
Brian Clozel 2b65d0e51f Fix error when writing empty String to DataBuffer
Prior to this commit, `DataBuffer.write` would throw an
`IllegalStateException` when called with an empty `String`, since the
`CharsetEncoder` would be flushed on an incorrent state.

This commit skips entirely the encoding phase for empty `String`.

Fixes #22262
2019-01-17 11:09:48 -05:00
Arjen Poutsma 86fb43900e Deprecate JiBX marshaller
Resolves #22249
2019-01-14 11:50:21 +01:00
Sam Brannen e1e6224acb Document effect of preemptive timeouts on transactional tests
Issue: SPR-17647
2019-01-09 16:38:47 +01:00
Sam Brannen cf565067fe Document effect of @DirtiesContext when used with constructor injection
Issue: SPR-17654
2019-01-09 15:43:41 +01:00
Sam Brannen 2159518252 Improve documentation for DI options in the TestContext framework 2019-01-09 15:43:31 +01:00
Spring Buildmaster 754ad4d0d3 Next Development Version 2019-01-09 12:43:27 +00:00
Juergen Hoeller 72dddfbc7b Polishing 2019-01-09 12:26:58 +01:00
Rossen Stoyanchev dc3f953f4b Correction for commit #b219c6c
Issue: SPR-17630
2019-01-08 22:43:42 -05:00
Juergen Hoeller 4058361e84 Upgrade to Reactor Californium SR4 2019-01-08 23:37:26 +01:00
Andrzej Leśkiewicz 952045c216 SPR-17606 @Profile mishandles "not" operand mixed with "&" (#2066)
Correct handling of not/and expressions in ProfilesParser

Issue: SPR-17606
2019-01-08 22:24:15 +01:00
Juergen Hoeller 815f151448 Upgrade to Checkstyle 8.16 2019-01-08 21:57:24 +01:00
Juergen Hoeller 605e2477b9 Polishing 2019-01-08 21:57:13 +01:00
Sam Brannen 304c85ec70 Link explicitly to JUnit 5.3.2 instead of current version 2019-01-08 18:08:31 +01:00
Juergen Hoeller f56fa91430 Polishing 2019-01-08 17:11:34 +01:00
Juergen Hoeller 9cb5369cb9 DependencyDescriptor supports TypeDescriptor resolution for fields
This allows for proper nested type conversion in @Value Optional fields analogous to method parameters, through a new TypeDescriptor-based method in the TypeConverter SPI. As an additional and less involved measure that is worth backporting, DefaultListableBeanFactory defensively checks for pre-converted Optional wrappers.

Issue: SPR-17607
2019-01-08 17:11:27 +01:00
Juergen Hoeller a82f049083 FormHttpMessageConverter officially supports non-String form values
Issue: SPR-17645
2019-01-08 17:11:07 +01:00
Rossen Stoyanchev b219c6ce15 Adjust UriComponentsBuilder#toUriString behavior
Commit #93b7a4 added support for pre-configuring URI variables at the
UriComponentsBuilder level, and also changed toUriString to encode
template and URI variables separately. However this went a bit too far
causing side effects for URLs with curly braces that don't represent
URI variables.

This commit restores the original toUriString behavior which is to
encode template and URI variables sepraately only if URI variables have
been pre-configured.

Issue: SPR-17630
2019-01-08 11:06:33 -05:00
Sam Brannen 17a4193810 Link explicitly to JUnit 4.12 instead of beta version
For details, see: https://github.com/junit-team/junit4/issues/1585
2019-01-08 16:29:46 +01:00
Sam Brannen 29ab38acb2 Provide external links to JUnit in published Javadoc API 2019-01-08 16:19:01 +01:00
Michel Schudel 4938dab0ae Fix XML parser default value handling
The xml parser does not fill in defaults provided in the XSD when
validation is disabled. As a result, attributes like default-lazy-init
will not receive the value "default" but an empty string.

With this commit, BeanDefinitionParserDelegate now takes this into
account, checking default values against empty string as well as
"default".

As a consequence, default-lazy-init attribute should now work correctly
even when the XSD validation is disabled.

Issue: SPR-8335
2019-01-08 15:36:01 +01:00
王诗峣 b94e8c4bef Fix ClassCastException in FormHttpMessageConverter
We should not cast MultiValueMap<String, ?> to MultiValueMap<String, String>
2019-01-08 12:19:51 +01:00
Brian Clozel abc68ef8ea Revert "package list URL for Reactor javadoc in Dokka"
This reverts commit dc2535516c.
The Reactor project reverted its Javadoc changes.
2019-01-08 10:31:00 +01:00
Juergen Hoeller d37a18ff03 Upgrade to Hibernate Validator 6.0.14 and Apache Johnzon 1.1.11
Includes OkHttp MockWebServer 3.12.1.
2019-01-08 00:50:44 +01:00
Juergen Hoeller 11976fa949 Upgrade to Groovy 2.5.5 and RxJava 2.2.5 2019-01-08 00:32:46 +01:00
Juergen Hoeller 6e3f974951 HttpHeaders.writableHttpHeaders properly handles HttpHeaders.EMPTY
Issue: SPR-17633
2019-01-08 00:32:27 +01:00
Juergen Hoeller 1faeeaea14 HandlerMethodParameter defensively handles interface annotation arrays
Issue: SPR-17629
2019-01-08 00:32:09 +01:00
Brian Clozel dc2535516c Fix package list URL for Reactor javadoc in Dokka
Reactor is now building its Javadoc with a recent JDK version, which
changes the structure of the published HTML pages.

Without this change, the build fails during the Dokka generation with
the following exception:

```
Exception while loading package-list from
ExternalDocumentationLinkImpl(
  url=http://projectreactor.io/docs/core/release/api/,
  packageListUrl=http://projectreactor.io/docs/core/release/api/package-list)
```

This commit now points to the `/element-list` page, which seems to
contain the same information as the `package-list` page.
2019-01-07 20:53:56 +01:00
Rossen Stoyanchev 673a20cb10 Defensive initialization of AsyncXMLInputFactory
Aalto's InputFactoryImpl already disables loading of external entities
by default (property "javax.xml.stream.isSupportingExternalEntities").
This commit goes further by applying the same defensive measures as we
do elsewhere for XMLInputFactory, which disables DTD completely.
Arguably there is no good reason to enable that by default in WebFlux.
2019-01-07 13:52:46 -05:00
Brian Clozel f52f3a2f35 Upgrade to Reactor Californium SNAPSHOTs 2019-01-07 18:10:55 +01:00
Stephane Nicoll 77129f5a2b Polish 2019-01-05 09:57:46 +01:00
Stephane Nicoll d289befa2b Fix assertions 2019-01-03 14:20:57 +01:00
Stephane Nicoll b802c28d27 Merge pull request #2068 from Niconal
* pr/2068:
  Polish "Add missing [ in toString of WebSocketMessageBrokerStats"
  Add missing [ in toString of WebSocketMessageBrokerStats
2019-01-03 13:55:40 +01:00
Stephane Nicoll 556656b35a Polish "Add missing [ in toString of WebSocketMessageBrokerStats"
Closes gh-2068
2019-01-03 13:55:03 +01:00
Niconal 74630a1b0c Add missing [ in toString of WebSocketMessageBrokerStats
See gh-2068
2019-01-03 13:54:16 +01:00
Rossen Stoyanchev 63984800e4 Lenient URI template encoding
URI template encoding ignores mismatched curly braces, treating them as
literal parts instead.

Issue: SPR-17630
2019-01-02 16:36:08 -05:00
Rossen Stoyanchev 4b24bcb799 More accurate checks for presence of MediaType.ALL
Typically a straight up equals as well as Collections#contains
checks for MediaType.ALL is susceptible to the presence of
media type parameters.

This commits adds equalsTypeAndSubtype as well as an
isPresentIn(Collection<MimeType>) methods to MimeType to faciliate
with checks for MediaType.ALL.

Issue: SPR-17550
2019-01-02 14:32:50 -05:00
Rossen Stoyanchev 1cb9f2c7b2 Explicit HEAD sorted higher than implicit one
Same fix as #7cdcc1 but for WebFlux.

Issue: SPR-14182
2019-01-02 09:23:05 -05:00
Stephane Nicoll 72fbbb2403 Merge pull request #2064 from pierDipi
* pr/2064:
  Fix typo
2019-01-01 11:07:29 +01:00
Pier Dipi d459e1ad61 Fix typo
Closes gh-2064
2019-01-01 11:07:11 +01:00
Sebastien Deleuze 78a6429c32 Document NumberUtils.parseNumber() trim behavior
Issue: SPR-9523
2018-12-28 09:58:25 +01:00
Chen Dayu bd6432cb79 Fix formatting in data-access.adoc (#2062) 2018-12-26 15:08:44 +01:00
Sébastien Deleuze fced4e1f9c Merge pull request #2061 from Gyllsdorff
Fix spelling of "reactive HttpClient" in doc
2018-12-26 13:54:48 +01:00
Gyllsdorff 56d93bac89 Fix spelling of "reactive HttpClient" in doc 2018-12-26 13:13:09 +01:00
Juergen Hoeller 8d1de75b60 Upgrade to WebJars Locator 0.36 and OkHttp 3.12.1
Includes JRuby 9.2.5 and Jetty Reactive HttpClient 1.0.2.
2018-12-25 13:22:17 +01:00
Juergen Hoeller b2756f5bd2 Relaxed position assertion (for overflows in large inline maps)
Issue: SPR-17605
2018-12-25 13:22:00 +01:00
Juergen Hoeller 31a24720a6 Consistent support for EnumSet subclasses in CollectionFactory
Issue: SPR-17619
2018-12-25 13:20:31 +01:00
Juergen Hoeller 7a7958f275 MockMvcResultMatchers.forwardedUrl argument declared as nullable
Issue: SPR-17623
2018-12-25 13:20:09 +01:00
Stephane Nicoll ca9c34710f Merge pull request #2052 from igor-suhoruko
* pr/2052:
  Polish "Join identical catch branches"
  Join identical catch branches
2018-12-25 09:46:53 +01:00
Stephane Nicoll 9cbd585c30 Polish "Join identical catch branches"
Closes gh-2052
2018-12-25 09:46:35 +01:00
igor-suhorukov a218bf40cd Join identical catch branches
See gh-2052
2018-12-25 09:46:11 +01:00
Stephane Nicoll 93e7a0a59d Merge pull request #1452 from diguage
* pr/1452:
  Polish "Refactor duplicate code"
  Refactor duplicate code
2018-12-21 15:10:05 +01:00
Stephane Nicoll b83ceab88a Polish "Refactor duplicate code"
Closes gh-1452
2018-12-21 15:07:09 +01:00
diguage c15bbd675f Refactor duplicate code
See gh-1452
2018-12-21 15:06:56 +01:00
Arjen Poutsma 5a8b8b11e4 Add test for calculateCapacity
Issue: SPR-17558
Closes gh-2054
2018-12-20 21:34:15 +01:00
Arjen Poutsma a00be62b04 Calculating capacity before allocation.
This commit optimizes the `CharSequenceEncoder` to allocate `DataBuffer`
instances with a predicted capacity.

Issue: SPR-17558
2018-12-20 21:33:50 +01:00
Brian Clozel 4955d08f28 Use DataBuffer.write in CharSequenceEncoder
Since SPR-17558, `DataBuffer` now offers a new method to write Strings
to them. This commit makes `CharSequenceEncoder` use that.

Issue: SPR-17558
2018-12-20 21:33:44 +01:00
Brian Clozel 6361b0cb23 Write CharSequence instances to DataBuffers
Prior to this commit, one could write a `CharSequence` to an existing
`DataBuffer` instance by turning it into a byte array or `ByteBuffer`
first. This had the following disadvantages:

1. Memory allocation was not efficient (not leveraging pooled memory
when available)
2. Dealing with `CharsetEncoder` is not always easy
3. `DataBuffer` implementations, like `NettyDataBuffer` can use
optimized implementations in some cases

This commit adds a new `DataBuffer#write(CharSequence, Charset)` method
for those cases and also an `ensureCapacity` method useful for checking
that the current buffer has enough capacity to write to it..

Issue: SPR-17558
2018-12-20 21:33:33 +01:00
Arjen Poutsma 5e4a8966ee Make TomcatHttpHandlerAdapter aware of request/response wrappers
This commit makes TomcatServerHttpRequest aware of
HttpServletRequestWrappers, and TomcatServerHttpResponse aware of
HttpServletResponseWrappers.

Issue: SPR-17611
2018-12-19 12:16:14 +01:00
Violeta Georgieva 09da10cc6c Propagate the cancel signal to the downstream
Issue: SPR-17609
2018-12-18 15:04:08 -05:00
Sam Brannen 44f39d4ce0 Fix Java comment in Reference Manual 2018-12-18 13:22:24 +01:00
Stephane Nicoll 1d593a970a Merge pull request #2057 from kimsaabyepedersen
* pr/2057:
  Polish "Fix method name in comment"
  Fix method name in comment
2018-12-18 07:56:43 +01:00
Stephane Nicoll e42cf9dc56 Polish "Fix method name in comment"
Closes gh-2057
2018-12-18 07:56:10 +01:00
Kim Saabye Pedersen 65cb935333 Fix method name in comment
See gh-2057
2018-12-18 07:55:49 +01:00
Juergen Hoeller 0e8ed5931d Revised backport version 5.0.11
Issue: SPR-17410
Issue: SPR-17433
2018-12-17 18:19:21 +01:00
Juergen Hoeller a240cfcf2f Consistent support for if-(un)modified-since as ZonedDateTime/Instant
Includes DefaultRequestBodyUriSpec pre-resolving URI for HttpRequest.

Issue: SPR-17571
2018-12-17 16:21:39 +01:00
Juergen Hoeller 199be6aec5 ValidationUtils.invokeValidator assertion for non-null target object 2018-12-17 14:24:56 +01:00
Juergen Hoeller 99da8e1477 Upgrade to Jackson 2.9.8 2018-12-17 14:24:43 +01:00
Juergen Hoeller 2f04cbba51 Upgrade to Gradle 4.10.3
Issue: SPR-17155
2018-12-17 14:24:34 +01:00
Juergen Hoeller fc9d1760be Revised c-namespace example
Issue: SPR-17601
2018-12-17 14:24:21 +01:00
Juergen Hoeller aab421167b Revised format annotation docs 2018-12-13 17:19:50 +01:00
stsypanov 112cc70231 Improve performance of ConcurrentReferenceHashMap creation 2018-12-13 16:57:48 +01:00
igor-suhorukov 93189a6733 String.indexOf() expressions can be replaced with a call to the String.contains() method available in Java 5 and newer. 2018-12-13 12:29:31 +01:00
Stephane Nicoll 81d77b9872 Merge pull request #2050 from diguage
* pr/2050:
  Fix sample in EnableAsync Javadoc
2018-12-13 10:18:08 +01:00
diguage ee95a110bd Fix sample in EnableAsync Javadoc
Closes gh-2050
2018-12-13 10:16:56 +01:00
Juergen Hoeller c48672c4c7 ParameterNameDiscoverer may return individual null entries in an array
Issue: SPR-17565
2018-12-12 21:56:17 +01:00
Juergen Hoeller ef72baad3a Revised @AspectJ vs XML section
Issue: SPR-17597
2018-12-12 21:56:01 +01:00
Rossen Stoyanchev 14e87d2733 Add reference to ConcurrentWebSocketSessionDecorator in the docs.
Issue: SPR-12886
2018-12-12 11:57:51 -05:00
Rossen Stoyanchev 388ce92861 Enable io.netty.leakDetection.level=paranoid in tests
Issue: SPR-17574
2018-12-12 11:40:33 -05:00
Rossen Stoyanchev 38ae282c3b Update log category precision for all tests
Replace the full category capped at 36 chars with the class name only
and 1 char per package, e.g. org.apache.commons.Foo -> o.a.c.Foo
2018-12-12 11:40:33 -05:00
Rossen Stoyanchev 05d616240a StringHttpMessageConverter defaults to UTF-8 for JSON
Issue: SPR-17568
2018-12-12 11:40:33 -05:00
Rossen Stoyanchev 8eef97da33 HTTP header adapters print header values
Issue: SPR-17546
2018-12-12 11:40:33 -05:00
Rossen Stoyanchev 270099383b Add protected method in StandaloneMockMvcBuilder
To allow sub-classes to register additional MVC infrastructure.

Issue: SPR-17520
2018-12-12 11:40:33 -05:00
Juergen Hoeller 0ad35053fb Upgrade to CGLIB 3.2.10
Includes upgrade to JarJar 1.7.2 and Tomcat 9.0.14.

Issue: SPR-17595
2018-12-12 16:03:31 +01:00
Arjen Poutsma 058608021e Fix invalid String representation for composed RequestPredicates
Issue: SPR-17594
2018-12-12 15:33:33 +01:00
Juergen Hoeller 106ae0cc5b Polishing 2018-12-12 13:21:06 +01:00
Juergen Hoeller 7b7a8196f5 Revised HttpHeaders javadoc 2018-12-12 13:20:58 +01:00
Juergen Hoeller 2c98c1b81a Relaxed assertion in NotificationPublisherAwareLazyTargetSource
Issue: SPR-17592
2018-12-12 12:16:14 +01:00
Juergen Hoeller 7b9c30f26e Explicit documentation notes on JMS 2.0 vs 1.1 compatibility
Issue: SPR-17583
2018-12-12 12:15:34 +01:00
Juergen Hoeller 474ac2d975 Revised SimpleEvaluationContext example
Issue: SPR-17581
2018-12-12 12:11:15 +01:00
Juergen Hoeller 6eb0a60df9 Polishing 2018-12-12 11:16:53 +01:00
Juergen Hoeller 5bbbc82e19 Consistent handling of null header values in HttpHeaders
Issue: SPR-17588
2018-12-12 11:16:45 +01:00
Juergen Hoeller 4b4503085a Prefer SLF4J SPI over Log4J in case of log4j-to-slf4j bridge
Issue: SPR-17586
2018-12-12 11:16:36 +01:00
Stephane Nicoll 73a96c5152 Merge pull request #2049 from wonwoo
* pr/2049:
  Fix typo in javadoc
2018-12-12 08:00:48 +01:00
wonwoo 9a13d93a6b Fix typo in javadoc
Closes gh-2049
2018-12-12 08:00:15 +01:00
Kamil Szymanski 894044cea0 Optimize ResourceUrlProvider
Closes gh-2008
2018-12-11 12:12:15 +01:00
Stephane Nicoll 0550c08f86 Merge pull request #2044 from chendy560
* pr/2044:
  Fix typo
2018-12-08 16:03:17 +01:00
chendayu 073f304db9 Fix typo
Closes gh-2044
2018-12-08 16:02:52 +01:00
Stephane Nicoll 58a99e3983 Merge pull request #2043 from marchpig
* pr/2043:
  Fix typo in webflux.adoc
2018-12-08 16:00:48 +01:00
Sangwoo Lee 62f2a6352f Fix typo in webflux.adoc
Closes gh-2043
2018-12-08 16:00:30 +01:00
Stephane Nicoll 528b9c17ec Merge pull request #2046 from yepapa
* pr/2046:
  Fix typo in websocket.adoc
2018-12-08 16:00:00 +01:00
Juhyoung Jeon 31318652ea Fix typo in websocket.adoc
Closes gh-2046
2018-12-08 15:59:45 +01:00
Arjen Poutsma f15bd88211 Fix checkstyle 2018-12-07 15:06:56 +01:00
Stephane Nicoll 220951707b Merge pull request #2042 from PascalSchumacher
* pr/2042:
  Fix typo in core-beans.adoc
2018-12-07 11:29:56 +01:00
Pascal Schumacher 18ac86ae16 Fix typo in core-beans.adoc
Closes gh-2042
2018-12-07 11:29:35 +01:00
Arjen Poutsma 3258ac1ec4 Expose request in WebClientResponseException
This commit exposes the request that lead to it in
WebClientResponseException, as a HttpRequest object.

Issue: SPR-17087
2018-12-07 11:08:02 +01:00
Stephane Nicoll 54f5b7d0ee Polish
Issue: SPR-17572
2018-12-07 10:54:03 +01:00
Juergen Hoeller aaaf81ed99 Polishing 2018-12-06 15:53:57 +01:00
Juergen Hoeller 6a012147c4 Consistent support for last-modified argument as Instant/ZonedDateTime
Issue: SPR-17571
2018-12-06 15:53:47 +01:00
Lars Grefer 9abd4ed33d Allow Instant and ZonedDateTime as Last-Modified header.
Issues: SPR-17571
2018-12-06 14:49:12 +01:00
Juergen Hoeller cf7ee0739f Upgrade to Checkstyle 8.15 2018-12-05 14:13:57 +01:00
Juergen Hoeller db63f7dd4a StandardEvaluationContext.setVariable leniently ignores null name
Issue: SPR-17565
2018-12-05 14:13:24 +01:00
Rossen Stoyanchev 7a5f8e03bc Refine check for multiple subscribers
Commit #c187cb2 introduced proactive rejection of multiple subscribers
in ReactorClientHttpResponse, instead of hanging indefinitely as per
https://github.com/reactor/reactor-netty/issues/503.

However FluxReceive also rejects subsequent subscribers if the response
is consumed fully, as opposed to being canceled, e.g. as with
bodyToMono(Void.class). In that case, a subsequent subscriber causes
two competing error signals to be sent, and one gets dropped and
logged by reactor-core.

This fix ensures that a rejection is raised in
ReactorClientHttpResponse only after a cancel() was detected.

Issue: SPR-17564
2018-12-04 21:27:37 -05:00
Juergen Hoeller 50e5bdb813 Clarified VfsResource constructor
Issue: SPR-17563
2018-12-04 22:09:06 +01:00
Juergen Hoeller 9efea7eb73 MockHttpServletRequest preserves original Accept-Language header value
Issue: SPR-17566
2018-12-04 22:07:43 +01:00
Juergen Hoeller d3cdecc621 Upgrade to Rome 1.12 and POI 4.0.1 2018-12-04 02:16:03 +01:00
Juergen Hoeller c024bdcc6f Cleanup after unexpected exception from external delegation call
Issue: SPR-17559
2018-12-04 02:15:47 +01:00
Juergen Hoeller 6d7827e36b Polishing 2018-12-03 23:53:00 +01:00
Juergen Hoeller d5dab12909 NettyDataBufferFactory.join returns single-element buffer as-is
Issue: SPR-17560
2018-12-03 23:52:35 +01:00
Juergen Hoeller 7854b7ac40 Avoid log statements between resource opening and returning
Issue: SPR-17559
2018-12-03 23:50:50 +01:00
Pascal Schumacher 26b1c848b8 Fix typo in core-beans.adoc (Obvious Fix) 2018-12-03 22:09:06 +01:00
Juergen Hoeller 5e153e4a77 Revised section on custom BeanPostProcessors
Issue: SPR-17556
2018-12-03 19:52:25 +01:00
Juergen Hoeller 16e9b83d43 JavaMailSenderImpl calls sendMessage with empty array instead of null
Issue: SPR-17540
2018-12-03 19:49:21 +01:00
Juergen Hoeller 516c01c438 Upgrade javadoc links to Jackson 2.9
Includes rollback to Hibernate ORM 5.1.16 for integration tests.
2018-12-03 19:09:39 +01:00
Juergen Hoeller 43077072ad Upgrade to Netty 4.1.32, Undertow 2.0.16, OpenPDF 1.2.7
Includes Hibernate ORM 5.1.17 for integration tests.
2018-12-03 18:28:50 +01:00
Juergen Hoeller 0841dc5f99 Restore Hibernate ORM 5.1 compatibility in HibernateTransactionManager
Issue: SPR-17557
2018-12-03 18:27:30 +01:00
Rossen Stoyanchev 15f8863f19 Add sub-section on validation for functional endpoints
Issue: SPR-17401
2018-11-30 10:56:29 -05:00
Bertrand Guay-Paquet bc3b95db92 Fix typo in Javadoc for transaction Propagation annotation 2018-11-29 16:32:28 -05:00
Francesco Komauli 66f822e600 Fix typo in Javadoc for UnsupportedMediaTypeStatusException
Response status 415 (unsupported media type) reported as of 416 (which is Range Not Satisfiable), mismatching with superclass constructor parameter HttpStatus.UNSUPPORTED_MEDIA_TYPE
2018-11-29 16:36:56 +01:00
Spring Buildmaster dfc193b85e Next Development Version 2018-11-27 09:29:05 +00:00
Rossen Stoyanchev 029101c79a Merge pull request #2025 from neVERberleRfellerER/SPR-17535 2018-11-26 16:02:08 -05:00
Rossen Stoyanchev 3eee118b44 Polish 2018-11-26 16:00:47 -05:00
Ondrej Kraus 959cf61647 Sanitize request fragment in ResourceUrlEncodingFilter
Prior to this change, ResourceUrlEncodingFilter would try to resolve
the resource path using request URL without removing fragment first,
whereas only paths should be used.

This commit synchronizes behavior of ResourceUrlEncodingFilter with
behavior of ResourceUrlProvider.

Issue: SPR-17535
2018-11-26 13:48:48 -05:00
Sam Brannen 82eb82a040 Upgrade to JUnit 5.3.2
Issue: SPR-17537
2018-11-25 21:44:12 +01:00
Juergen Hoeller 80b8382f00 Revised alias definition example in reference documentation
Issue: SPR-17536
2018-11-25 21:27:49 +01:00
Juergen Hoeller ebbe14c363 ResolvableType-based matching consistently respects generic factory method return type (even for pre-initialized raw singleton instance)
Issue: SPR-17524
2018-11-25 21:27:19 +01:00
Juergen Hoeller c2e545776d Upgrade to RxJava 2.2.4 2018-11-23 23:46:37 +01:00
Juergen Hoeller 97ac1c22c5 DefaultResponseErrorHandler makes use of HttpStatus.isError()
Issue: SPR-17439
2018-11-23 19:27:47 +01:00
Sam Brannen a528407d0c Suppress warning 2018-11-23 18:05:47 +01:00
Sam Brannen 58cde3c2e6 Avoid test compile-time dependency on junit-jupiter-engine
Issue: SPR-17533
2018-11-23 18:05:34 +01:00
Arjen Poutsma fedbb09ad9 Improve RouterFunctions reference documentation
Changed WebFlux.fn docs to use router function builder.

Issue: SPR-17016
2018-11-23 17:48:11 +01:00
Sam Brannen 81fde5ec41 Ensure that MethodParameter.findParameterIndex() is thread-safe
Prior to this commit, parallel invocations of
MethodParameter.findParameterIndex() (invoked indirectly via
SynthesizingMethodParameter.forParameter() and
MethodParameter.forParameter()) could intermittently lead to an
IllegalArgumentException being thrown due to a race condition in the
internal implementation of the JDK's
java.lang.reflect.Executable.getParameters() method.

This commit addresses this issue by introducing a fallback for-loop
that iterates over the candidate parameters a second time using
equality checks instead of identity checks.

Issue: SPR-17534
2018-11-23 17:37:20 +01:00
Sam Brannen aa7f69a5d1 Ensure that parameter resolution in SpringExtension is thread-safe
Prior to this commit, parallel execution of @BeforeEach and @AfterEach
methods that accepted @Autowired arguments would fail intermittently
due to a race condition in the internal implementation of the JDK's
java.lang.reflect.Executable.getParameters() method.

This commit addresses this issue by creating instances of
SynthesizingMethodParameter via
SynthesizingMethodParameter.forExecutable(Executable, int) instead of
SynthesizingMethodParameter.forParameter(Parameter), since the latter
looks up the parameter index by iterating over the array returned by
Executable.getParameters() (which is not thread-safe).

Issue: SPR-17533
2018-11-23 16:35:19 +01:00
Sebastien Deleuze 91de8d265e Fix ProtobufDecoder handling of split message size
This commit introduces a new readMessageSize(DataBuffer input) private
method, inspired from CodedInputStream#readRawVarint32(int, InputStream)
and adapted for DataBuffer using MessageDecoderFunction fields in
order to support use cases where the message size is split between
distinct chunks.

It also fixes handling of end of streams by using
DataBuffer#readableByteCount instead of -1 which is only relevant with
InputStream.

Issue: SPR-17429
2018-11-23 14:22:58 +01:00
Juergen Hoeller 77ab88b144 Polishing 2018-11-23 13:56:02 +01:00
Juergen Hoeller 738097def2 DefaultResponseErrorHandler detects non-standard error code as well
Issue: SPR-17439
2018-11-23 13:55:50 +01:00
Juergen Hoeller b90553db5c Upgrade to Reactor Californium SR3 2018-11-22 22:03:56 +01:00
Juergen Hoeller 56234fe877 Polishing 2018-11-22 22:03:36 +01:00
Juergen Hoeller c16f36b537 Upgrade to Mockito 2.23.4, Selenium 3.141.59, JSON-P 1.1.4 2018-11-22 18:24:18 +01:00
Juergen Hoeller ae8f680d2e Polishing 2018-11-22 18:21:56 +01:00
Juergen Hoeller bf272b0b21 Nullability fine-tuning based on IntelliJ IDEA 2018.3 inspection
Issue: SPR-15540
2018-11-22 16:12:38 +01:00
Juergen Hoeller b1b28d4641 ToStringVisitor consistently returns platform-independent line breaks
Issue: SPR-17322
2018-11-22 16:11:59 +01:00
Johnny Lim 17b2b8af86 Remove an unnecessary local variable 2018-11-22 13:56:22 +01:00
Juergen Hoeller 262c702da4 CachingMetadataReaderFactory releases shared cache Map on clearCache()
LocalResourceCache properly initializes cacheLimit on construction.

Issue: SPR-17527
2018-11-22 11:20:47 +01:00
Rossen Stoyanchev 548126ddd8 Consistently pass param info to ServerWebInputException
Issue: SPR-17232
2018-11-21 14:41:42 -05:00
Rossen Stoyanchev 7e9857a663 ForwardedHeaderTransformer handles encoding correctly
Issue: SPR-17525
2018-11-21 10:54:39 -05:00
Rossen Stoyanchev 0134c9d608 Update @since version after backport 2018-11-21 09:35:33 -05:00
Brian Clozel 5fe628a811 Polish 2018-11-21 10:27:49 +01:00
Rossen Stoyanchev 759013eb17 Consistent isEmpty check in WebTestClient
Issue: SPR-17522
2018-11-20 23:02:53 -05:00
Rossen Stoyanchev a55ca56e34 BEST_MATCHING_HANDLER_ATTRIBUTE for spring-webmvc
Issue: SPR-17518
2018-11-20 22:31:02 -05:00
Rossen Stoyanchev d6a5c3428b Improve docs on STOMP / WebSocket frame max size
Issue: SPR-17514
2018-11-20 21:59:47 -05:00
Rossen Stoyanchev 24848ec1bc Configurable TcpClient for ReactorNettyTcpClient
Issue: SPR-17523
2018-11-20 21:20:21 -05:00
Juergen Hoeller fef0e21d8b Remove unused LinkedList import 2018-11-20 22:16:51 +01:00
Juergen Hoeller 8c7579eba8 Polishing 2018-11-20 22:06:44 +01:00
Juergen Hoeller a3d763d137 Consistent parameter resolution for batch updates (IN clauses etc)
Includes deprecation of (NamedParameter)BatchUpdateUtils in favor of inlined code in (NamedParameter)JdbcTemplate itself.

Issue: SPR-17402
2018-11-20 22:05:53 +01:00
Juergen Hoeller 2a5d7690b6 CglibAopProxy skips method proxy for equals/hashCode/toString override
Issue: SPR-17500
2018-11-20 22:04:28 +01:00
Juergen Hoeller f5aeb81473 SerializedBeanFactoryReference falls back to dummy with specific id
Issue: SPR-17508
2018-11-20 22:02:10 +01:00
stsypanov 02d3cfa42d Use ArrayList instead of LinkedList 2018-11-20 21:54:51 +01:00
Vojtech Janota 12f168290d SPR-17492: FastByteArrayOutputStream.read byte-to-int conversion 2018-11-20 17:08:01 +01:00
Arjen Poutsma 88cb126511 Add RequestPredicate Visitor to WebFlux.fn
This commit introduces RequestPredicates.Visitor, an implementation of
the visitor pattern for RequestPredicates.

Issue: SPR-17322
2018-11-20 14:05:17 +01:00
Arjen Poutsma f3c29fe2e6 Add test for UriUtils.encode(String, Charset)
Issue: SPR-17451
2018-11-20 10:51:19 +01:00
Rossen Stoyanchev abf9ce8a34 Improve handling of empty response with Mono<T>
Issue: SPR-17560
2018-11-19 16:48:38 -05:00
Arjen Poutsma 63275ae2b7 Add Test for LeakAwareDataBufferFactory 2018-11-19 16:56:25 +01:00
Brian Clozel 3203d39821 Remove Content-Length response header from errors
Prior to this commit, when errors happened before the response was
committed, the `Content-Length` response header would be left as is.
This can be problematic since the error can be handled later in the
chain and the response body changed accordingly. For example, Spring
Boot renders error pages in those cases. If the `Content-Length` is set,
HTTP clients can get confused and only consider part of the error
response body.

This commit ensures that any `Content-Length` response header is removed
in case of errors, if the response is not already committed.

This is done at the `AbstractServerHttpResponse` level, since errors can
be handled in multiple places and the response itself is the safest
place to handle this case.

As a consequence, this commit also removes `Content-Length` checks in
`EncoderHttpMessageWriter` since we now consider that we should rely on
the response body we're about to write rather than any previously set
value.

Issue: SPR-17502
2018-11-19 15:49:54 +01:00
Juergen Hoeller ce5c65c0b0 Upgrade to JAXB 2.3.1, Groovy 2.5.4, Jetty 9.4.14, Tomcat 9.0.13
Includes JAX-WS 2.3.1, Awaitility 3.1.3, OkHttp 3.12, Woodstox 5.2.
2018-11-19 12:41:26 +01:00
Stephane Nicoll afa38f5f97 Merge pull request #2019 from Hanope
* pr/2019:
  Polish contribution
  Fix typos
2018-11-19 08:50:49 +01:00
Stephane Nicoll 7b6f2f8fb3 Polish contribution
Closes gh-2019
2018-11-19 08:45:33 +01:00
Hanope bfb49c7249 Fix typos
See gh-2019
2018-11-19 08:41:21 +01:00
HeemangHan 729ce4108d Correct typos (#2018) 2018-11-17 16:31:01 +01:00
Rossen Stoyanchev 1a37345e84 Fix checkstyle violation and polish 2018-11-16 19:42:42 -05:00
Rossen Stoyanchev c89e6c616a Improve logging of request mapping information
Issue: SPR-17450
2018-11-16 17:30:18 -05:00
Arjen Poutsma 539cfc24c6 Refactor AbstractEncoderTestCase
Refactor AbstractEncoderTestCase to resemble AbstractDecoderTestCase

Issue: SPR-17449
2018-11-16 14:33:26 +01:00
Arjen Poutsma 39ce989d1a Add and use AbstractDecoderTestCase
Introduce new base test case for decoder tests, and use it.

Issue: SPR-17449
2018-11-16 14:33:26 +01:00
Brian Clozel 0f2d9df79f Upgrade to Reactor Californium SNAPSHOTs 2018-11-16 11:13:17 +01:00
Jay Bryant b9603680bc Fixing typoes
Jim Showalter found two typoes in the web section. This PR fixes them. Thanks, Jim.
2018-11-14 16:10:17 -05:00
Rossen Stoyanchev 7bbd4c681f Merge pull request #2010 from dimitrisli/SPR-17459 2018-11-13 23:05:07 -05:00
Rossen Stoyanchev ba3fef3e8a Refactor media types parsing improvements
Issue: SPR-17459
2018-11-13 23:02:09 -05:00
Dimitrios Liapis f4b05dc2e7 MediaType parsing supports comma inside quotes
Issue: SPR-17459
2018-11-13 16:59:57 -05:00
Rossen Stoyanchev 46a5fb7a91 Configurable Marshaller/Unmarshaller in JAXB2 codecs
Issue: SPR-17388
2018-11-13 16:56:56 -05:00
Juergen Hoeller 093254b2b3 Jackson2ObjectMapperBuilder stores visibility declarations in order
Issue: SPR-17489
2018-11-13 21:17:55 +01:00
Rossen Stoyanchev 9f857c1f16 Replace constant exceptions with inlined ones
Issue: SRP-17475
2018-11-13 14:49:23 -05:00
Rossen Stoyanchev 75b1396768 Fall back on default server response status code
Update the ServerHttpRespnose contract to indicate that server specific
sub-classes should fall back on the default status, if a status code
has not been set explicitly.

Issue: SPR-17368
2018-11-13 14:10:48 -05:00
Arjen Poutsma 4182935b7a Revert optimization in StringDecoder
This commit reverts the first optimizations listed in
fa096dc60f, as the default delimiters
do vary, namely by the charset given in the message mime type.
The mimetype charset might not be compatible with ASCII (i.e. anything
but UTF-8 or ISO-8859-1, for instance it might be UTF-16), and will not
successfully find the default delimiters as a consequence.

Added test to indicate the bug.
2018-11-13 13:38:13 +01:00
Arjen Poutsma 445b76bbe8 Polishing 2018-11-13 13:35:37 +01:00
Arjen Poutsma 3bab3515b1 Add and use AbstractEncoderTestCase
Introduce new base test case for encoder tests, and use it.

Issue: SPR-17449
2018-11-13 13:35:37 +01:00
Arjen Poutsma 0c0de851f4 Add LeakAwareDataBufferFactory
Introduce a data buffer factory that can check for memory leaks in
@After methods.

Issue: SPR-17449
2018-11-13 13:35:37 +01:00
Arjen Poutsma e31914bada Polishing 2018-11-13 13:35:37 +01:00
Juergen Hoeller 40148c0560 Consistent use of ResolvableType.toClass() for assignability checks
Issue: SPR-17086
2018-11-12 20:29:37 +01:00
Juergen Hoeller 3a66927bd2 Polishing 2018-11-12 16:43:43 +01:00
Juergen Hoeller c58da71006 Synthesize parameter annotations from interface methods as well
Issue: SPR-17460
2018-11-12 16:23:14 +01:00
Juergen Hoeller 818c2aa3b9 ServerRequest.attribute(name) defensively accesses concurrent map
Issue: SPR-17486
2018-11-12 16:22:42 +01:00
Juergen Hoeller d96a7b4bfc ClientRequest.attribute(name) defensively handles null value
Issue: SPR-17486
2018-11-12 11:52:21 +01:00
Sam Brannen b3aad549c9 Fix @since tag 2018-11-10 16:56:39 +01:00
Sam Brannen 865f1f692a Introduce tests for @Sql and @Transactional support in @Nested test classes
This commit was inspired by the following question on Stack Overflow.

https://stackoverflow.com/questions/53236807/spring-boot-testing-run-script-in-a-nested-test-sql-script-sql
2018-11-10 15:47:30 +01:00
Sam Brannen 93df24af16 Polishing 2018-11-10 15:47:29 +01:00
Rossen Stoyanchev a5339d71ea WebClient handles no Content-Type with data correctly
Issue: SPR-17482
2018-11-09 16:16:03 -05:00
Rossen Stoyanchev e4c84ec757 Consistent default encoding in DefaultUriBuilderFactory
Issue: SPR-17465
2018-11-09 14:13:51 -05:00
Rossen Stoyanchev f5da737bd4 Polish 2018-11-08 23:13:48 -05:00
Rossen Stoyanchev c187cb2fa1 Ensure client response is drained with onStatus hook
Issue: SPR-17473
2018-11-08 22:41:22 -05:00
Rossen Stoyanchev ed1d63dcc3 ResolvableMethod copy in spring-messaging src/test 2018-11-08 13:29:21 -05:00
Juergen Hoeller e26ae9853e Up-to-date version and link in ASM/CGLIB/Objenesis package javadoc
Issue: SPR-17267
Issue: SPR-17372
2018-11-08 16:56:48 +01:00
Juergen Hoeller 362c59c310 Consistently return empty array in case of empty batch arguments
Issue: SPR-17476
2018-11-08 13:43:07 +01:00
Stephane Nicoll b6e8674700 Merge pull request #2011 from bactoria
* pr/2011:
  Fix typo
2018-11-07 07:48:22 +01:00
황준오 db8a94ce5f Fix typo
Closes gh-2011
2018-11-07 07:47:55 +01:00
Stephane Nicoll 3232825a55 Clarify @Async documentation
Issue: SPR-17458
2018-11-06 08:30:30 +01:00
Juergen Hoeller e71ff2901a Polishing 2018-11-05 22:59:33 +01:00
Juergen Hoeller d9c1811d21 Deprecate NON_BRIDGED_METHODS constant as of 5.0.11 as well
Issue: SPR-17464
2018-11-05 22:59:18 +01:00
Juergen Hoeller 5e7a8b275d Polishing 2018-11-05 19:33:24 +01:00
Juergen Hoeller ea3250c8d6 Explicit notes on class/method-level semantics in class hierarchies
Issue: SPR-17445
2018-11-05 19:32:34 +01:00
Juergen Hoeller b1f5f51503 Synchronized onRefresh execution for concurrent ContextRefreshedEvent
Issue: SPR-17442
2018-11-05 19:27:43 +01:00
Rossen Stoyanchev 2ce03f34d9 Fix formatting on index.adoc 2018-11-05 13:16:04 -05:00
Rossen Stoyanchev 9280e32d5d Feature Github Wiki more prominently
Issue: SPR-17469
2018-11-05 13:12:18 -05:00
Juergen Hoeller 5cd525a2b0 Enforce use of ClassLoader.loadClass in case of temporary ClassLoader
Issue: SPR-17452
2018-11-05 17:44:46 +01:00
Juergen Hoeller 2ac4355ec0 ASM ClassReader leniently handles label offset mismatch (again)
Issue: SPR-17467
2018-11-05 17:44:23 +01:00
Juergen Hoeller a3cd7af72d Polishing 2018-11-05 12:27:35 +01:00
Juergen Hoeller 6a9f91081e Upgrade to Netty 4.1.31 and Undertow 2.0.15 2018-11-05 12:27:20 +01:00
Juergen Hoeller f65408f646 Avoid references to groovy-all artifact across all modules
Issue: SPR-17446
2018-11-05 12:27:07 +01:00
Juergen Hoeller 59fa647e2d StandardEvaluationContext supports concurrent variable modification
Issue: SPR-17448
2018-11-05 12:26:35 +01:00
Juergen Hoeller 0a7dcf14f9 Deprecate ReflectionUtils.invokeJdbcMethod (for removal in 5.2)
Issue: SPR-17464
2018-11-05 12:26:20 +01:00
Stephane Nicoll 86846507e2 Remove trailing whitespace 2018-11-05 07:44:36 +01:00
Rossen Stoyanchev 133b8b0b5a Polish 2018-11-02 16:19:53 -04:00
Juergen Hoeller dc8f6f7177 Upgrade to CGLIB 3.2.9
This CGLIB upgrade literally does not make any difference to Spring users since its only purpose is a default ASM7 declaration in its AsmApi class (which we patched a month ago). We nevertheless leave our local AsmApi copy in place for the time being, allowing for an individual upgrade of the declared ASM API version in the future.

Issue: SPR-17267
Issue: SPR-17371
2018-11-02 19:55:13 +01:00
Rossen Stoyanchev c2b55e60cd Fix failing test
After the fix #658c7f for lenient parsing of dates, the error message
raised uses an HttpHeaders-formatted date. As a result the test
verifying the error message fails in the beginning of the month between
1-9 because it's formatted slightly differently.
2018-11-01 15:27:39 -04:00
Rossen Stoyanchev 48654c6483 Polish 2018-11-01 14:21:00 -04:00
Stephane Nicoll 47aec50917 Merge pull request #2004 from MasterEx
* pr/2004:
  Polish reference documentation
2018-11-01 10:22:27 +09:00
Periklis Ntanasis 6f36514369 Polish reference documentation
Issue: SRP-17453

Closes gh-2004
2018-11-01 10:21:48 +09:00
Rossen Stoyanchev 9da9bb9652 Fix since tag 2018-10-31 10:56:17 -04:00
Rossen Stoyanchev 3f42e16172 Increase sharing among InvocableHandlerMethod variants
In particular between reactive and non-reactive web variants, but
also preparing for a messaing reactive variant.
2018-10-30 17:15:09 -04:00
Rossen Stoyanchev 7c36549e3a Consistent InvocableHandlerMethod implementations
This commit makes the 3 existing InvocableHandlerMethod types more
consistent and comparable with each other.

1. Use of consistent method names and method order.

2. Consistent error formatting.

3. Explicit for loops for resolving argument values in webflux variant
because that makes it more readable, creates less garabage, and it's
the only way to bring consistency since the other two variants cannot
throw exceptions inside Optional lambdas (vs webflux variant which can
wrap it in a Mono).

4. Use package private HandlerMethodArgumentComposite in webflux
variant in order to pick up the resolver argument caching that the
other two variants have.

5. Polish tests.

6. Add missing tests for messaging variant.
2018-10-30 16:36:01 -04:00
Juergen Hoeller 991e9f4269 Upgrade to Joda-Time 2.10.1 2018-10-29 18:33:36 +01:00
Brian Clozel 2a41067a17 Update reactive streams spec URL in ref docs 2018-10-29 15:10:03 +01:00
Sam Brannen 42a95b8f35 Fix typo and polish 2018-10-29 14:47:20 +01:00
Rossen Stoyanchev 76d203fc61 Merge pull request #2001 from tamkylet/readme-writing-edit 2018-10-29 09:28:18 -04:00
Rossen Stoyanchev 9fc7bfde99 Polish README 2018-10-29 09:27:19 -04:00
tamkylet a999c4aa7e readme writing changes to improve readability 2018-10-29 09:18:45 -04:00
Spring Buildmaster a82d726f76 Next Development Version 2018-10-29 10:33:23 +00:00
551 changed files with 10848 additions and 4903 deletions
+7 -7
View File
@@ -29,7 +29,7 @@ If you have a question, check StackOverflow using
Find an existing discussion or start a new one if necessary.
If you suspect an issue, perform a search in the
[JIRA issue tracker](https://jira.spring.io/browse/SPR), using a few different keywords.
[Github issue tracker](https://github.com/spring-projects/spring-framework/issues), using a few different keywords.
When you find related issues and discussions, prior or current, it helps you to learn and
it helps us to make a decision.
@@ -42,7 +42,7 @@ Before you create a ticket, please take the time to [research first](#discuss).
If creating a ticket after a discussion on StackOverflow, please provide a self-sufficient description in the ticket, independent of the details on StackOverview. We understand this is extra work but the issue tracker is an important place of record for design discussions and decisions that can often be referenced long after the fix version, for example to revisit decisions, to understand the origin of a feature, and so on.
When ready create a ticket in the [JIRA issue tracker](https://jira.spring.io/browse/SPR).
When ready create a ticket in the [Github issue tracker](https://github.com/spring-projects/spring-framework/issues).
#### Ticket Lifecycle
@@ -66,7 +66,7 @@ automatically when you submit a pull request.
1. For all but the most trivial of contributions, please [create a ticket](#create-a-ticket).
The purpose of the ticket is to understand and discuss the underlying issue or feature.
We use the JIRA issue tracker as the preferred place of record for conversations and
We use the GitHub issue tracker as the preferred place of record for conversations and
conclusions. In that sense discussions directly under a PR are more implementation detail
oriented and transient in nature.
@@ -75,7 +75,7 @@ oriented and transient in nature.
Backports to prior versions will be considered on a case-by-case basis and reflected as
the fix version in the issue tracker.
1. Use short branch names, preferably based on the JIRA issue (e.g. `SPR-1234`), or
1. Use short branch names, preferably based on the GitHub issue (e.g. `22276`), or
otherwise using succinct, lower-case, dash (-) delimited names, such as `fix-warnings`.
1. Choose the granularity of your commits consciously and squash commits that represent
@@ -84,12 +84,12 @@ multiple edits or corrections of the same logical change. See
for an overview of streamlining commit history.
1. Format commit messages using 55 characters for the subject line, 72 lines for the
description, followed by related issues, e.g. `Issues: SPR-1234, SPR-1235`.
description, followed by the issue fixed, e.g. `Fixes #22276`.
See the
[Commit Guidelines section of Pro Git](http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines)
for best practices around commit messages and use `git log` to see some examples.
1. List the JIRA issue number in the PR description.
1. List the GitHub issue number in the PR description.
If accepted, your contribution may be heavily modified as needed prior to merging.
You will likely retain author attribution for your Git commits granted that the bulk of
@@ -116,7 +116,7 @@ defines the source file coding standards we use along with some IDEA editor sett
The reference documentation is in the [src/docs/asciidoc](src/docs/asciidoc) directory and, in
[Asciidoctor](http://asciidoctor.org/) format. For trivial changes, you may be able to browse,
edit source files, and submit directly from Github.
edit source files, and submit directly from GitHub.
When making changes locally, use `./gradlew asciidoctor` and then browse the result under
`build/asciidoc/html5/index.html`.
+9 -27
View File
@@ -1,48 +1,30 @@
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework
This is the home of the Spring Framework, the foundation for all
[Spring projects](https://spring.io/projects). Together the Spring Framework and the family of Spring projects make up what we call "Spring".
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects is often referred to simply as "Spring".
Spring provides everything you need beyond the Java language to create enterprise
applications in a wide range of scenarios and architectures. Please read the
[Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction)
section in the reference for a more complete introduction.
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
## Code of Conduct
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc).
By participating you are expected to uphold this code.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Access to Binaries
For access to artifacts or a distribution zip, see the
[Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts)
wiki page.
For access to artifacts or a distribution zip, see the [Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts) wiki page.
## Documentation
The Spring Frameworks maintains reference documentation
([published](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and
[source](src/docs/asciidoc)),
Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](http://docs.spring.io/spring-framework/docs/current/javadoc-api/).
There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
The Spring Framework maintains reference documentation ([published](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](http://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## Build from Source
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
wiki page and also [CONTRIBUTING.md](CONTRIBUTING.md).
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wikipedia page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## Stay in Touch
Follow [@SpringCentral](https://twitter.com/springcentral),
[@SpringFramework](https://twitter.com/springframework), and its
[team members](https://twitter.com/springframework/lists/team/members) on Twitter.
In-depth articles can be found at [The Spring Blog](http://spring.io/blog/),
and releases are announced via our [news feed](http://spring.io/blog/category/news).
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](http://spring.io/blog/), and releases are announced via our [news feed](http://spring.io/blog/category/news).
## License
The Spring Framework is released under version 2.0 of the
[Apache License](http://www.apache.org/licenses/LICENSE-2.0).
The Spring Framework is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
+22 -18
View File
@@ -19,7 +19,7 @@ plugins {
ext {
linkHomepage = "https://projects.spring.io/spring-framework"
linkCi = "https://build.spring.io/browse/SPR"
linkIssue = "https://jira.spring.io/browse/SPR"
linkIssue = "https://github.com/spring-projects/spring-framework/issues"
linkScmUrl = "https://github.com/spring-projects/spring-framework"
linkScmConnection = "scm:git:git://github.com/spring-projects/spring-framework.git"
linkScmDevConnection = "scm:git:ssh://git@github.com:spring-projects/spring-framework.git"
@@ -30,22 +30,22 @@ ext {
aspectjVersion = "1.9.2"
freemarkerVersion = "2.3.28"
groovyVersion = "2.5.3"
groovyVersion = "2.5.6"
hsqldbVersion = "2.4.1"
jackson2Version = "2.9.7"
jettyVersion = "9.4.12.v20180830"
junit5Version = "5.3.1"
jackson2Version = "2.9.8"
jettyVersion = "9.4.14.v20181114"
junit5Version = "5.3.2"
kotlinVersion = "1.2.71"
log4jVersion = "2.11.1"
nettyVersion = "4.1.30.Final"
reactorVersion = "Californium-SR2"
log4jVersion = "2.11.2"
nettyVersion = "4.1.33.Final"
reactorVersion = "Californium-SR5"
rxjavaVersion = "1.3.8"
rxjavaAdapterVersion = "1.2.1"
rxjava2Version = "2.2.3"
rxjava2Version = "2.2.6"
slf4jVersion = "1.7.25" // spring-jcl + consistent 3rd party deps
tiles3Version = "3.0.8"
tomcatVersion = "9.0.12"
undertowVersion = "2.0.14.Final"
tomcatVersion = "9.0.16"
undertowVersion = "2.0.17.Final"
gradleScriptDir = "${rootProject.projectDir}/gradle"
withoutJclOverSlf4J = {
@@ -132,6 +132,7 @@ configure(allprojects) { project ->
test {
systemProperty("java.awt.headless", "true")
systemProperty("testGroups", project.properties.get("testGroups"))
systemProperty("io.netty.leakDetection.level", "paranoid")
scanForTestClasses = false
include(["**/*Tests.class", "**/*Test.class"])
// Since we set scanForTestClasses to false, we need to filter out inner
@@ -142,19 +143,20 @@ configure(allprojects) { project ->
}
checkstyle {
toolVersion = "8.14"
toolVersion = "8.17"
configDir = rootProject.file("src/checkstyle")
}
repositories {
maven { url "https://repo.spring.io/libs-release" }
maven { url "https://repo.spring.io/snapshot" } // Reactor
}
dependencies {
testCompile("junit:junit:4.12") {
exclude group: "org.hamcrest", module: "hamcrest-core"
}
testCompile("org.mockito:mockito-core:2.23.0") {
testCompile("org.mockito:mockito-core:2.24.0") {
exclude group: "org.hamcrest", module: "hamcrest-core"
}
testCompile("com.nhaarman:mockito-kotlin:1.6.0") {
@@ -185,10 +187,12 @@ configure(allprojects) { project ->
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"http://ehcache.org/apidocs/2.10.4",
"http://quartz-scheduler.org/api/2.2.1/",
"http://fasterxml.github.io/jackson-core/javadoc/2.8/",
"http://fasterxml.github.io/jackson-databind/javadoc/2.8/",
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.8/",
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/"
"http://fasterxml.github.io/jackson-core/javadoc/2.9/",
"http://fasterxml.github.io/jackson-databind/javadoc/2.9/",
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.9/",
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
"https://junit.org/junit4/javadoc/4.12/",
"https://junit.org/junit5/docs/${junit5Version}/api/"
] as String[]
}
@@ -276,7 +280,7 @@ configure(rootProject) {
testCompile("javax.servlet:javax.servlet-api:3.1.0")
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.hibernate:hibernate-core:5.1.16.Final")
testCompile("org.hibernate:hibernate-core:5.1.17.Final")
}
artifacts {
+1 -1
View File
@@ -1 +1 @@
version=5.1.2.BUILD-SNAPSHOT
version=5.1.5.RELEASE
+2 -2
View File
@@ -52,8 +52,8 @@ def customizePom(pom, gradleProject) {
}
}
issueManagement {
system = "Jira"
url = "https://jira.springsource.org/browse/SPR"
system = "GitHub"
url = "https://github.com/spring-projects/spring-framework/issues"
}
}
}
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -19,7 +19,7 @@ package org.aopalliance.intercept;
import java.lang.reflect.Constructor;
/**
* Description of an invocation to a constuctor, given to an
* Description of an invocation to a constructor, given to an
* interceptor upon constructor-call.
*
* <p>A constructor invocation is a joinpoint and can be intercepted
@@ -32,7 +32,7 @@ public interface MethodInvocation extends Invocation {
/**
* Get the method being called.
* <p>This method is a frienly implementation of the
* <p>This method is a friendly implementation of the
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the method being called
*/
@@ -63,7 +63,7 @@ import org.springframework.util.StringUtils;
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
/**
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
* Key used in ReflectiveMethodInvocation userAttributes map for the current joinpoint.
*/
protected static final String JOIN_POINT_KEY = JoinPoint.class.getName();
@@ -272,15 +272,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
}
}
catch (AmbiguousBindingException ambigEx) {
if (this.raiseExceptions) {
throw ambigEx;
}
else {
return null;
}
}
catch (IllegalArgumentException ex) {
catch (AmbiguousBindingException | IllegalArgumentException ex) {
if (this.raiseExceptions) {
throw ex;
}
@@ -723,17 +723,20 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
@Nullable
private final MethodProxy methodProxy;
private final boolean publicMethod;
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
this.publicMethod = Modifier.isPublic(method.getModifiers());
// Only use method proxy for public methods not derived from java.lang.Object
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
/**
@@ -742,7 +745,7 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.publicMethod && getMethod().getDeclaringClass() != Object.class) {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
@@ -795,7 +798,7 @@ class CglibAopProxy implements AopProxy, Serializable {
* <dt>For advised methods:</dt>
* <dd>If the target is static and the advice chain is frozen then a
* FixedChainStaticTargetInterceptor specific to the method is used to
* invoke the advice chain. Otherwise a DyanmicAdvisedInterceptor is
* invoke the advice chain. Otherwise a DynamicAdvisedInterceptor is
* used.</dd>
* <dt>For non-advised methods:</dt>
* <dd>Where it can be determined that the method will not return {@code this}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -133,7 +133,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
@@ -236,9 +236,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
@@ -297,7 +295,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
@@ -79,7 +79,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
/**
* The {@code $[targetClassName]} placeholder.
* Replaced with the fully-qualifed name of the {@code Class}
* Replaced with the fully-qualified name of the {@code Class}
* of the method invocation target.
*/
public static final String PLACEHOLDER_TARGET_CLASS_NAME = "$[targetClassName]";
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -77,8 +77,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
}
/**
* Subclasses can override this if it's possible to filter out
* some candidate classes.
* Subclasses can override this if it's possible to filter out some candidate classes.
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
@@ -758,7 +758,7 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
@Around(value="setAge(age)",argNames="age")
// @ArgNames({"age"}) // AMC needs more work here? ignoring pjp arg... ok??
// argNames should be suported in Around as it is in Pointcut
// argNames should be supported in Around as it is in Pointcut
public void changeReturnType(ProceedingJoinPoint pjp, int age) throws Throwable {
pjp.proceed(new Object[] {age*2});
}
@@ -884,12 +884,12 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
@Aspect
abstract class AbstractMakeModifiable {
public interface MutableModifable extends Modifiable {
public interface MutableModifiable extends Modifiable {
void markDirty();
}
public static class ModifiableImpl implements MutableModifable {
public static class ModifiableImpl implements MutableModifiable {
private boolean modified;
@@ -911,7 +911,7 @@ abstract class AbstractMakeModifiable {
@Before(value="execution(void set*(*)) && this(modifiable) && args(newValue)", argNames="modifiable,newValue")
public void recordModificationIfSetterArgumentDiffersFromOldValue(
JoinPoint jp, MutableModifable mixin, Object newValue) {
JoinPoint jp, MutableModifiable mixin, Object newValue) {
/*
* We use the mixin to check and, if necessary, change,
@@ -972,7 +972,7 @@ class MakeITestBeanModifiable extends AbstractMakeModifiable {
@DeclareParents(value = "org.springframework.tests.sample.beans.ITestBean+",
defaultImpl=ModifiableImpl.class)
public static MutableModifable mixin;
public static MutableModifiable mixin;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -157,7 +157,7 @@ public class DelegatingIntroductionInterceptorTests {
TimeStamped ts = (TimeStamped) pf.getProxy();
assertThat(ts, instanceOf(TimeStamped.class));
// Shoulnd't proxy framework interfaces
// Shouldn't proxy framework interfaces
assertTrue(!(ts instanceof MethodInterceptor));
assertTrue(!(ts instanceof IntroductionInterceptor));
@@ -132,7 +132,7 @@ public class HotSwappableTargetSourceTests {
@Test
public void testRejectsSwapToNull() {
IllegalArgumentException ex = testRejectsSwapToInvalidValue(null);
assertTrue(ex.getMessage().indexOf("null") != -1);
assertTrue(ex.getMessage().contains("null"));
}
// TODO test reject swap to wrong interface or class?
@@ -2,7 +2,7 @@
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
</Console>
</Appenders>
<Loggers>
@@ -2,7 +2,7 @@
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
</Console>
</Appenders>
<Loggers>
@@ -166,7 +166,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
}
/**
* Obtain a lazily initializted CachedIntrospectionResults instance
* Obtain a lazily initialized CachedIntrospectionResults instance
* for the wrapped object.
*/
private CachedIntrospectionResults getCachedIntrospectionResults() {
@@ -314,6 +314,7 @@ class ExtendedBeanInfo implements BeanInfo {
}
@Override
@Nullable
public Class<?> getPropertyType() {
if (this.propertyType == null) {
try {
@@ -425,6 +426,7 @@ class ExtendedBeanInfo implements BeanInfo {
}
@Override
@Nullable
public Class<?> getPropertyType() {
if (this.propertyType == null) {
try {
@@ -460,6 +462,7 @@ class ExtendedBeanInfo implements BeanInfo {
}
@Override
@Nullable
public Class<?> getIndexedPropertyType() {
if (this.indexedPropertyType == null) {
try {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.beans;
import java.lang.reflect.Field;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
/**
@@ -93,4 +94,27 @@ public interface TypeConverter {
<T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
throws TypeMismatchException;
/**
* Convert the value to the required type (if necessary from a String).
* <p>Conversions from String to any type will typically use the {@code setAsText}
* method of the PropertyEditor class, or a Spring Converter in a ConversionService.
* @param value the value to convert
* @param requiredType the type we must convert to
* (or {@code null} if not known, for example in case of a collection element)
* @param typeDescriptor the type descriptor to use (may be {@code null}))
* @return the new value, possibly the result of type conversion
* @throws TypeMismatchException if type conversion failed
* @since 5.1.4
* @see java.beans.PropertyEditor#setAsText(String)
* @see java.beans.PropertyEditor#getValue()
* @see org.springframework.core.convert.ConversionService
* @see org.springframework.core.convert.converter.Converter
*/
@Nullable
default <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
throw new UnsupportedOperationException("TypeDescriptor resolution not supported");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.CollectionFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
@@ -82,42 +81,6 @@ class TypeConverterDelegate {
}
/**
* Convert the value to the specified required type.
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* (or {@code null} if not known, for example in case of a collection element)
* @param methodParam the method parameter that is the target of the conversion
* (may be {@code null})
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
@Nullable
public <T> T convertIfNecessary(@Nullable Object newValue, @Nullable Class<T> requiredType,
@Nullable MethodParameter methodParam) throws IllegalArgumentException {
return convertIfNecessary(null, null, newValue, requiredType,
(methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType)));
}
/**
* Convert the value to the specified required type.
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* (or {@code null} if not known, for example in case of a collection element)
* @param field the reflective field that is the target of the conversion
* (may be {@code null})
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
@Nullable
public <T> T convertIfNecessary(@Nullable Object newValue, @Nullable Class<T> requiredType, @Nullable Field field)
throws IllegalArgumentException {
return convertIfNecessary(null, null, newValue, requiredType,
(field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType)));
}
/**
* Convert the value to the required type for the specified property.
* @param propertyName name of the property
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.lang.reflect.Field;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -41,15 +42,16 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
@Override
@Nullable
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType) throws TypeMismatchException {
return doConvert(value, requiredType, null, null);
return convertIfNecessary(value, requiredType, TypeDescriptor.valueOf(requiredType));
}
@Override
@Nullable
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable MethodParameter methodParam)
throws TypeMismatchException {
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
@Nullable MethodParameter methodParam) throws TypeMismatchException {
return doConvert(value, requiredType, methodParam, null);
return convertIfNecessary(value, requiredType,
(methodParam != null ? new TypeDescriptor(methodParam) : TypeDescriptor.valueOf(requiredType)));
}
@Override
@@ -57,21 +59,18 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
throws TypeMismatchException {
return doConvert(value, requiredType, null, field);
return convertIfNecessary(value, requiredType,
(field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType)));
}
@Nullable
private <T> T doConvert(@Nullable Object value,@Nullable Class<T> requiredType,
@Nullable MethodParameter methodParam, @Nullable Field field) throws TypeMismatchException {
@Override
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
try {
if (field != null) {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
}
else {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
}
return this.typeConverterDelegate.convertIfNecessary(null, null, value, requiredType, typeDescriptor);
}
catch (ConverterNotFoundException | IllegalStateException ex) {
throw new ConversionNotSupportedException(value, requiredType, ex);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -133,8 +133,7 @@ public interface BeanFactory {
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no bean definition
* with the specified name
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
* @throws BeansException if the bean could not be obtained
*/
Object getBean(String name) throws BeansException;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,8 @@ import org.springframework.util.ObjectUtils;
/**
* A simple descriptor for an injection point, pointing to a method/constructor
* parameter or a field. Exposed by {@link UnsatisfiedDependencyException}.
* Also available as an argument for factory methods, reacting to the
* requesting injection point for building a customized bean instance.
*
* @author Juergen Hoeller
* @since 4.3
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import java.lang.annotation.Target;
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
*
* <p>A common use case is to assign default field values using
* "#{systemProperties.myProp}" style expressions.
* {@code #{systemProperties.myProp}} style expressions.
*
* <p>Note that actual processing of the {@code @Value} annotation is performed
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
@@ -55,7 +55,7 @@ import java.lang.annotation.Target;
public @interface Value {
/**
* The actual value expression: e.g. "#{systemProperties.myProp}".
* The actual value expression: for example {@code #{systemProperties.myProp}}.
*/
String value();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -289,7 +289,8 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
* instance, invoking their {@code postProcessBeforeInitialization} methods.
* The returned bean instance may be a wrapper around the original.
* @param existingBean the new bean instance
* @param existingBean the existing bean instance
* @param beanName the name of the bean, to be passed to it if necessary
* (only passed to {@link BeanPostProcessor BeanPostProcessors};
* can follow the {@link #ORIGINAL_INSTANCE_SUFFIX} convention in order to
* enforce the given instance to be returned, i.e. no proxies etc)
@@ -305,7 +306,8 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
* instance, invoking their {@code postProcessAfterInitialization} methods.
* The returned bean instance may be a wrapper around the original.
* @param existingBean the new bean instance
* @param existingBean the existing bean instance
* @param beanName the name of the bean, to be passed to it if necessary
* (only passed to {@link BeanPostProcessor BeanPostProcessors};
* can follow the {@link #ORIGINAL_INSTANCE_SUFFIX} convention in order to
* enforce the given instance to be returned, i.e. no proxies etc)
@@ -337,8 +339,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* including its bean name.
* <p>This is effectively a variant of {@link #getBean(Class)} which preserves the
* bean name of the matching instance.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@code null} is disallowed.
* @param requiredType type the bean must match; can be an interface or superclass
* @return the bean name plus bean instance
* @throws NoSuchBeanDefinitionException if no matching bean was found
* @throws NoUniqueBeanDefinitionException if more than one matching bean was found
@@ -348,6 +349,22 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
*/
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
/**
* Resolve a bean instance for the given bean name, providing a dependency descriptor
* for exposure to target factory methods.
* <p>This is effectively a variant of {@link #getBean(String, Class)} which supports
* factory methods with an {@link org.springframework.beans.factory.InjectionPoint}
* argument.
* @param name the name of the bean to look up
* @param descriptor the dependency descriptor for the requesting injection point
* @return the corresponding bean instance
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
* @throws BeansException if the bean could not be created
* @since 5.1.5
* @see #getBean(String, Class)
*/
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
/**
* Resolve the specified dependency against the beans defined in this factory.
* @param descriptor the descriptor for the dependency (field/method/constructor)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
@@ -77,6 +78,9 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
@Nullable
private transient volatile ResolvableType resolvableType;
@Nullable
private transient volatile TypeDescriptor typeDescriptor;
/**
* Create a new descriptor for a method or constructor parameter.
@@ -301,7 +305,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
}
/**
* Build a ResolvableType object for the wrapped parameter/field.
* Build a {@link ResolvableType} object for the wrapped parameter/field.
* @since 4.0
*/
public ResolvableType getResolvableType() {
@@ -315,6 +319,21 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
return resolvableType;
}
/**
* Build a {@link TypeDescriptor} object for the wrapped parameter/field.
* @since 5.1.4
*/
public TypeDescriptor getTypeDescriptor() {
TypeDescriptor typeDescriptor = this.typeDescriptor;
if (typeDescriptor == null) {
typeDescriptor = (this.field != null ?
new TypeDescriptor(getResolvableType(), getDependencyType(), getAnnotations()) :
new TypeDescriptor(obtainMethodParameter()));
this.typeDescriptor = typeDescriptor;
}
return typeDescriptor;
}
/**
* Return whether a fallback match is allowed.
* <p>This is {@code false} by default but may be overridden to return {@code true} in order
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,32 +28,26 @@ import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.util.StringValueResolver;
/**
* {@link PlaceholderConfigurerSupport} subclass that resolves ${...} placeholders
* against {@link #setLocation local} {@link #setProperties properties} and/or system properties
* {@link PlaceholderConfigurerSupport} subclass that resolves ${...} placeholders against
* {@link #setLocation local} {@link #setProperties properties} and/or system properties
* and environment variables.
*
* <p>As of Spring 3.1, {@link org.springframework.context.support.PropertySourcesPlaceholderConfigurer
* PropertySourcesPlaceholderConfigurer} should be used preferentially over this implementation; it is
* more flexible through taking advantage of the {@link org.springframework.core.env.Environment Environment} and
* {@link org.springframework.core.env.PropertySource PropertySource} mechanisms also made available in Spring 3.1.
* more flexible through taking advantage of the {@link org.springframework.core.env.Environment} and
* {@link org.springframework.core.env.PropertySource} mechanisms also made available in Spring 3.1.
*
* <p>{@link PropertyPlaceholderConfigurer} is still appropriate for use when:
* <ul>
* <li>the {@code spring-context} module is not available (i.e., one is using Spring's
* {@code BeanFactory} API as opposed to {@code ApplicationContext}).
* <li>existing configuration makes use of the {@link #setSystemPropertiesMode(int) "systemPropertiesMode"} and/or
* {@link #setSystemPropertiesModeName(String) "systemPropertiesModeName"} properties. Users are encouraged to move
* away from using these settings, and rather configure property source search order through the container's
* {@code Environment}; however, exact preservation of functionality may be maintained by continuing to
* use {@code PropertyPlaceholderConfigurer}.
* <li>existing configuration makes use of the {@link #setSystemPropertiesMode(int) "systemPropertiesMode"}
* and/or {@link #setSystemPropertiesModeName(String) "systemPropertiesModeName"} properties.
* Users are encouraged to move away from using these settings, and rather configure property
* source search order through the container's {@code Environment}; however, exact preservation
* of functionality may be maintained by continuing to use {@code PropertyPlaceholderConfigurer}.
* </ul>
*
* <p>Prior to Spring 3.1, the {@code <context:property-placeholder/>} namespace element
* registered an instance of {@code PropertyPlaceholderConfigurer}. It will still do so if
* using the {@code spring-context-3.0.xsd} definition of the namespace. That is, you can preserve
* registration of {@code PropertyPlaceholderConfigurer} through the namespace, even if using Spring 3.1;
* simply do not update your {@code xsi:schemaLocation} and continue using the 3.0 XSD.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 02.10.2003
@@ -92,7 +86,6 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
* Set the system property mode by the name of the corresponding constant,
* e.g. "SYSTEM_PROPERTIES_MODE_OVERRIDE".
* @param constantName name of the constant
* @throws java.lang.IllegalArgumentException if an invalid constant was specified
* @see #setSystemPropertiesMode
*/
public void setSystemPropertiesModeName(String constantName) throws IllegalArgumentException {
@@ -124,14 +117,9 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
* against system environment variables. Note that it is generally recommended
* to pass external values in as JVM system properties: This can easily be
* achieved in a startup script, even for existing environment variables.
* <p><b>NOTE:</b> Access to environment variables does not work on the
* Sun VM 1.4, where the corresponding {@link System#getenv} support was
* disabled - before it eventually got re-enabled for the Sun VM 1.5.
* Please upgrade to 1.5 (or higher) if you intend to rely on the
* environment variable support.
* @see #setSystemPropertiesMode
* @see java.lang.System#getProperty(String)
* @see java.lang.System#getenv(String)
* @see System#getProperty(String)
* @see System#getenv(String)
*/
public void setSearchSystemEnvironment(boolean searchSystemEnvironment) {
this.searchSystemEnvironment = searchSystemEnvironment;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,6 +58,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -337,12 +338,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return initializeBean(beanName, existingBean, bd);
}
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
return resolveDependency(descriptor, requestingBeanName, null, null);
}
//-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
@@ -446,6 +441,28 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
//-------------------------------------------------------------------------
// Delegate methods for resolving injection points
//-------------------------------------------------------------------------
@Override
public Object resolveBeanByName(String name, DependencyDescriptor descriptor) {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
return getBean(name, descriptor.getDependencyType());
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
return resolveDependency(descriptor, requestingBeanName, null, null);
}
//---------------------------------------------------------------------
// Implementation of relevant AbstractBeanFactory template methods
//---------------------------------------------------------------------
@@ -510,12 +510,21 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Generics potentially only match on the target class, not on the proxy...
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
Class<?> targetType = mbd.getTargetType();
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance) &&
typeToMatch.isAssignableFrom(targetType)) {
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
// Check raw class match as well, making sure it's exposed on the proxy.
Class<?> classToMatch = typeToMatch.resolve();
return (classToMatch == null || classToMatch.isInstance(beanInstance));
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
return false;
}
if (typeToMatch.isAssignableFrom(targetType)) {
return true;
}
}
ResolvableType resolvableType = mbd.targetType;
if (resolvableType == null) {
resolvableType = mbd.factoryMethodReturnType;
}
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
}
}
return false;
@@ -1362,6 +1371,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
@@ -1391,13 +1401,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
throws ClassNotFoundException {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader classLoaderToUse = beanClassLoader;
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
classLoaderToUse = tempClassLoader;
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
@@ -1406,6 +1419,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
@@ -1415,18 +1429,31 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
return ClassUtils.forName((String) evaluated, classLoaderToUse);
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (classLoaderToUse != beanClassLoader) {
return ClassUtils.forName(className, classLoaderToUse);
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.beans.factory.support;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -28,6 +29,7 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import org.springframework.beans.BeanMetadataElement;
@@ -49,6 +51,18 @@ import org.springframework.util.ClassUtils;
*/
abstract class AutowireUtils {
private static final Comparator<Executable> EXECUTABLE_COMPARATOR = (e1, e2) -> {
boolean p1 = Modifier.isPublic(e1.getModifiers());
boolean p2 = Modifier.isPublic(e2.getModifiers());
if (p1 != p2) {
return (p1 ? -1 : 1);
}
int c1pl = e1.getParameterCount();
int c2pl = e2.getParameterCount();
return Integer.compare(c2pl, c1pl);
};
/**
* Sort the given constructors, preferring public constructors and "greedy" ones with
* a maximum number of arguments. The result will contain public constructors first,
@@ -57,16 +71,7 @@ abstract class AutowireUtils {
* @param constructors the constructor array to sort
*/
public static void sortConstructors(Constructor<?>[] constructors) {
Arrays.sort(constructors, (c1, c2) -> {
boolean p1 = Modifier.isPublic(c1.getModifiers());
boolean p2 = Modifier.isPublic(c2.getModifiers());
if (p1 != p2) {
return (p1 ? -1 : 1);
}
int c1pl = c1.getParameterCount();
int c2pl = c2.getParameterCount();
return (c1pl < c2pl ? 1 : (c1pl > c2pl ? -1 : 0));
});
Arrays.sort(constructors, EXECUTABLE_COMPARATOR);
}
/**
@@ -77,16 +82,7 @@ abstract class AutowireUtils {
* @param factoryMethods the factory method array to sort
*/
public static void sortFactoryMethods(Method[] factoryMethods) {
Arrays.sort(factoryMethods, (fm1, fm2) -> {
boolean p1 = Modifier.isPublic(fm1.getModifiers());
boolean p2 = Modifier.isPublic(fm2.getModifiers());
if (p1 != p2) {
return (p1 ? -1 : 1);
}
int c1pl = fm1.getParameterCount();
int c2pl = fm2.getParameterCount();
return (c1pl < c2pl ? 1 : (c1pl > c2pl ? -1 : 0));
});
Arrays.sort(factoryMethods, EXECUTABLE_COMPARATOR);
}
/**
@@ -158,7 +154,7 @@ abstract class AutowireUtils {
* on the given method itself.
* <p>For example, given a factory method with the following signature, if
* {@code resolveReturnTypeForFactoryMethod()} is invoked with the reflected
* method for {@code creatProxy()} and an {@code Object[]} array containing
* method for {@code createProxy()} and an {@code Object[]} array containing
* {@code MyService.class}, {@code resolveReturnTypeForFactoryMethod()} will
* infer that the target return type is {@code MyService}.
* <pre class="code">{@code public static <T> T createProxy(Class<T> clazz)}</pre>
@@ -278,7 +278,7 @@ public final class BeanDefinitionBuilder {
}
/**
* Set the depency check mode for this definition.
* Set the dependency check mode for this definition.
*/
public BeanDefinitionBuilder setDependencyCheck(int dependencyCheck) {
this.beanDefinition.setDependencyCheck(dependencyCheck);
@@ -39,7 +39,7 @@ class BeanDefinitionResource extends AbstractResource {
/**
* Create a new BeanDefinitionResource.
* @param beanDefinition the BeanDefinition objectto wrap
* @param beanDefinition the BeanDefinition object to wrap
*/
public BeanDefinitionResource(BeanDefinition beanDefinition) {
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
@@ -196,7 +196,7 @@ class ConstructorResolver {
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
@@ -276,11 +276,12 @@ class ConstructorResolver {
ambiguousConstructors);
}
if (explicitArgs == null) {
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
@@ -602,12 +603,13 @@ class ConstructorResolver {
}
}
Assert.state(argsToUse != null, "Unresolved factory method arguments");
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
private Object instantiate(
String beanName, RootBeanDefinition mbd, Object factoryBean, Method factoryMethod, Object[] args) {
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
try {
if (System.getSecurityManager() != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -677,7 +677,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (bd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition abd = (AbstractBeanDefinition) bd;
if (abd.hasBeanClass()) {
ann = AnnotationUtils.findAnnotation(abd.getBeanClass(), annotationType);
Class<?> beanClass = abd.getBeanClass();
if (beanClass != beanType) {
ann = AnnotationUtils.findAnnotation(beanClass, annotationType);
}
}
}
}
@@ -1093,8 +1096,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
Class<?> clazz = requiredType.getRawClass();
Assert.notNull(clazz, "Required type must have a raw Class");
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
@@ -1111,7 +1112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, clazz, args));
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
@@ -1124,14 +1125,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
candidates.put(beanName, getType(beanName));
}
}
String candidateName = determinePrimaryCandidate(candidates, clazz);
String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
if (candidateName == null) {
candidateName = determineHighestPriorityCandidate(candidates, clazz);
candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance == null || beanInstance instanceof Class) {
beanInstance = getBean(candidateName, clazz, args);
beanInstance = getBean(candidateName, requiredType.toClass(), args);
}
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
}
@@ -1185,13 +1186,20 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
@@ -1689,7 +1697,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
super.resolveCandidate(beanName, requiredType, beanFactory));
}
};
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
}
@@ -1750,7 +1759,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
// Lenient fallback: dummy factory in case of original factory not found...
return new DefaultListableBeanFactory();
DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory();
dummyFactory.serializationId = this.id;
return dummyFactory;
}
}
@@ -1915,8 +1926,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private Stream<Object> resolveStream(boolean ordered) {
DependencyDescriptor descriptorToUse = new StreamDependencyDescriptor(this.descriptor, ordered);
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
Assert.state(result instanceof Stream, "Stream expected");
return (Stream<Object>) result;
return (result instanceof Stream ? (Stream<Object>) result : Stream.of(result));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,9 +82,10 @@ public class ReplaceOverride extends MethodOverride {
if (this.typeIdentifiers.size() != method.getParameterCount()) {
return false;
}
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < this.typeIdentifiers.size(); i++) {
String identifier = this.typeIdentifiers.get(i);
if (!method.getParameterTypes()[i].getName().contains(identifier)) {
if (!parameterTypes[i].getName().contains(identifier)) {
return false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -320,21 +320,21 @@ public class BeanDefinitionParserDelegate {
*/
protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable DocumentDefaultsDefinition parentDefaults, Element root) {
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
if (isDefaultValue(lazyInit)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
}
defaults.setLazyInit(lazyInit);
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(merge)) {
if (isDefaultValue(merge)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
}
defaults.setMerge(merge);
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
if (isDefaultValue(autowire)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
}
@@ -572,7 +572,7 @@ public class BeanDefinitionParserDelegate {
}
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
if (isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
@@ -586,7 +586,7 @@ public class BeanDefinitionParserDelegate {
}
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
if (isDefaultValue(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
@@ -661,7 +661,7 @@ public class BeanDefinitionParserDelegate {
@SuppressWarnings("deprecation")
public int getAutowireMode(String attValue) {
String att = attValue;
if (DEFAULT_VALUE.equals(att)) {
if (isDefaultValue(att)) {
att = this.defaults.getAutowire();
}
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
@@ -1341,7 +1341,7 @@ public class BeanDefinitionParserDelegate {
*/
public boolean parseMergeAttribute(Element collectionElement) {
String value = collectionElement.getAttribute(MERGE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(value)) {
if (isDefaultValue(value)) {
value = this.defaults.getMerge();
}
return TRUE_VALUE.equals(value);
@@ -1481,6 +1481,10 @@ public class BeanDefinitionParserDelegate {
return isDefaultNamespace(getNamespaceURI(node));
}
private boolean isDefaultValue(String value) {
return (DEFAULT_VALUE.equals(value) || "".equals(value));
}
private boolean isCandidateElement(Node node) {
return (node instanceof Element && (isDefaultNamespace(node) || !isDefaultNamespace(node.getParentNode())));
}
@@ -84,7 +84,7 @@ public class BeanWrapperGenericsTests {
fail("Should have thrown TypeMismatchException");
}
catch (TypeMismatchException ex) {
assertTrue(ex.getMessage().indexOf("java.lang.Integer") != -1);
assertTrue(ex.getMessage().contains("java.lang.Integer"));
}
}
@@ -89,7 +89,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
catch (PropertyBatchUpdateException ex) {
assertTrue("Must contain 2 exceptions", ex.getExceptionCount() == 2);
// Test validly set property matches
assertTrue("Vaid set property must stick", target.getName().equals(newName));
assertTrue("Valid set property must stick", target.getName().equals(newName));
assertTrue("Invalid set property must retain old value", target.getAge() == 0);
assertTrue("New value of dodgy setter must be available through exception",
ex.getPropertyAccessException("touchy").getPropertyChangeEvent().getNewValue().equals(invalidTouchy));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ public class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
@Test
public void withShadowedField() throws Exception {
public void withShadowedField() {
final StringBuilder sb = new StringBuilder();
@SuppressWarnings("serial")
@@ -198,7 +198,7 @@ public class ServiceLocatorFactoryBeanTests {
assertNotSame(testBean2, testBean4);
assertNotSame(testBean3, testBean4);
assertTrue(factory.toString().indexOf("TestServiceLocator3") != -1);
assertTrue(factory.toString().contains("TestServiceLocator3"));
}
@Ignore @Test // worked when using an ApplicationContext (see commented), fails when using BeanFactory
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,21 @@ public class NestedBeansElementAttributeRecursionTests {
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
assertLazyInits(bf);
}
@Test
public void defaultLazyInitWithNonValidatingParser() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
xmlBeanDefinitionReader.setValidating(false);
xmlBeanDefinitionReader.loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
assertLazyInits(bf);
}
private void assertLazyInits(DefaultListableBeanFactory bf) {
BeanDefinition foo = bf.getBeanDefinition("foo");
BeanDefinition bar = bf.getBeanDefinition("bar");
BeanDefinition baz = bf.getBeanDefinition("baz");
@@ -61,6 +76,22 @@ public class NestedBeansElementAttributeRecursionTests {
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
assertMerge(bf);
}
@Test
@SuppressWarnings("unchecked")
public void defaultMergeWithNonValidatingParser() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
xmlBeanDefinitionReader.setValidating(false);
xmlBeanDefinitionReader.loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
assertMerge(bf);
}
private void assertMerge(DefaultListableBeanFactory bf) {
TestBean topLevel = bf.getBean("topLevelConcreteTestBean", TestBean.class);
// has the concrete child bean values
assertThat((Iterable<String>) topLevel.getSomeList(), hasItems("charlie", "delta"));
@@ -84,6 +115,21 @@ public class NestedBeansElementAttributeRecursionTests {
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
assertAutowireCandidates(bf);
}
@Test
public void defaultAutowireCandidatesWithNonValidatingParser() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
xmlBeanDefinitionReader.setValidating(false);
xmlBeanDefinitionReader.loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
assertAutowireCandidates(bf);
}
private void assertAutowireCandidates(DefaultListableBeanFactory bf) {
assertThat(bf.getBeanDefinition("fooService").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("fooRepository").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("other").isAutowireCandidate(), is(false));
@@ -2,7 +2,7 @@
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
</Console>
</Appenders>
<Loggers>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,87 +84,86 @@ public class CandidateComponentsIndexerTests {
this.compiler = new TestCompiler(this.temporaryFolder);
}
@Test
public void noCandidate() throws IOException {
public void noCandidate() {
CandidateComponentsMetadata metadata = compile(SampleNone.class);
assertThat(metadata.getItems(), hasSize(0));
}
@Test
public void noAnnotation() throws IOException {
public void noAnnotation() {
CandidateComponentsMetadata metadata = compile(CandidateComponentsIndexerTests.class);
assertThat(metadata.getItems(), hasSize(0));
}
@Test
public void stereotypeComponent() throws IOException {
public void stereotypeComponent() {
testComponent(SampleComponent.class);
}
@Test
public void stereotypeService() throws IOException {
public void stereotypeService() {
testComponent(SampleService.class);
}
@Test
public void stereotypeController() throws IOException {
public void stereotypeController() {
testComponent(SampleController.class);
}
@Test
public void stereotypeControllerMetaAnnotation() throws IOException {
public void stereotypeControllerMetaAnnotation() {
testComponent(SampleMetaController.class);
}
@Test
public void stereotypeRepository() throws IOException {
public void stereotypeRepository() {
testSingleComponent(SampleRepository.class, Component.class);
}
@Test
public void stereotypeControllerMetaIndex() throws IOException {
public void stereotypeControllerMetaIndex() {
testSingleComponent(SampleMetaIndexedController.class,
Component.class, MetaControllerIndexed.class);
}
@Test
public void stereotypeOnAbstractClass() throws IOException {
public void stereotypeOnAbstractClass() {
testComponent(AbstractController.class);
}
@Test
public void cdiManagedBean() throws IOException {
public void cdiManagedBean() {
testSingleComponent(SampleManagedBean.class, ManagedBean.class);
}
@Test
public void cdiNamed() throws IOException {
public void cdiNamed() {
testSingleComponent(SampleNamed.class, Named.class);
}
@Test
public void persistenceEntity() throws IOException {
public void persistenceEntity() {
testSingleComponent(SampleEntity.class, Entity.class);
}
@Test
public void persistenceMappedSuperClass() throws IOException {
public void persistenceMappedSuperClass() {
testSingleComponent(SampleMappedSuperClass.class, MappedSuperclass.class);
}
@Test
public void persistenceEmbeddable() throws IOException {
public void persistenceEmbeddable() {
testSingleComponent(SampleEmbeddable.class, Embeddable.class);
}
@Test
public void persistenceConverter() throws IOException {
public void persistenceConverter() {
testSingleComponent(SampleConverter.class, Converter.class);
}
@Test
public void packageInfo() throws IOException {
public void packageInfo() {
CandidateComponentsMetadata metadata = compile(
"org/springframework/context/index/sample/jpa/package-info");
assertThat(metadata, hasComponent(
@@ -172,32 +171,32 @@ public class CandidateComponentsIndexerTests {
}
@Test
public void typeStereotypeFromMetaInterface() throws IOException {
public void typeStereotypeFromMetaInterface() {
testSingleComponent(SampleSpecializedRepo.class, Repo.class);
}
@Test
public void typeStereotypeFromInterfaceFromSuperClass() throws IOException {
public void typeStereotypeFromInterfaceFromSuperClass() {
testSingleComponent(SampleRepo.class, Repo.class);
}
@Test
public void typeStereotypeFromSeveralInterfaces() throws IOException {
public void typeStereotypeFromSeveralInterfaces() {
testSingleComponent(SampleSmartRepo.class, Repo.class, SmartRepo.class);
}
@Test
public void typeStereotypeOnInterface() throws IOException {
public void typeStereotypeOnInterface() {
testSingleComponent(SpecializedRepo.class, Repo.class);
}
@Test
public void typeStereotypeOnInterfaceFromSeveralInterfaces() throws IOException {
public void typeStereotypeOnInterfaceFromSeveralInterfaces() {
testSingleComponent(SmartRepo.class, Repo.class, SmartRepo.class);
}
@Test
public void typeStereotypeOnIndexedInterface() throws IOException {
public void typeStereotypeOnIndexedInterface() {
testSingleComponent(Repo.class, Repo.class);
}
@@ -217,12 +216,12 @@ public class CandidateComponentsIndexerTests {
}
@Test
public void embeddedNonStaticCandidateAreIgnored() throws IOException {
public void embeddedNonStaticCandidateAreIgnored() {
CandidateComponentsMetadata metadata = compile(SampleNonStaticEmbedded.class);
assertThat(metadata.getItems(), hasSize(0));
}
private void testComponent(Class<?>... classes) throws IOException {
private void testComponent(Class<?>... classes) {
CandidateComponentsMetadata metadata = compile(classes);
for (Class<?> c : classes) {
assertThat(metadata, hasComponent(c, Component.class));
@@ -230,19 +229,19 @@ public class CandidateComponentsIndexerTests {
assertThat(metadata.getItems(), hasSize(classes.length));
}
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) throws IOException {
private void testSingleComponent(Class<?> target, Class<?>... stereotypes) {
CandidateComponentsMetadata metadata = compile(target);
assertThat(metadata, hasComponent(target, stereotypes));
assertThat(metadata.getItems(), hasSize(1));
}
private CandidateComponentsMetadata compile(Class<?>... types) throws IOException {
private CandidateComponentsMetadata compile(Class<?>... types) {
CandidateComponentsIndexer processor = new CandidateComponentsIndexer();
this.compiler.getTask(types).call(processor);
return readGeneratedMetadata(this.compiler.getOutputLocation());
}
private CandidateComponentsMetadata compile(String... types) throws IOException {
private CandidateComponentsMetadata compile(String... types) {
CandidateComponentsIndexer processor = new CandidateComponentsIndexer();
this.compiler.getTask(types).call(processor);
return readGeneratedMetadata(this.compiler.getOutputLocation());
@@ -16,7 +16,7 @@ dependencies {
optional("org.freemarker:freemarker:${freemarkerVersion}")
testCompile(project(":spring-context"))
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.hibernate:hibernate-validator:6.0.13.Final")
testCompile("org.hibernate:hibernate-validator:6.0.14.Final")
testCompile("javax.annotation:javax.annotation-api:1.3.2")
testRuntime("org.ehcache:jcache:1.0.1")
testRuntime("org.ehcache:ehcache:3.4.0")
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.activation.FileTypeMap;
import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
@@ -459,7 +460,8 @@ public class JavaMailSenderImpl implements JavaMailSender {
// Preserve explicitly specified message id...
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
}
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
Address[] addresses = mimeMessage.getAllRecipients();
transport.sendMessage(mimeMessage, (addresses != null ? addresses : new Address[0]));
}
catch (Exception ex) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ public class InternetAddressEditorTests {
}
@Test
public void simpleGoodAddess() {
public void simpleGoodAddress() {
editor.setAsText(SIMPLE);
assertEquals("Simple email address failed", SIMPLE, editor.getAsText());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,6 +56,7 @@ public class JavaMailSenderTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
@Test
public void javaMailSenderWithSimpleMessage() throws MessagingException, IOException {
MockJavaMailSender sender = new MockJavaMailSender();
@@ -68,8 +69,8 @@ public class JavaMailSenderTests {
simpleMessage.setFrom("me@mail.org");
simpleMessage.setReplyTo("reply@mail.org");
simpleMessage.setTo("you@mail.org");
simpleMessage.setCc(new String[] {"he@mail.org", "she@mail.org"});
simpleMessage.setBcc(new String[] {"us@mail.org", "them@mail.org"});
simpleMessage.setCc("he@mail.org", "she@mail.org");
simpleMessage.setBcc("us@mail.org", "them@mail.org");
Date sentDate = new GregorianCalendar(2004, 1, 1).getTime();
simpleMessage.setSentDate(sentDate);
simpleMessage.setSubject("my subject");
@@ -105,7 +106,8 @@ public class JavaMailSenderTests {
assertEquals("my text", sentMessage.getContent());
}
public void testJavaMailSenderWithSimpleMessages() throws MessagingException, IOException {
@Test
public void javaMailSenderWithSimpleMessages() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("host");
sender.setUsername("username");
@@ -133,7 +135,8 @@ public class JavaMailSenderTests {
assertEquals("she@mail.org", ((InternetAddress) tos2.get(0)).getAddress());
}
public void testJavaMailSenderWithMimeMessage() throws MessagingException {
@Test
public void javaMailSenderWithMimeMessage() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("host");
sender.setUsername("username");
@@ -394,7 +397,7 @@ public class JavaMailSenderTests {
}
@Test
public void failedMailServerConnect() throws Exception {
public void failedMailServerConnect() {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost(null);
sender.setUsername("username");
@@ -415,7 +418,7 @@ public class JavaMailSenderTests {
}
@Test
public void failedMailServerClose() throws Exception {
public void failedMailServerClose() {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("");
sender.setUsername("username");
@@ -434,7 +437,7 @@ public class JavaMailSenderTests {
}
@Test
public void failedSimpleMessage() throws Exception {
public void failedSimpleMessage() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("host");
sender.setUsername("username");
@@ -466,7 +469,7 @@ public class JavaMailSenderTests {
}
@Test
public void fFailedMimeMessage() throws Exception {
public void failedMimeMessage() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("host");
sender.setUsername("username");
@@ -498,14 +501,14 @@ public class JavaMailSenderTests {
}
@Test
public void testConnection() throws Exception {
public void testConnection() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("host");
sender.testConnection();
}
@Test
public void testConnectionWithFailure() throws Exception {
public void testConnectionWithFailure() throws MessagingException {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost(null);
@@ -592,7 +595,8 @@ public class JavaMailSenderTests {
if ("fail".equals(message.getSubject())) {
throw new MessagingException("failed");
}
if (!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients())) {
if (addresses == null || (message.getAllRecipients() == null ? addresses.length > 0 :
!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients()))) {
throw new MessagingException("addresses not correct");
}
if (message.getSentDate() == null) {
@@ -2,7 +2,7 @@
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
</Console>
</Appenders>
<Loggers>
+5 -5
View File
@@ -15,21 +15,21 @@ dependencies {
optional("javax.interceptor:javax.interceptor-api:1.2.2")
optional("javax.money:money-api:1.0.3")
optional("javax.validation:validation-api:1.1.0.Final")
optional("javax.xml.ws:jaxws-api:2.3.0")
optional("javax.xml.ws:jaxws-api:2.3.1")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.codehaus.groovy:groovy:${groovyVersion}")
optional("org.beanshell:bsh:2.0b5")
optional("joda-time:joda-time:2.10")
optional("joda-time:joda-time:2.10.1")
optional("org.hibernate:hibernate-validator:5.4.2.Final")
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
testCompile("org.codehaus.groovy:groovy-xml:${groovyVersion}")
testCompile("org.codehaus.groovy:groovy-jsr223:${groovyVersion}")
testCompile("org.codehaus.groovy:groovy-test:${groovyVersion}")
testCompile("org.codehaus.groovy:groovy-xml:${groovyVersion}")
testCompile("org.apache.commons:commons-pool2:2.6.0")
testCompile("javax.inject:javax.inject-tck:1")
testCompile("org.awaitility:awaitility:3.1.2")
testRuntime("javax.xml.bind:jaxb-api:2.3.0")
testCompile("org.awaitility:awaitility:3.1.3")
testRuntime("javax.xml.bind:jaxb-api:2.3.1")
testRuntime("org.glassfish:javax.el:3.0.1-b08")
testRuntime("org.javamoney:moneta:1.3")
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ public interface MessageSourceAware extends Aware {
* <p>Invoked after population of normal bean properties but before an init
* callback like InitializingBean's afterPropertiesSet or a custom init-method.
* Invoked before ApplicationContextAware's setApplicationContext.
* @param messageSource message sourceto be used by this object
* @param messageSource message source to be used by this object
*/
void setMessageSource(MessageSource messageSource);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -512,13 +512,19 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
Set<String> autowiredBeanNames;
String name = element.name;
if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&
factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet<>();
resource = ((AutowireCapableBeanFactory) factory).resolveDependency(
element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
else {
@@ -393,6 +393,7 @@ class ConfigurationClassEnhancer {
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
// Detect package-protected NullBean instance through equals(null) check
if (beanInstance.equals(null)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("@Bean method %s.%s called as bean reference " +
@@ -138,7 +138,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
* last.
*
* <p>In certain situations, it may not be possible or practical to tightly control
* property source ordering when using {@code @ProperySource} annotations. For example,
* property source ordering when using {@code @PropertySource} annotations. For example,
* if the {@code @Configuration} classes above were registered via component-scanning,
* the ordering is difficult to predict. In such cases - and if overriding is important -
* it is recommended that the user fall back to using the programmatic PropertySource API.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,11 +94,10 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(this.targetMethod, EventListener.class);
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
this.condition = (ann != null ? ann.condition() : null);
this.order = resolveOrder(method);
this.order = resolveOrder(this.targetMethod);
}
private List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
private static List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
int count = method.getParameterCount();
if (count > 1) {
throw new IllegalStateException(
@@ -123,11 +122,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0));
}
private int resolveOrder(Method method) {
private static int resolveOrder(Method method) {
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class);
return (ann != null ? ann.value() : 0);
}
/**
* Initialize this instance.
*/
@@ -148,8 +148,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
if (declaredEventType.isAssignableFrom(eventType)) {
return true;
}
Class<?> eventClass = eventType.getRawClass();
if (eventClass != null && PayloadApplicationEvent.class.isAssignableFrom(eventClass)) {
if (PayloadApplicationEvent.class.isAssignableFrom(eventType.toClass())) {
ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
if (declaredEventType.isAssignableFrom(payloadType)) {
return true;
@@ -202,8 +201,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
if (this.method.getParameterCount() == 0) {
return new Object[0];
}
Class<?> eventClass = declaredEventType.getRawClass();
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.toClass()) &&
event instanceof PayloadApplicationEvent) {
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
}
@@ -358,12 +356,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
}
for (ResolvableType declaredEventType : this.declaredEventTypes) {
Class<?> eventClass = declaredEventType.getRawClass();
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
Class<?> eventClass = declaredEventType.toClass();
if (!ApplicationEvent.class.isAssignableFrom(eventClass) &&
payloadType != null && declaredEventType.isAssignableFrom(payloadType)) {
return declaredEventType;
}
if (eventClass != null && eventClass.isInstance(event)) {
if (eventClass.isInstance(event)) {
return declaredEventType;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -101,7 +101,7 @@ public class MethodBasedEvaluationContext extends StandardEvaluationContext {
}
setVariable("a" + i, value);
setVariable("p" + i, value);
if (paramNames != null) {
if (paramNames != null && paramNames[i] != null) {
setVariable(paramNames[i], value);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -212,7 +212,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/** Statically specified listeners. */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** ApplicationEvents published early. */
/** Local listeners registered before refresh. */
@Nullable
private Set<ApplicationListener<?>> earlyApplicationListeners;
/** ApplicationEvents published before the multicaster setup. */
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
@@ -483,7 +487,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
this.beanFactoryPostProcessors.add(postProcessor);
}
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
@@ -578,6 +581,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
@@ -591,13 +595,23 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
// Initialize any placeholder property sources in the context environment
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// Validate that all properties marked as required are resolvable
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
@@ -982,6 +996,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @see #registerShutdownHook()
*/
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isDebugEnabled()) {
logger.debug("Closing " + this);
@@ -1016,6 +1031,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Let subclasses do some final clean-up if they wish...
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
this.active.set(false);
}
}
@@ -1302,7 +1324,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
@Nullable
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext ?
((AbstractApplicationContext) getParent()).messageSource : getParent());
((AbstractApplicationContext) getParent()).messageSource : getParent());
}
@@ -183,7 +183,7 @@ public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator
/**
* Prepares the thread context if necessar, and delegates to
* Prepares the thread context if necessary, and delegates to
* {@link #invokeInContext}.
*/
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
* Declares that a field or method parameter should be formatted as a date or time.
*
* <p>Supports formatting by style pattern, ISO date time pattern, or custom format pattern string.
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code java.lang.Long},
* Joda-Time value types; and as of Spring 4 and JDK 8, to JSR-310 <code>java.time</code> types too.
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code Long} (for
* millisecond timestamps) as well as JSR-310 <code>java.time</code> and Joda-Time value types.
*
* <p>For style-based formatting, set the {@link #style} attribute to be the style pattern code.
* The first character of the code is the date style, and the second character is the time style.
@@ -48,6 +48,7 @@ import java.lang.annotation.Target;
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
* @see java.time.format.DateTimeFormatter
* @see org.joda.time.format.DateTimeFormat
*/
@Documented
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@ import java.lang.annotation.Target;
/**
* Declares that a field or method parameter should be formatted as a number.
*
* <p>Supports formatting by style or custom pattern string.
* Can be applied to any JDK {@code java.lang.Number} type.
* <p>Supports formatting by style or custom pattern string. Can be applied
* to any JDK {@code Number} type such as {@code Double} and {@code Long}.
*
* <p>For style-based formatting, set the {@link #style} attribute to be the
* desired {@link Style}. For custom formatting, set the {@link #pattern}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import org.springframework.util.ReflectionUtils;
* Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
*
* <p>As of Spring Framework 5.0, this weaver supports WildFly 8+.
* As of Spring Framework 5.1.5, it also supports WildFly 13+.
*
* @author Costin Leau
* @author Juergen Hoeller
@@ -42,6 +43,9 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
private static final String DELEGATING_TRANSFORMER_CLASS_NAME =
"org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
private static final String WRAPPER_TRANSFORMER_CLASS_NAME =
"org.jboss.modules.JLIClassTransformer";
private final ClassLoader classLoader;
@@ -76,12 +80,23 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
}
transformer.setAccessible(true);
this.delegatingTransformer = transformer.get(classLoader);
if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
Object suggestedTransformer = transformer.get(classLoader);
if (suggestedTransformer.getClass().getName().equals(WRAPPER_TRANSFORMER_CLASS_NAME)) {
Field wrappedTransformer = ReflectionUtils.findField(suggestedTransformer.getClass(), "transformer");
if (wrappedTransformer == null) {
throw new IllegalArgumentException(
"Could not find 'transformer' field on JBoss JLIClassTransformer: " +
suggestedTransformer.getClass().getName());
}
wrappedTransformer.setAccessible(true);
suggestedTransformer = wrappedTransformer.get(suggestedTransformer);
}
if (!suggestedTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
throw new IllegalStateException(
"Transformer not of the expected type DelegatingClassFileTransformer: " +
this.delegatingTransformer.getClass().getName());
suggestedTransformer.getClass().getName());
}
this.delegatingTransformer = suggestedTransformer;
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
"addTransformer", ClassFileTransformer.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import javax.management.ObjectName;
* accessed by application developers during application runtime.
*
* <p>This interface should be used to export application resources to JMX using Spring's
* management interface generation capabilties and, optionally, it's {@link ObjectName}
* management interface generation capabilities and, optionally, it's {@link ObjectName}
* generation capabilities.
*
* @author Rob Harrop
@@ -509,7 +509,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
/**
* Register the defined beans with the {@link MBeanServer}.
* <p>Each bean is exposed to the {@code MBeanServer} via a
* {@code ModelMBean}. The actual implemetation of the
* {@code ModelMBean}. The actual implementation of the
* {@code ModelMBean} interface used depends on the implementation of
* the {@code ModelMBeanProvider} interface that is configured. By
* default the {@code RequiredModelMBean} class that is supplied with
@@ -939,9 +939,9 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* {@link org.springframework.jmx.export.notification.NotificationPublisher} is injected.
*/
private void injectNotificationPublisherIfNecessary(
Object managedResource, ModelMBean modelMBean, ObjectName objectName) {
Object managedResource, @Nullable ModelMBean modelMBean, @Nullable ObjectName objectName) {
if (managedResource instanceof NotificationPublisherAware) {
if (managedResource instanceof NotificationPublisherAware && modelMBean != null && objectName != null) {
((NotificationPublisherAware) managedResource).setNotificationPublisher(
new ModelMBeanNotificationPublisher(modelMBean, objectName, managedResource));
}
@@ -1112,7 +1112,6 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
@Override
protected void postProcessTargetObject(Object targetObject) {
Assert.state(this.modelMBean != null && this.objectName != null, "Not initialized");
injectNotificationPublisherIfNecessary(targetObject, this.modelMBean, this.objectName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
* The property key should match the bean key and the property value should match
* the list of method names. When searching for method names for a bean, Spring
* will check these mappings first.
* @param mappings the mappins of bean keys to method names
* @param mappings the mappings of bean keys to method names
*/
public void setMethodMappings(Properties mappings) {
this.methodMappings = new HashMap<>();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import javax.management.Notification;
* implementing the {@link NotificationPublisherAware} interface. After a particular
* managed resource instance is registered with the {@link javax.management.MBeanServer},
* Spring will inject a {@code NotificationPublisher} instance into it if that
* resource implements the {@link NotificationPublisherAware} inteface.
* resource implements the {@link NotificationPublisherAware} interface.
*
* <p>Each managed resource instance will have a distinct instance of a
* {@code NotificationPublisher} implementation. This instance will keep
@@ -170,11 +170,12 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
try {
if (this.threaded) {
// Start the connector server asynchronously (in a separate thread).
final JMXConnectorServer serverToStart = this.connectorServer;
Thread connectorThread = new Thread() {
@Override
public void run() {
try {
connectorServer.start();
serverToStart.start();
}
catch (IOException ex) {
throw new JmxException("Could not start JMX connector server after delay", ex);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -103,7 +103,7 @@ public abstract class JndiObjectLocator extends JndiLocatorSupport implements In
* Perform the actual JNDI lookup for this locator's target resource.
* @return the located target object
* @throws NamingException if the JNDI lookup failed or if the
* located JNDI object is not assigable to the expected type
* located JNDI object is not assignable to the expected type
* @see #setJndiName
* @see #setExpectedType
* @see #lookup(String, Class)
@@ -99,7 +99,7 @@ import org.springframework.core.Ordered;
*
* &#064;Override
* public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
* return MyAsyncUncaughtExceptionHandler();
* return new MyAsyncUncaughtExceptionHandler();
* }
* }</pre>
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.format.Formatter;
import org.springframework.format.support.FormatterPropertyEditorAdapter;
import org.springframework.lang.Nullable;
@@ -700,6 +701,14 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return getTypeConverter().convertIfNecessary(value, requiredType, field);
}
@Nullable
@Override
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
@Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException {
return getTypeConverter().convertIfNecessary(value, requiredType, typeDescriptor);
}
/**
* Bind the given property values to this binder's target.
@@ -71,6 +71,7 @@ public abstract class ValidationUtils {
Validator validator, Object target, Errors errors, @Nullable Object... validationHints) {
Assert.notNull(validator, "Validator must not be null");
Assert.notNull(target, "Target object must not be null");
Assert.notNull(errors, "Errors object must not be null");
if (logger.isDebugEnabled()) {
@@ -40,7 +40,7 @@ public class OverloadedAdviceTests {
Throwable cause = ex.getRootCause();
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
assertTrue("invalidAbsoluteTypeName should be detected by AJ",
cause.getMessage().indexOf("invalidAbsoluteTypeName") != -1);
cause.getMessage().contains("invalidAbsoluteTypeName"));
}
}
@@ -53,7 +53,7 @@ public class OverloadedAdviceTests {
Throwable cause = ex.getRootCause();
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
assertTrue("Cannot resolve method 'myBeforeAdvice' to a unique method",
cause.getMessage().indexOf("Cannot resolve method 'myBeforeAdvice' to a unique method") != -1);
cause.getMessage().contains("Cannot resolve method 'myBeforeAdvice' to a unique method"));
}
}
@@ -59,7 +59,7 @@ public class AtAspectJAnnotationBindingTests {
}
@Test
public void testPointcutEvaulatedAgainstArray() {
public void testPointcutEvaluatedAgainstArray() {
ctx.getBean("arrayFactoryBean");
}
@@ -365,7 +365,7 @@ public abstract class AbstractAopProxyTests {
assertEquals("Only one invocation via AOP as use of this wasn't proxied", 1, di.getCount());
// 1 invocation
assertEquals("Increment happened", 1, proxied.getCount());
proxied.incrementViaProxy(); // 2 invoocations
proxied.incrementViaProxy(); // 2 invocations
assertEquals("Increment happened", 2, target.getCount());
assertEquals("3 more invocations via AOP as the first call was reentrant through the proxy", 4, di.getCount());
}
@@ -511,7 +511,7 @@ public abstract class AbstractAopProxyTests {
}
@Test
public void testUndeclaredUnheckedException() throws Throwable {
public void testUndeclaredUncheckedException() throws Throwable {
final RuntimeException unexpectedException = new RuntimeException();
// Test return value
MethodInterceptor mi = new MethodInterceptor() {
@@ -736,7 +736,7 @@ public abstract class AbstractAopProxyTests {
fail("Shouldn't be able to add introduction interceptor except via introduction advice");
}
catch (AopConfigException ex) {
assertTrue(ex.getMessage().indexOf("ntroduction") > -1);
assertTrue(ex.getMessage().contains("ntroduction"));
}
// Check it still works: proxy factory state shouldn't have been corrupted
ITestBean proxied = (ITestBean) createProxy(pc);
@@ -786,7 +786,7 @@ public abstract class AbstractAopProxyTests {
/**
* Note that an introduction can't throw an unexpected checked exception,
* as it's constained by the interface.
* as it's constrained by the interface.
*/
@Test
public void testIntroductionThrowsUncheckedException() throws Throwable {
@@ -849,7 +849,7 @@ public abstract class AbstractAopProxyTests {
fail("Shouldn't be able to add interceptor when frozen");
}
catch (AopConfigException ex) {
assertTrue(ex.getMessage().indexOf("frozen") > -1);
assertTrue(ex.getMessage().contains("frozen"));
}
// Check it still works: proxy factory state shouldn't have been corrupted
assertEquals(target.getAge(), proxied.getAge());
@@ -74,6 +74,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
return true;
}
@Test(expected = IllegalArgumentException.class)
public void testNullConfig() {
new CglibAopProxy(null);
@@ -153,6 +154,20 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.getName());
}
@Test
public void testToStringInvocation() {
PrivateCglibTestBean bean = new PrivateCglibTestBean();
bean.setName("Rob Harrop");
AdvisedSupport as = new AdvisedSupport();
as.setTarget(bean);
as.addAdvice(new NopInterceptor());
AopProxy aop = new CglibAopProxy(as);
PrivateCglibTestBean proxy = (PrivateCglibTestBean) aop.getProxy();
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.toString());
}
@Test
public void testUnadvisedProxyCreationWithCallDuringConstructor() {
CglibTestBean target = new CglibTestBean();
@@ -480,6 +495,29 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
return this.value;
}
}
private static class PrivateCglibTestBean {
private String name;
public PrivateCglibTestBean() {
setName("Some Default");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public String toString() {
return this.name;
}
}
}
@@ -498,6 +536,11 @@ class CglibTestBean {
public String getName() {
return this.name;
}
@Override
public String toString() {
return this.name;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import java.io.Serializable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
@@ -60,7 +59,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
}
@Test
public void testProxyIsJustInterface() throws Throwable {
public void testProxyIsJustInterface() {
TestBean raw = new TestBean();
raw.setAge(32);
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
@@ -73,7 +72,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
}
@Test
public void testInterceptorIsInvokedWithNoTarget() throws Throwable {
public void testInterceptorIsInvokedWithNoTarget() {
// Test return value
final int age = 25;
MethodInterceptor mi = (invocation -> age);
@@ -87,7 +86,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
}
@Test
public void testTargetCanGetInvocationWithPrivateClass() throws Throwable {
public void testTargetCanGetInvocationWithPrivateClass() {
final ExposedInvocationTestBean expectedTarget = new ExposedInvocationTestBean() {
@Override
protected void assertions(MethodInvocation invocation) {
@@ -128,7 +127,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
}
@Test
public void testEqualsAndHashCodeDefined() throws Exception {
public void testEqualsAndHashCodeDefined() {
AdvisedSupport as = new AdvisedSupport(Named.class);
as.setTarget(new Person());
JdkDynamicAopProxy aopProxy = new JdkDynamicAopProxy(as);
@@ -139,7 +138,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
}
@Test // SPR-13328
public void testVarargsWithEnumArray() throws Exception {
public void testVarargsWithEnumArray() {
ProxyFactory proxyFactory = new ProxyFactory(new VarargTestBean());
VarargTestInterface proxy = (VarargTestInterface) proxyFactory.getProxy();
assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C));
@@ -145,7 +145,7 @@ public class ProxyFactoryBeanTests {
catch (BeanCreationException ex) {
// Root cause of the problem must be an AOP exception
AopConfigException aex = (AopConfigException) ex.getCause();
assertTrue(aex.getMessage().indexOf("TargetSource") != -1);
assertTrue(aex.getMessage().contains("TargetSource"));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -161,7 +161,7 @@ public class CommonsPool2TargetSourceTests {
// desired
}
// lets now release an object and try to accquire a new one
// lets now release an object and try to acquire a new one
targetSource.releaseTarget(pooledInstances[9]);
pooledInstances[9] = targetSource.getTarget();
@@ -194,7 +194,7 @@ public class CommonsPool2TargetSourceTests {
// desired
}
// lets now release an object and try to accquire a new one
// lets now release an object and try to acquire a new one
targetSource.releaseTarget(pooledInstances[9]);
pooledInstances[9] = targetSource.getTarget();
@@ -482,7 +482,7 @@ public class XmlBeanFactoryTests {
}
catch (BeanDefinitionStoreException ex) {
// check exception message contains the name
assertTrue(ex.getMessage().indexOf("bogusParent") != -1);
assertTrue(ex.getMessage().contains("bogusParent"));
assertTrue(ex.getCause() instanceof NoSuchBeanDefinitionException);
}
}
@@ -678,7 +678,7 @@ public class XmlBeanFactoryTests {
fail();
}
catch (BeanCreationException ex) {
assertTrue(ex.getResourceDescription().indexOf("initializers.xml") != -1);
assertTrue(ex.getResourceDescription().contains("initializers.xml"));
assertEquals("init-method2", ex.getBeanName());
assertTrue(ex.getCause() instanceof IOException);
}
@@ -694,9 +694,9 @@ public class XmlBeanFactoryTests {
}
catch (FatalBeanException ex) {
// check message is helpful
assertTrue(ex.getMessage().indexOf("initializers.xml") != -1);
assertTrue(ex.getMessage().indexOf("init-method3") != -1);
assertTrue(ex.getMessage().indexOf("init") != -1);
assertTrue(ex.getMessage().contains("initializers.xml"));
assertTrue(ex.getMessage().contains("init-method3"));
assertTrue(ex.getMessage().contains("init"));
}
}
@@ -934,7 +934,7 @@ public class XmlBeanFactoryTests {
xbf.getBean("rod2Accessor");
}
catch (BeanCreationException ex) {
assertTrue(ex.toString().indexOf("touchy") != -1);
assertTrue(ex.toString().contains("touchy"));
ex.printStackTrace();
assertNull(ex.getRelatedCauses());
}
@@ -1115,7 +1115,7 @@ public class XmlBeanFactoryTests {
fail("Must have thrown a CannotLoadBeanClassException");
}
catch (CannotLoadBeanClassException ex) {
assertTrue(ex.getResourceDescription().indexOf("classNotFound.xml") != -1);
assertTrue(ex.getResourceDescription().contains("classNotFound.xml"));
assertTrue(ex.getCause() instanceof ClassNotFoundException);
}
}
@@ -1367,7 +1367,7 @@ public class XmlBeanFactoryTests {
}
catch (BeanDefinitionStoreException ex) {
// Check that the bogus method name was included in the error message
assertTrue("Bogus method name correctly reported", ex.getMessage().indexOf("bogusMethod") != -1);
assertTrue("Bogus method name correctly reported", ex.getMessage().contains("bogusMethod"));
}
}
@@ -29,7 +29,7 @@ public class BeanThatBroadcasts implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
if (applicationContext.getDisplayName().indexOf("listener") != -1) {
if (applicationContext.getDisplayName().contains("listener")) {
applicationContext.getBean("listener");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@ public class LifecycleContextBean extends LifecycleBean implements ApplicationCo
public void afterPropertiesSet() {
super.afterPropertiesSet();
if (this.owningContext == null)
throw new RuntimeException("Factory didn't call setAppliationContext before afterPropertiesSet on lifecycle bean");
throw new RuntimeException("Factory didn't call setApplicationContext before afterPropertiesSet on lifecycle bean");
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ public class ComponentScanAnnotationTests {
@Test
public void noop() {
// no-op; the @ComponentScan-annotated MyConfig class below simply excercises
// no-op; the @ComponentScan-annotated MyConfig class below simply exercises
// available attributes of the annotation.
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -184,6 +184,20 @@ public class ConfigurationClassPostProcessorTests {
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class);
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
public void postProcessorWorksWithExtendedConfigurationWithAttributeOverrideForExcludesFilterUsingAsm() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
ExtendedConfigurationWithAttributeOverrideForExcludeFilter.class.getName());
assertSupportForComposedAnnotationWithExclude(beanDefinition);
}
@Test
public void postProcessorWorksWithComposedComposedConfigurationWithAttributeOverridesUsingReflection() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(
@@ -571,6 +585,10 @@ public class ConfigurationClassPostProcessorTests {
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
}
@Test
@@ -585,6 +603,78 @@ public class ConfigurationClassPostProcessorTests {
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
}
@Test
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(0, beanNames.length);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(0, beanNames.length);
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
}
@Test
public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
}
@Test
@@ -604,6 +694,10 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
}
@@ -625,12 +719,16 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class));
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setProxyTargetClass(true);
@@ -646,6 +744,35 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setProxyTargetClass(true);
autoProxyCreator.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(autoProxyCreator);
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo")));
}
@@ -665,6 +792,10 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
}
@@ -685,12 +816,16 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawFactoryMethod() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class));
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setBeanFactory(beanFactory);
@@ -705,6 +840,34 @@ public class ConfigurationClassPostProcessorTests {
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
}
@Test
public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawInstance() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class));
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(autoProxyCreator);
beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
beanFactory.preInstantiateSingletons();
String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class);
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class));
assertEquals(1, beanNames.length);
assertEquals("stringRepo", beanNames[0]);
assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo")));
}
@@ -1125,7 +1288,7 @@ public class ConfigurationClassPostProcessorTests {
}
@Configuration
public static class RawRepositoryConfiguration {
public static class RawFactoryMethodRepositoryConfiguration {
@Bean
public Repository stringRepo() {
@@ -1138,6 +1301,21 @@ public class ConfigurationClassPostProcessorTests {
}
}
@Configuration
public static class RawInstanceRepositoryConfiguration {
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
public Repository<String> stringRepo() {
return new Repository() {
@Override
public String toString() {
return "Repository<String>";
}
};
}
}
@Configuration
public static class ScopedRepositoryConfiguration {
@@ -1351,6 +1529,15 @@ public class ConfigurationClassPostProcessorTests {
public static class ComposedConfigurationWithAttributeOverrideForExcludeFilter {
}
@ComponentScan(basePackages = "org.springframework.context.annotation.componentscan.base", excludeFilters = {})
public static class BaseConfigurationWithEmptyExcludeFilters {
}
@ComponentScan(basePackages = "org.springframework.context.annotation.componentscan.simple",
excludeFilters = @ComponentScan.Filter(Component.class))
public static class ExtendedConfigurationWithAttributeOverrideForExcludeFilter extends BaseConfigurationWithEmptyExcludeFilters {
}
@ComposedConfigurationWithAttributeOverrides
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import javax.annotation.Resource;
import javax.inject.Provider;
import org.junit.Rule;
@@ -228,6 +229,22 @@ public class ConfigurationClassProcessingTests {
ctx.close();
}
@Test
public void configurationWithAdaptiveResourcePrototypes() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithPrototypeBean.class, AdaptiveResourceInjectionPoints.class);
ctx.refresh();
AdaptiveResourceInjectionPoints adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
ctx.close();
}
@Test
public void configurationWithPostProcessor() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -444,6 +461,21 @@ public class ConfigurationClassProcessingTests {
}
@Scope("prototype")
static class AdaptiveResourceInjectionPoints {
@Resource(name = "adaptive1")
public TestBean adaptiveInjectionPoint1;
public TestBean adaptiveInjectionPoint2;
@Resource(name = "adaptive2")
public void setAdaptiveInjectionPoint2(TestBean adaptiveInjectionPoint2) {
this.adaptiveInjectionPoint2 = adaptiveInjectionPoint2;
}
}
static class ConfigWithPostProcessor extends ConfigWithPrototypeBean {
@Value("${myProp}")
@@ -27,7 +27,7 @@ import static org.junit.Assert.*;
/**
* Reproduces SPR-8756, which has been marked as "won't fix" for reasons
* described in the JIRA issue. Also demonstrates the suggested workaround.
* described in the issue. Also demonstrates the suggested workaround.
*
* @author Chris Beams
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,11 +25,11 @@ import java.net.URI;
import java.net.URL;
import java.security.AccessControlException;
import java.security.Permission;
import java.util.Optional;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.beans.factory.ObjectFactory;
@@ -46,7 +46,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
@@ -102,6 +102,8 @@ public class ApplicationContextExpressionTests {
}
});
ac.getBeanFactory().setConversionService(new DefaultConversionService());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties placeholders = new Properties();
placeholders.setProperty("code", "123");
@@ -176,6 +178,9 @@ public class ApplicationContextExpressionTests {
System.getProperties().put("country", "UK");
assertEquals("123 UK", tb3.country);
assertEquals("123 UK", tb3.countryFactory.getObject());
assertEquals("123", tb3.optionalValue1.get());
assertEquals("123", tb3.optionalValue2.get());
assertFalse(tb3.optionalValue3.isPresent());
assertSame(tb0, tb3.tb);
tb3 = (ValueTestBean) SerializationTestUtils.serializeAndDeserialize(tb3);
@@ -209,12 +214,7 @@ public class ApplicationContextExpressionTests {
GenericApplicationContext ac = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
GenericConversionService cs = new GenericConversionService();
cs.addConverter(String.class, String.class, new Converter<String, String>() {
@Override
public String convert(String source) {
return source.trim();
}
});
cs.addConverter(String.class, String.class, String::trim);
ac.getBeanFactory().registerSingleton(GenericApplicationContext.CONVERSION_SERVICE_BEAN_NAME, cs);
RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class);
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
@@ -276,8 +276,7 @@ public class ApplicationContextExpressionTests {
@Test
public void systemPropertiesSecurityManager() {
GenericApplicationContext ac = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(TestBean.class);
@@ -313,8 +312,7 @@ public class ApplicationContextExpressionTests {
@Test
public void stringConcatenationWithDebugLogging() {
GenericApplicationContext ac = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(String.class);
@@ -365,6 +363,15 @@ public class ApplicationContextExpressionTests {
@Value("${code} #{systemProperties.country}")
public ObjectFactory<String> countryFactory;
@Value("${code}")
private transient Optional<String> optionalValue1;
@Value("${code:#{null}}")
private transient Optional<String> optionalValue2;
@Value("${codeX:#{null}}")
private transient Optional<String> optionalValue3;
@Autowired @Qualifier("original")
public transient TestBean tb;
}
@@ -64,7 +64,7 @@ public class LiveBeansViewTests {
}
@Test
public void registerUnregisterServeralContexts() throws MalformedObjectNameException {
public void registerUnregisterSeveralContexts() throws MalformedObjectNameException {
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME, this.name.getMethodName());
ConfigurableApplicationContext context = createApplicationContext("app");
ConfigurableApplicationContext childContext = createApplicationContext("child");
@@ -80,7 +80,7 @@ public class LiveBeansViewTests {
}
@Test
public void registerUnregisterServeralContextsDifferentOrder() throws MalformedObjectNameException {
public void registerUnregisterSeveralContextsDifferentOrder() throws MalformedObjectNameException {
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME, this.name.getMethodName());
ConfigurableApplicationContext context = createApplicationContext("app");
ConfigurableApplicationContext childContext = createApplicationContext("child");
@@ -65,7 +65,7 @@ public class PropertyResourceConfigurerIntegrationTests {
if (userDir.startsWith("/")) {
userDir = userDir.substring(1);
}
assertTrue(ex.getMessage().indexOf(userDir) != -1);
assertTrue(ex.getMessage().contains(userDir));
}
}
@@ -109,8 +109,8 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
// Now msg better be as expected
assertTrue("2nd search within MsgFormat cache returned expected message for Locale.US",
sac.getMessage("message.format.example1", arguments, Locale.US).indexOf(
"there was \"a disturbance in the Force\" on planet 7.") != -1);
sac.getMessage("message.format.example1", arguments, Locale.US).
contains("there was \"a disturbance in the Force\" on planet 7."));
Object[] newArguments = {
new Integer(8), new Date(System.currentTimeMillis()),
@@ -119,8 +119,8 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
// Now msg better be as expected even with different args
assertTrue("2nd search within MsgFormat cache with different args returned expected message for Locale.US",
sac.getMessage("message.format.example1", newArguments, Locale.US)
.indexOf("there was \"a disturbance in the Force\" on planet 8.") != -1);
sac.getMessage("message.format.example1", newArguments, Locale.US).
contains("there was \"a disturbance in the Force\" on planet 8."));
}
/**
@@ -142,13 +142,13 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
minutes of the time might not be the same.
*/
assertTrue("msg from staticMsgSource for Locale.US substituting args for placeholders is as expected",
sac.getMessage("message.format.example1", arguments, Locale.US)
.indexOf("there was \"a disturbance in the Force\" on planet 7.") != -1);
sac.getMessage("message.format.example1", arguments, Locale.US).
contains("there was \"a disturbance in the Force\" on planet 7."));
// Try with Locale.UK
assertTrue("msg from staticMsgSource for Locale.UK substituting args for placeholders is as expected",
sac.getMessage("message.format.example1", arguments, Locale.UK)
.indexOf("there was \"a disturbance in the Force\" on station number 7.") != -1);
sac.getMessage("message.format.example1", arguments, Locale.UK).
contains("there was \"a disturbance in the Force\" on station number 7."));
// Try with Locale.US - Use a different test msg that requires no args
assertTrue("msg from staticMsgSource for Locale.US that requires no args is as expected",
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -127,7 +127,7 @@ public class InterfaceBasedMBeanInfoAssemblerMappedTests extends AbstractJmxAsse
private void assertNickName(MBeanAttributeInfo attr) {
assertNotNull("Nick Name should not be null", attr);
assertTrue("Nick Name should be writable", attr.isWritable());
assertTrue("Nick Name should be readab;e", attr.isReadable());
assertTrue("Nick Name should be readable", attr.isReadable());
}
}
@@ -396,7 +396,7 @@ public class JndiObjectFactoryBeanTests {
fail("Should have thrown NamingException");
}
catch (NamingException ex) {
assertTrue(ex.getMessage().indexOf("org.springframework.tests.sample.beans.DerivedTestBean") != -1);
assertTrue(ex.getMessage().contains("org.springframework.tests.sample.beans.DerivedTestBean"));
}
}
@@ -217,7 +217,7 @@ public class EnableAsyncTests {
}
@Test
public void customExecutorConfig() throws InterruptedException {
public void customExecutorConfig() {
// Arrange
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(CustomExecutorConfig.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,28 +23,29 @@ import javax.naming.NamingException;
import org.springframework.jndi.JndiTemplate;
/**
* Simple extension of the JndiTemplate class that always returns
* a given object. Very useful for testing. Effectively a mock object.
* Simple extension of the JndiTemplate class that always returns a given object.
*
* <p>Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>();
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>(16);
/**
* Construct a new JndiTemplate that will always return given objects
* for given names. To be populated through {@code addObject} calls.
* Construct a new JndiTemplate that will always return given objects for
* given names. To be populated through {@code addObject} calls.
* @see #addObject(String, Object)
*/
public ExpectedLookupTemplate() {
}
/**
* Construct a new JndiTemplate that will always return the
* given object, but honour only requests for the given name.
* Construct a new JndiTemplate that will always return the given object,
* but honour only requests for the given name.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
@@ -54,8 +55,7 @@ public class ExpectedLookupTemplate extends JndiTemplate {
/**
* Add the given object to the list of JNDI objects that this
* template will expose.
* Add the given object to the list of JNDI objects that this template will expose.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
@@ -63,11 +63,10 @@ public class ExpectedLookupTemplate extends JndiTemplate {
this.jndiObjects.put(name, object);
}
/**
* If the name is the expected name specified in the constructor,
* return the object provided in the constructor. If the name is
* unexpected, a respective NamingException gets thrown.
* If the name is the expected name specified in the constructor, return the
* object provided in the constructor. If the name is unexpected, a
* respective NamingException gets thrown.
*/
@Override
public Object lookup(String name) throws NamingException {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@ import javax.naming.OperationNotSupportedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -80,7 +81,9 @@ public class SimpleNamingContext implements Context {
* Create a new naming context with the given naming root,
* the given name/object map, and the JNDI environment entries.
*/
public SimpleNamingContext(String root, Hashtable<String, Object> boundObjects, Hashtable<String, Object> env) {
public SimpleNamingContext(
String root, Hashtable<String, Object> boundObjects, @Nullable Hashtable<String, Object> env) {
this.root = root;
this.boundObjects = boundObjects;
if (env != null) {
@@ -206,6 +209,7 @@ public class SimpleNamingContext implements Context {
}
@Override
@Nullable
public Object addToEnvironment(String propName, Object propVal) {
return this.environment.put(propName, propVal);
}
@@ -293,7 +297,7 @@ public class SimpleNamingContext implements Context {
}
private static abstract class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
private abstract static class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
private Iterator<T> iterator;
@@ -353,7 +357,7 @@ public class SimpleNamingContext implements Context {
}
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
private static final class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
@@ -366,7 +370,7 @@ public class SimpleNamingContext implements Context {
}
private static class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
private static final class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,10 @@ import javax.naming.spi.NamingManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* Simple implementation of a JNDI naming context builder.
@@ -42,7 +45,7 @@ import org.springframework.util.ClassUtils;
* <ul>
* <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls)
* <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call)
* <li>Apache's Jakarta Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
* <li>Apache's Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
* </ul>
*
* <p>Typical usage in bootstrap code:
@@ -80,7 +83,8 @@ import org.springframework.util.ClassUtils;
*/
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder {
/** An instance of this class bound to JNDI */
/** An instance of this class bound to JNDI. */
@Nullable
private static volatile SimpleNamingContextBuilder activated;
private static boolean initialized = false;
@@ -93,13 +97,14 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
* @return the current SimpleNamingContextBuilder instance,
* or {@code null} if none
*/
@Nullable
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
return activated;
}
/**
* If no SimpleNamingContextBuilder is already configuring JNDI,
* create and activate one. Otherwise take the existing activate
* create and activate one. Otherwise take the existing activated
* SimpleNamingContextBuilder, clear it and return it.
* <p>This is mainly intended for test suites that want to
* reinitialize JNDI bindings from scratch repeatedly.
@@ -107,17 +112,18 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
* to control JNDI bindings
*/
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException {
if (activated != null) {
SimpleNamingContextBuilder builder = activated;
if (builder != null) {
// Clear already activated context builder.
activated.clear();
builder.clear();
}
else {
// Create and activate new context builder.
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder = new SimpleNamingContextBuilder();
// The activate() call will cause an assignment to the activated variable.
builder.activate();
}
return activated;
return builder;
}
@@ -138,12 +144,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
logger.info("Activating simple JNDI environment");
synchronized (initializationLock) {
if (!initialized) {
if (NamingManager.hasInitialContextFactoryBuilder()) {
throw new IllegalStateException(
Assert.state(!NamingManager.hasInitialContextFactoryBuilder(),
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
}
NamingManager.setInitialContextFactoryBuilder(this);
initialized = true;
}
@@ -192,7 +196,8 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
* @see SimpleNamingContext
*/
@Override
public InitialContextFactory createInitialContextFactory(Hashtable<?,?> environment) {
@SuppressWarnings("unchecked")
public InitialContextFactory createInitialContextFactory(@Nullable Hashtable<?,?> environment) {
if (activated == null && environment != null) {
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
if (icf != null) {
@@ -212,22 +217,16 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf);
}
try {
return (InitialContextFactory) icfClass.newInstance();
return (InitialContextFactory) ReflectionUtils.accessibleConstructor(icfClass).newInstance();
}
catch (Throwable ex) {
throw new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf, ex);
throw new IllegalStateException("Unable to instantiate specified InitialContextFactory: " + icf, ex);
}
}
}
// Default case...
return new InitialContextFactory() {
@Override
@SuppressWarnings("unchecked")
public Context getInitialContext(Hashtable<?,?> environment) {
return new SimpleNamingContext("", boundObjects, (Hashtable<String, Object>) environment);
}
};
return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable<String, Object>) env);
}
}
@@ -2,7 +2,7 @@
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n" />
</Console>
</Appenders>
<Loggers>
+7 -8
View File
@@ -7,11 +7,10 @@ dependencyManagement {
}
}
// As of Spring 5.1, spring-core includes asm 7.0 and repackages cglib 3.2.8, inlining
// both into the spring-core jar. cglib 3.2.8 itself depends on asm 6+ and is therefore
// further transformed by the JarJar task to depend on org.springframework.asm; this
// avoids including two different copies of asm unnecessarily.
def cglibVersion = "3.2.8"
// spring-core includes asm and repackages cglib, inlining both into the spring-core jar.
// cglib itself depends on asm and is therefore further transformed by the JarJar task to
// depend on org.springframework.asm; this avoids including two different copies of asm.
def cglibVersion = "3.2.10"
def objenesisVersion = "3.0.1"
configurations {
@@ -65,7 +64,7 @@ task objenesisRepackJar(type: Jar) { repackJar ->
dependencies {
cglib("cglib:cglib:${cglibVersion}@jar")
objenesis("org.objenesis:objenesis:${objenesisVersion}@jar")
jarjar("org.pantsbuild:jarjar:1.6.6")
jarjar("org.pantsbuild:jarjar:1.7.2")
compile(files(cglibRepackJar))
compile(files(objenesisRepackJar))
@@ -82,8 +81,8 @@ dependencies {
testCompile("io.projectreactor:reactor-test")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.xmlunit:xmlunit-matchers:2.6.2")
testCompile("javax.xml.bind:jaxb-api:2.3.0")
testCompile("com.fasterxml.woodstox:woodstox-core:5.1.0") {
testCompile("javax.xml.bind:jaxb-api:2.3.1")
testCompile("com.fasterxml.woodstox:woodstox-core:5.2.0") {
exclude group: "stax", module: "stax-api"
}
}
@@ -2437,6 +2437,11 @@ public class ClassReader {
* @return a non null Label, which must be equal to labels[bytecodeOffset].
*/
protected Label readLabel(final int bytecodeOffset, final Label[] labels) {
// SPRING PATCH: leniently handle offset mismatch
if (bytecodeOffset >= labels.length) {
return new Label();
}
// END OF PATCH
if (labels[bytecodeOffset] == null) {
labels[bytecodeOffset] = new Label();
}

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